Facet是什么?

Posted Data+Science+Insight

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Facet是什么?相关的知识,希望对你有一定的参考价值。

Facet是什么?

facet

英 [ˈfæsɪt] 美 [ˈfæsɪt]

n. 小平面;侧面,方面;(昆虫的)小眼面;[建]柱槽筋

vt. 在…上琢面

ElasticSearch 和 Solr中有Facet的概念

Eclipse工程中有Facet的概念

Lucene中也有Facet的概念

ES中的Aggregations API是从Facets功能基础上发展而来,官网正在进行替换计划,建议用户使用Aggregations API,而不是Facets API。ES中的聚合上可以分为下面两类:

metric(度量)聚合:度量类型聚合主要针对的number类型的数据,需要ES做比较多的计算工作。

bucketing(桶)聚合:划分不同的“桶”,将数据分配到不同的“桶”里。非常类似sql中的group语句的含义。

metric既可以作用在整个数据集上,也可以作为bucketing的子聚合作用在每一个“桶”中的数据集上。当然,我们可以把整个数据集合看做一个大“桶”,所有的数据都分配到这个大“桶”中。

。。。。

。。。。。。。。

Elasticsearch强大的聚合功能Facet

在常规数据库中,我们都知道有一个sql就是group,分组。如果主表只有对应的一个列记录的分组的ID,那么还好统计,比如说每本书book表,有一个分类catId,记录是属于哪一类的书,那么直接按照catId进行分组即可。可是在实际应用种,并非如此简单。一本书往往属于多个分类,比如:某本书既属于科技类书,又属于儿童类书,要求按照这两种条件进行筛选,都能筛选出来,如果要求按照分类进行统计数量,数据库怎么group?我们且抛开种种解决方案,来看看Elasticsearch里面对这种需求,是多么的容易统计。

 

首先,我们需要造些数据,需要用到一个模型,这个模型定义了一个type,就算类型吧,我们用这个属性来演示常规的group。还有一个catIds的列表模型,这个来解决我们上面描述的一本书对应多个分类的需求。模型定义如下:

.........

.........................

接下来,我们首先对type进行统计。在elasticsearch中,分组的功能叫facet,不知道为啥起这个名称。总之,就是对type的每一个值的数量进行统计,注意,要设置里面的size条件,否则默认只返回10个。

.........

.........................

在分组这方面,ES真的很强大,除了上面的支持列表分组外,还支持范围分组rangeFacet,多个分组可以一次全部发送给ES等等,更多功能,大家还是自己多多验证。

.........

.........................

1.facet的直观认识

facet:面、切面、方面。个人理解就是维度,在满足query的前提下,观察结果在各维度上的分布(一个维度下各子类的数目)。

如jd上搜“手机”,得到4009个商品。其中品牌、网络、价格就是商品的维度(facet),点击某个品牌或者网络,获取更细分的结果。

点击品牌小米,获得小米手机的结果,显示27个。

点击移动4G,获得移动4G、小米手机,显示4个。

2.facet特性

facet counting:返回一个facet下某子类的结果数。如上面的品牌维度下小米子类中满足查询"手机"的结果有27个。

facet associations:一个文档与某子类的关联度,如一本书30%讲lucene,70%讲solor,这个百分比就是书与分类的关联度(匹配度、信心度)。

multiple facet requests:支持多facet查询(多维度查询)。如查询品牌为小米、网络为移动4G的手机。

3.实例

一个facet简单使用例子,依赖于lucene-facet-4.10.0。讲述了从搜手机到品牌、到网络向下browser的过程。

public class SimpleFacetsExample {

    private final Directory indexDir = new RAMDirectory();

    private final Directory taxoDir = new RAMDirectory();

    private final FacetsConfig config = new FacetsConfig();

 

    /** Empty constructor */

    public SimpleFacetsExample() {

        config.setHierarchical("Publish Date", true);

    }

 

    /** Build the example index. */

    private void index() throws IOException {

        IndexWriter indexWriter = new IndexWriter(indexDir, new IndexWriterConfig(Version.LUCENE_4_10_0,

                new WhitespaceAnalyzer()));

        // Writes facet ords to a separate directory from the main index

        DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(taxoDir);

 

        Document doc = new Document();

        doc.add(new TextField("device", "手机", Field.Store.YES));

        doc.add(new TextField("name", "米1", Field.Store.YES));

        doc.add(new FacetField("brand", "小米"));

        doc.add(new FacetField("network", "移动4G"));

        indexWriter.addDocument(config.build(taxoWriter, doc));

 

        doc = new Document();

        doc.add(new TextField("device", "手机", Field.Store.YES));

        doc.add(new TextField("name", "米4", Field.Store.YES));

        doc.add(new FacetField("brand", "小米"));

        doc.add(new FacetField("network", "联通4G"));

        indexWriter.addDocument(config.build(taxoWriter, doc));

 

        doc = new Document();

        doc.add(new TextField("device", "手机", Field.Store.YES));

        doc.add(new TextField("name", "荣耀6", Field.Store.YES));

        doc.add(new FacetField("brand", "华为"));

        doc.add(new FacetField("network", "移动4G"));

        indexWriter.addDocument(config.build(taxoWriter, doc));

 

        doc = new Document();

        doc.add(new TextField("device", "电视", Field.Store.YES));

        doc.add(new TextField("name", "小米电视2", Field.Store.YES));

        doc.add(new FacetField("brand", "小米"));

        indexWriter.addDocument(config.build(taxoWriter, doc));

 

        taxoWriter.close();

        indexWriter.close();

    }

 

