Elasticsearch 之 Facet

尽管官网上强调,facet在以后的版本中将会从elasticsearch中移除,推荐使用aggregations。但在工作上,自己还是使用了facet。在阅读《Mastering Elasticsearch》的时候,看到了对facet的介绍,介绍的非常的实用和易懂,于是就摘译了一部分出来,供需要的参考。

当使用ElasticSearch 刻面(faceting)机制时,需要牢记:刻面(faceting)结果仅在查询(query)结果上计算;如果你在query实体外包含过滤(filter),这样的过滤不会限制刻面统计的文档(document)

来看例子:

首先,使用以下命令往books索引内插入一些文本:

curl -XPUT ‘localhost:9200/books/book/1‘ -d ‘{

"id":"1", "title":"Test book 1", "category":"book",

"price":29.99

}‘

curl -XPUT ‘localhost:9200/books/book/2‘ -d ‘{

"id":"2", "title":"Test book 2", "category":"book",

"price":39.99

}‘

curl -XPUT ‘localhost:9200/books/book/3‘ -d ‘{

"id":"3", "title":"Test comic 1","category":"comic",

"price":11.99

}‘

curl -XPUT ‘localhost:9200/books/book/4‘ -d ‘{

"id":"4", "title":"Test comic 2","category":"comic",

"price":15.99

}‘

让我们来看看当使用查询(query)和过滤(filter)时,刻面(faceting)是如何工作的。我们将会执行一个简单的查询(query)——返回books索引上的所有文档。同样,我们会包含一个过滤来将查询结果限制仅仅属于book分类(category),以及包含一个针对price字段的范围切面,来查看有多少文档的价格低于30和有多少是高于30.整个查询如下:

{

"query": {

"match_all": {}

},

"filter": {

"term": {

"category": "book"

}

},

"facets": {

"price": {

"range": {

"field": "price",

"ranges": [

{

"to": 30

},

{

"from": 30

}

]

}

}

}

}

执行后,我们将得到以下结果:

{

"hits":{

"total":2,

"max_score": 1.0,

"hits": [

{

"_index": "books",

"_type": "book",

"_id": "1",

"_score": 1.0,

"_source": {

"id": "1",

"title": "Test book 1",

"category": "book",

"price": 29.99

}

},

{

"_index": "books",

"_type": "book",

"_id": "2",

"_score": 1.0,

"_source": {

"id": "2",

"title": "Test book 2",

"category": "book",

"price": 39.99

}

}

]

},

"facets": {

"price": {

"_type": "range",

"ranges": [

{

"to": 30.0,

"count": 3,

"min": 11.99,

"max": 29.99,

"total_count": 3,

"total": 57.97,

"mean": 19.323333333333334

},

{

"from": 30.0,

"count": 1,

"min": 39.99,

"max": 39.99,

"total_count": 1,

"total": 39.99,

"mean": 39.99

}

]

}

}

}

从结果可以看出,尽管filter限制只包括category字段取值为book的文档,但facet并不是只在这些文档上执行,而是在books索引上的所有文档上执行(因为match_all查询)。也就是说,刻面机制在计算的时候是不考虑filter的。但如果filter作为query的一部分呢?比如filtered查询?继续看例子。

{

"query": {

"filtered": {

"query": {

"match_all": {}

},

"filter": {

"term": {

"category": "book"

}

}

}

},

"facets": {

"price": {

"range": {

"field": "price",

"ranges": [

{

"to": 30

},

{

"from": 30

}

]

}

}

}

}

返回结果:

{

...

"hits":{

"total": 2,

"max_score": 1.0,

"hits": [

{

"_index": "books",

"_type": "book",

"_id": "1",

"_score": 1.0,

"_source": {

"id": "1",

"title": "Test book 1",

"category": "book",

"price": 29.99

}

},

{

"_index": "books",

"_type": "book",

"_id": "2",

"_score": 1.0,

"_source": {

"id": "2",

"title": "Test book2",

"category": "book",

"price": 39.99

}

}

]

},

"facets": {

"price": {

"_type": "range",

"ranges": [

{

"to": 30.0,

"count": 1,

"min": 29.99,

"max": 29.99,

"total_count": 1,

"total": 29.99,

"mean": 29.99

},

{

"from": 30.0,

"count": 1,

"min": 39.99,

"max": 39.99,

"total_count": 1,

"total": 39.99,

"mean": 39.99

}

]

}

}

}

