filters和scope在ElasticSearch Faceting模块的应用
filters和scope在ElasticSearch Faceting模块的应用
使用ElasticSearch的Facet功能时,有一些关键点需要记住。首先,faceting的结果只会基于查询结果。如果用户在查询命令中使用了filters,那么filters不会对Facet用来的统计计算的文档产生影响。另一个关键点就是scope属性,该属性可以扩展Facet用来统计计算的文档范围。接下来直接看样例。
样例数据
在回忆queries,filters,facets工作原理的同时,我们来开始新内容的学习。首先往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
}'
Faceting和filtering
接下来验证queries结合filters时,facetings是如何工作的。我们会运行一个简单的查询命令,该查询会返回books索引中所有的文档;同时,我们也添加了一个filter来缩减查询只返回category域值为book的文档;此外,我们还为price域添加了一个简单的range faceting统计,来看看有多少文档的price域值低于30,多少文档的price域值高于30。整个查询命令如下(存储于query_with_filter.json文件):
{
"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
} ]
}
}
}
尽管查询的结果限制到了category域值为book的文档,但是faceting的结果却不是这样。实际上,faceting的结果是基于books索引中的所有文档(由于match_all_query的缘故)。因此,现在可以确定ElasticSearch的faceting机制在计算时不会把filter考虑进去。那么,如果filters是query对象的一部分呢,比如filtered query类型?让我们来验证一下。
Filter作为Query对象的一部分
接下来,还是用前面的例子,只是把查询换成filtered query类型。然后再次从books索引中取得所有的文档,并用book类别来过滤结果集,同时对price域进行简单的range faceting操作,来查看多少文档的price值低于30,多少文档的price值高于30。为了实现这个目的,来运行如下的查询(存储在filtered_query.json文件):
{
"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 book
2", "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
} ]
}
}
}
可以看到,正所我们所希望的,faceting的结果限制到了查询返回的结果集中,这是由于filter成为了查询的一部分。在本例中,faceting结果由两个区间组成,每个区间都包含着一个文档。
Facet filter
假如我们希望对title域中含term值为2的书进行faceting统计。我们可能想到在query对象中添加第二个过滤器,但是这样做会减少查询结果的数量,而我们不希望查询受到影响。因此我们引入facet filter。
我们将facet_filter过滤器添加到facet类型(本例中是price)的同一层。该过滤器可以减少faceting统计计算的文档数量,其使用方式与查询中的过滤器是一样的。例如,假如我们用facet_filter使得facet功能只对title域中含term值为2的书籍进行faceting统计,我们应该把查询命令修改成如下(整个查询命令存储在 filtered_query_facet_filter.json文件中):
{
...
"facets" : {
"price" : {
"range" : {
"field" : "price",
"ranges" : [
{ "to" : 30 },
{ "from" : 30 }
]
},
"facet_filter" : {
"term" : {
"title" : "2"
}
}
}
}
}
可以看到,我们引入了新的过滤器,即一个简单的term类型的过滤器。上面查询命令返回的结果如下:
{
...
"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 filter,就可以实现基于只一个文档的faceting统计计算,但是查询不受影响,仍然返回两个文档。
Facet的统计范围
如果我们希望执行一个查询命令,查找到name域中包含term值为2的所有文档,同时基于索引中的所有文档进行range facet统计操作,该怎么做呢?幸运地是,我们不必非要使用两个查询命令来实现,我们可以通过添加global属性,设置其值为true来使用全局范围的faceting操作。
例如,我们先把前面用过的查询命令进行简单的修改。在本节中,查询命令中去掉过滤器,只有一个term query。此外,我们还添加了一个global属性,因此查询命令如下(已经存储在query_global_scope.json文件中):
{
"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统计计算却是基于整个索引的所有文档。
global属性可能的应用场景在于使用faceting来建立导航信息。设想无论什么查询,我们都需要返回顶级分类信息,比如在电子商务网站,使用terms facet功能来展示商品的顶级分类信息。在这类的场景中,使用global 范围是很方便的。
filters和scope在ElasticSearch Faceting模块的应用的更多相关文章
- ElasticSearch 索引模块——全文检索
curl -XPOST http://master:9200/djt/user/3/_update -d '{"doc":{"name":"我们是中国 ...
- Elasticsearch Index模块
1. Index Setting(索引设置) 每个索引都可以设置索引级别.可选值有: static :只能在索引创建的时候,或者在一个关闭的索引上设置 dynamic:可以动态设置 1.1. S ...
- Elasticsearch Transport 模块创建及启动分析
Elasticsearch 通信模块的分析从宏观上介绍了ES Transport模块总体功能,于是就很好奇ElasticSearch是怎么把服务启动起来,以接收Client发送过来的Index索引操作 ...
- Elasticsearch 搜索模块之Cross Cluster Search(跨集群搜索)
Cross Cluster Search简介 cross-cluster search功能允许任何节点作为跨多个群集的federated client(联合客户端),与tribe node不同的是cr ...
- ElasticSearch 索引模块——集成IK中文分词
下载插件地址 https://github.com/medcl/elasticsearch-analysis-ik/tree/v1.10.0 对这个插件在window下进行解压 用maven工具对插件 ...
- ES搜索引擎-简单入门
基本概念: 索引Index es吧数据放到一个或者多个索引中,如果用关系型数据库模型对比,索引的地位与数据库实例(db)相当.索引存放和读取的基本单元是文档(document).es内部使用的是apa ...
- npm 私有模块的管理使用
你可以使用 NPM 命令行工具来管理你在 NPM 仓库的私有模块代码,这使得在项目中使用公共模块变的更加方便. 开始前的工作 你需要一个 2.7.0 以上版本的 npm ,并且需要有一个可以登陆 np ...
- Elasticsearch+Logstash+Kibana教程
参考资料 累了就听会歌吧! Elasticsearch中文参考文档 Elasticsearch官方文档 Elasticsearch 其他——那些年遇到的坑 Elasticsearch 管理文档 Ela ...
- Python基础-作用域和命名空间(Scope and Namespace)
在Python中,对象是独立的,不同作用域中的不同名字都可以被绑定在同一个对象上,当然对这个对象的修改会影响所有的引用.赋值操作就是名字和对象的绑定或重绑定.这和C++中的引用是一样的. 1,基础概念 ...
随机推荐
- 数据库MySQL--子查询
例子文件1:https://files.cnblogs.com/files/Vera-y/myemployees.zip 子查询:又称内查询,出现在其他语句中的select语句 主查询:又称外查询,内 ...
- LoadRunner关联通用函数的学习
LoadRunner关联通用函数的学习 写这篇文章的时候,我先声明一下,本BLOG中的文章如果没有写出是转贴的一般就是本人原创. Loadrunner脚本中进行关联的时候,用到了一些函数,作用是把字符 ...
- ReentrantLock中的公平锁与非公平锁
简介 ReentrantLock是一种可重入锁,可以等同于synchronized的使用,但是比synchronized更加的强大.灵活. 一个可重入的排他锁,它具有与使用 synchronized ...
- Python中虚拟环境venv的基本用法
环境windows 7 venv为python3中的默认库,无需安装. 创建新的venv方法, 在当前文件夹下执行cmd,输入如下代码 python -m venv bob bob为需要创建的文件夹名 ...
- 【luoguP4721】分治 FFT
description 给定长度为\(n-1\)的数组\(g[1],g[2],..,g[n-1]\),求\(f[0],f[1],..,f[n-1]\),其中 \[f[i]=\sum_{j=1}^if[ ...
- golang中使用gorm连接mysql操作
一.代码 package main import ( "fmt" "github.com/jinzhu/gorm" _ "github.com/go- ...
- IDEA被删除的模块在编译时会再次出现
工程根目录下.idea文件->compiler.xml,删除多余的model,workspace.xml->删除带有无用的target标签
- (转)[视频压制/转换技术] I帧 B帧 P帧 IDR帧 等帧用途详细说明
转:http://www.u2game.net/bbs/thread-46116-1-1.html 在视频压制.转换中,经常会看到:I帧 B帧 P帧 IDR帧 等名词,这里就是通用的解释一下这些帧的用 ...
- 从 i++ 和 ++i 说起局部变量表和操作数栈
本文转载自:从 i++ 和 ++i 说起局部变量表和操作数栈 最近公司有人看了尚硅谷柴林燕老师的第一季面试题,就想来考考我.我觉得柴老师讲的很好,部分内容可以延伸一下,所以写这篇文章分享给大家! 这篇 ...
- jquery判断是pc端还是移动端
原文地址:https://www.cnblogs.com/mo-cha/p/6038872.html $(function(){ var system = { win: false, mac: fal ...