    private void facetsWithSearch() throws IOException {

        DirectoryReader indexReader = DirectoryReader.open(indexDir);

        IndexSearcher searcher = new IndexSearcher(indexReader);

        TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir);

 

        FacetsCollector fc = new FacetsCollector();

        //1.查询手机

        System.out.println("-----手机-----");

        TermQuery query = new TermQuery(new Term("device", "手机"));

        FacetsCollector.search(searcher, query, 10, fc);

        Facets facets = new FastTaxonomyFacetCounts(taxoReader, config, fc);

        List results = facets.getAllDims(10);

        //手机总共有3个,品牌维度:小米2个,华为1个;网络维度:移动4G 2个,联通4G 1个

        for (FacetResult tmp : results) {

            System.out.println(tmp);

        }

        //2.drill down,品牌选小米

        System.out.println("-----小米手机-----");

        DrillDownQuery drillDownQuery = new DrillDownQuery(config, query);

        drillDownQuery.add("brand", "小米");

        FacetsCollector fc1 = new FacetsCollector();//要new新collector,否则会累加

        FacetsCollector.search(searcher, drillDownQuery, 10, fc1);

        facets = new FastTaxonomyFacetCounts(taxoReader, config, fc1);

        results = facets.getAllDims(10);

        //获得小米手机的分布,总数2个,网络:移动4G 1个,联通4G 1个

        for (FacetResult tmp : results) {

            System.out.println(tmp);

        }

 

        //3.drill down,小米移动4G手机

        System.out.println("-----移动4G小米手机-----");

        drillDownQuery.add("network", "移动4G");

        FacetsCollector fc2 = new FacetsCollector();

        FacetsCollector.search(searcher, drillDownQuery, 10, fc2);

        facets = new FastTaxonomyFacetCounts(taxoReader, config, fc2);

        results = facets.getAllDims(10);

        for (FacetResult tmp : results) {

            System.out.println(tmp);

        }

 

        //4.drill sideways,横向浏览

        //如果已经进入了小米手机,但是还想看到其他牌子(华为)的手机数目,就用到了sideways

        System.out.println("-----小米手机drill sideways-----");

        DrillSideways ds = new DrillSideways(searcher, config, taxoReader);

        DrillDownQuery drillDownQuery1 = new DrillDownQuery(config, query);

        drillDownQuery1.add("brand", "小米");

        DrillSidewaysResult result = ds.search(drillDownQuery1, 10);

        results = result.facets.getAllDims(10);

        for (FacetResult tmp : results) {

            System.out.println(tmp);

        }

 

        indexReader.close();

        taxoReader.close();

    }

 

    /** Runs the search and drill-down examples and prints the results. */

    public static void main(String[] args) throws Exception {

        SimpleFacetsExample example = new SimpleFacetsExample();

        example.index();

        example.facetsWithSearch();

    }

}

输出:

-----手机-----

//总数3个,2个子类

dim=brand path=[] value=3 childCount=2

  小米 (2)

  华为 (1)

dim=network path=[] value=3 childCount=2

  移动4G (2)

  联通4G (1)

-----小米手机-----

//普通向下浏览,丢失了同一维度,其他子类的统计

dim=brand path=[] value=2 childCount=1

  小米 (2)

dim=network path=[] value=2 childCount=2

  移动4G (1)

  联通4G (1)

-----移动4G小米手机-----

dim=brand path=[] value=1 childCount=1

  小米 (1)

dim=network path=[] value=1 childCount=1

  移动4G (1)

-----小米手机drill sideways-----

//drill sideways, 保留了该drill维度的其他子类统计

dim=brand path=[] value=3 childCount=2

  小米 (2)

  华为 (1)

//小米手机中的网络分布

dim=network path=[] value=2 childCount=2

  移动4G (1)

  联通4G (1)

先来看一下Group与Facet的区别:

相同点:两者都能分组一个或多个字段并求数量,并支持组内分页

不同点:

facet可以对分组数量进行过滤,以及排序,和日期范围,时间范围分组,但是如果你想得到具体的数据,还得需要查询一次或多次

group可以得到分组的组数量,一次请求,可以拿到所有的数据。

facet可用来做电商网站的这个功能:

group可以用来做这个功能:

Group常用属性介绍:

group=true开启group

group.field需要分组的字段

group.limit限制每个分组里面返回的数量

group.offset配合limit可实现分页

group.ngroups 开启可得到匹配组的数量

Facet常用属性介绍:

facet=true开启facet功能

facet.field分组字段

facet.prefix前缀查询

facet.limit限制组内返回数量

facet.offset配合limit实现分页功能

facet.mincount过滤数量设置

facet.sort排序选项count或index 条件有desc ,asc

......

...................

参考:Elasticsearch强大的聚合功能Facet

参考:(转载) 有关项目的facet是什么东西

参考+维基百科:Facet (geometry)

参考:百度百科Facet

参考:JavaEE中的“Facet”是什么?

参考:导入一个web工程,切换project facets失败

参考:Lucene 之 Facet

参考:Lucene系列-facet

参考:Group与Facet的区别

参考:数据可视化函数-seaborn.FacetGrid

参考:Solr中的group与facet的区别

以上是关于Facet是什么?的主要内容,如果未能解决你的问题,请参考以下文章

Solr高级查询Facet

Solr高级查询Facet

salesforce零基础学习(九十一)Facet

SAP Marketing Cloud里的contact main facet是什么意思

mongodb Aggregation聚合操作之$facet

如何在ggplot2中为facet添加常规标签?