从返回结果可以看出,这个时候的filter限制了facet的计算范围。

现在,想象我们想要仅仅对title字段包含”2”的书籍计算刻面。我们可以在query增加第二个filter,但是这样的话,会限制查询结果,这并不是我们想要的。我们要做的是引入facet filter。

在提供facet的同级使用facet_filter,这允许我们限制计算刻面的文本。比如如果想限制刻面计算只针对title字段包含”2“的文本,elasticsearch语句可修改为:

{

"query": {

"filtered": {

"query": {

"match_all": {

}

},

"filter": {

"term": {

"category": "book"

}

}

}

}"facets": {

"price": {

"range": {

"field": "price",

"ranges": [

{

"to": 30

},

{

"from": 30

}

]

},

"facet_filter": {

"term": {

"title": "2"

}

}

}

}

}

返回结果:

{

...

"hits":{

"total":2,

"max_score": 1.0,

"hits": [

{

"_index": "books",

"_type": "book",

"_id": "1",

"_score": 1.0,

"_source": {

"id": "1",

"title": "Test book 1",

"category": "book",

"price": 29.99

}

},

{

"_index": "books",

"_type": "book",

"_id": "2",

"_score": 1.0,

"_source": {

"id": "2",

"title": "Test book 2",

"category": "book",

"price": 39.99

}

}

]

},

"facets": {

"price": {

"_type": "range",

"ranges": [

{

"to": 30.0,

"count": 0,

"total_count": 0,

"total": 0.0,

"mean": 0.0

},

{

"from": 30.0,

"count": 1,

"min": 39.99,

"max": 39.99,

"total_count": 1,

"total": 39.99,

"mean": 39.99

}

]

}

}

}

从上面可以看出,facet限制在了一个文本。而query没变。

现在,假如我们想要对所有category字段为”book“的文档进行query(查询),但是想要对索引中的所有文档都进行facet,改怎么办呢?

直接看语句吧:

{

"query": {

"term": {

"category": "book"

}

},

"facets": {

"price": {

"range": {

"field":"price",

"ranges": [

{

"to": 30

},

{

"from": 30

}

]

},

"global": true

}

}

}

返回结果:

{

...

"hits":{

"total":2,

"max_score": 0.30685282,

"hits": [

{

"_index": "books",

"_type": "book",

"_id": "1",

"_score": 0.30685282,

"_source": {

"id": "1",

"title": "Test book 1",

"category": "book",

"price": 29.99

}

},

{

"_index": "books",

"_type": "book",

"_id": "2",

"_score": 0.30685282,

"_source": {

"id": "2",

"title": "Test book 2",

"category": "book",

"price": 39.99

}

}

]

},

"facets": {

"price": {

"_type": "range",

"ranges": [

{

"to": 30.0,

"count": 3,

"min": 11.99,

"max": 29.99,

"total_count": 3,

"total": 57.97,

"mean": 19.323333333333334

},

{

"from": 30.0,

"count": 1,

"min": 39.99,

"max": 39.99,

"total_count": 1,

"total": 39.99,

"mean": 39.99

}

]

}

}

}

这就是global带给facet的好处。

时间: 2024-11-05 22:27:38

Elasticsearch 之 Facet的相关文章

Elasticsearch的javaAPI之facet,count,delete by query

Elasticsearch的javaAPI之count count API允许轻松地执行一个查询,获得匹配的数量,可以跨越一个或多个index ,一个或多个type. import static org.elasticsearch.index.query.xcontent.FilterBuilders.*; import static org.elasticsearch.index.query.xcontent.QueryBuilders.*; CountResponse response =

用ElasticSearch和Protovis实现数据可视化

搜索引擎最重要的目的,嗯,不出意料就是搜索.你传给它一个请求,然后它依照相关性返回你一串匹配的结果.我们可以根据自己的内容创造各种请求结构,试验各种不同的分析器,搜索引擎都会努力尝试提供最好的结果. 不过,一个现代的全文搜索引擎可以做的比这个更多.因为它的核心是基于一个为了高效查询匹配文档而高度优化过的数据结构——倒排索引.它也可以为我们的数据完成复杂的聚合运算,在这里我们叫它facets.(不好翻译,后文对这个单词都保留英文) facets通常的目的是提供给用户某个方面的导航或者搜索. 当你在

filters和scope在ElasticSearch Faceting模块的应用

filters和scope在ElasticSearch Faceting模块的应用 使用ElasticSearch的Facet功能时,有一些关键点需要记住.首先,faceting的结果只会基于查询结果.如果用户在查询命令中使用了filters,那么filters不会对Facet用来的统计计算的文档产生影响.另一个关键点就是scope属性,该属性可以扩展Facet用来统计计算的文档范围.接下来直接看样例. 样例数据 在回忆queries,filters,facets工作原理的同时,我们来开始新内容

elasticsearch 中文API facets(⑩)

facets Elasticsearch提供完整的java API用来支持facets.在查询的过程中,将需要计数的facets添加到FacetBuilders中.然后将该FacetBuilders条件到查询请求中. SearchResponse sr = node.client().prepareSearch() .setQuery( /* your query */ ) .addFacet( /* add a facet */ ) .execute().actionGet(); 为了构建fa

elasticsearch报错

[2014-09-05 10:04:26,551][INFO ][node                     ] [Yukio] started [2014-09-05 10:05:49,076][DEBUG][action.search.type       ] [Yukio] [logstash-2014.08.25][1], node[D9K7wZoESkutIqqdR0CxkQ], [P], s[STARTED]: Failed to execute [[email protect

elasticsearch代码片段,及工具类SearchEsUtil.java

ElasticSearchClient.java package com.zbiti.framework.elasticsearch.utils; import java.util.Arrays; import java.util.List; import java.util.Map; import org.apache.commons.collections.CollectionUtils; import org.apache.log4j.Logger; import org.elastics

搜索引擎选择: Elasticsearch与Solr

搜索引擎选型调研文档 Elasticsearch简介* Elasticsearch是一个实时的分布式搜索和分析引擎.它可以帮助你用前所未有的速度去处理大规模数据. 它可以用于全文搜索,结构化搜索以及分析,当然你也可以将这三者进行组合. Elasticsearch是一个建立在全文搜索引擎 Apache Lucene™ 基础上的搜索引擎,可以说Lucene是当今最先进,最高效的全功能开源搜索引擎框架. 但是Lucene只是一个框架,要充分利用它的功能,需要使用JAVA,并且在程序中集成Lucene.

亿级规模的Elasticsearch优化实战

本次分享主要包含两个方面的实战经验:索引性能和查询性能. 一. 索引性能(Index Performance) 首先要考虑的是,索引性能是否有必要做优化? 索引速度提高与否?主要是看瓶颈在什么地方,若是 Read DB(产生DOC)的速度比较慢,那瓶颈不在 ElasticSearch 时,优化就没那么大的动力.实际上 Elasticsearch 的索引速度还是非常快的. 我们有一次遇到 Elasticsearch 升级后索引速度很慢,查下来是新版 IK 分词的问题,修改分词插件后得到解决. 如果

ElasticSearch的基本用法与集群搭建

ElasticSearch的基本用法与集群搭建 一.简介 ElasticSearch和Solr都是基于Lucene的搜索引擎,不过ElasticSearch天生支持分布式,而Solr是4.0版本后的SolrCloud才是分布式版本,Solr的分布式支持需要ZooKeeper的支持. 这里有一个详细的ElasticSearch和Solr的对比:http://solr-vs-elasticsearch.com/ 二.基本用法 Elasticsearch集群可以包含多个索引(indices),每一个索