ElasticSearch权威指南学习(结构化查询)
请求体查询
简单查询语句(lite)是一种有效的命令行adhoc查询。但是,如果你想要善用搜索,你必须使用请求体查询(request body search)API。
空查询
- 我们以最简单的 search API开始,空查询将会返回索引中所有的文档。
GET /_search
{}- 同字符串查询一样,你可以查询一个,多个或_all索引(indices)或类型(types):
GET /index_2014*/type1,type2/_search
{}
- 你可以使用from及size参数进行分页:
GET /_search
{
"from": 30,
"size": 10
}
结构化查询 Query DSL
使用结构化查询,你需要传递query参数:
GET /_search
{
"query": YOUR_QUERY_HERE
}
空查询 - {} - 在功能上等同于使用match_all查询子句,正如其名字一样,匹配所有的文档:
GET /_search
{
"query": {
"match_all": {}
}
}
查询子句
你可以使用match查询子句用来找寻在tweet字段中找寻包含elasticsearch的成员:
GET /_search
{
"query": {
"match": {
"tweet": "elasticsearch"
}
}
}
合并多子句
- 查询子句就像是搭积木一样,可以合并简单的子句为一个复杂的查询语句
- 叶子子句(leaf clauses)(比如match子句)用以在将查询字符串与一个字段(或多字段)进行比较
- 复合子句(compound)用以合并其他的子句。例如,bool子句允许你合并其他的合法子句,must,must_not或者should,如果可能的话:
{
"bool": {
"must": { "match": { "tweet": "elasticsearch" }},
"must_not": { "match": { "name": "mary" }},
"should": { "match": { "tweet": "full text" }}
}
}
- 复合子句能合并 任意其他查询子句,包括其他的复合子句。 这就意味着复合子句可以相互嵌套,从而实现非常复杂的逻辑。
- 以下实例查询的是邮件正文中含有“business opportunity”字样的星标邮件或收件箱中正文中含有“business opportunity”字样的非垃圾邮件:
{
"bool": {
"must": { "match": { "email": "business opportunity" }},
"should": [
{ "match": { "starred": true }},
{ "bool": {
"must": { "folder": "inbox" }},
"must_not": { "spam": true }}
}}
],
"minimum_should_match": 1
}
}
查询与过滤
查询与过滤语句非常相似,但是它们由于使用目的不同而稍有差异
一条过滤语句会询问每个文档的字段值是否包含着特定值
- created 的日期范围是否在 2013 到 2014 ?
- status 字段中是否包含单词 "published" ?
- lat_lon 字段中的地理位置与目标点相距是否不超过10km ?
一条查询语句会计算每个文档与查询语句的相关性,会给出一个相关性评分 _score,并且 按照相关性对匹配到的文档进行排序。 这种评分方式非常适用于一个没有完全配置结果的全文本搜索
性能差异
- 使用过滤语句得到的结果集--一个简单的文档列表,快速匹配运算并存入内存是十分方便的,每个文档仅需要1个字节。这些缓存的过滤结果集与后续请求的结合使用是非常高效的
- 查询语句不仅要查找相匹配的文档,还需要计算每个文档的相关性,所以一般来说查询语句要比过滤语句更耗时,并且查询结果也不可缓存。
- 幸亏有了倒排索引,一个只匹配少量文档的简单查询语句在百万级文档中的查询效率会与一条经过缓存的过滤语句旗鼓相当,甚至略占上风。但是一般情况下,一条经过缓存的过滤查询要远胜一条查询语句的执行效率。
使用情况
- 原则上来说,使用查询语句做全文本搜索或其他需要进行相关性评分的时候,剩下的全部用过滤语句
最重要的查询过滤语句
term 过滤
- term主要用于精确匹配哪些值,比如数字,日期,布尔值或 not_analyzed的字符串(未经分析的文本数据类型):
{ "term": { "age": 26 }}
{ "term": { "date": "2014-09-01" }}
{ "term": { "public": true }}
{ "term": { "tag": "full_text" }}
terms 过滤
- terms 跟 term 有点类似,但 terms 允许指定多个匹配条件。 如果某个字段指定了多个值,那么文档需要一起去做匹配:
{
"terms": {
"tag": [ "search", "full_text", "nosql" ]
}
}
range 过滤
- range过滤允许我们按照指定范围查找一批数据:
{
"range": {
"age": {
"gte": 20,
"lt": 30
}
}
}
范围操作符包含:
gt :: 大于
gte:: 大于等于
lt :: 小于
lte:: 小于等于exists 和 missing 过滤
- exists 和 missing 过滤可以用于查找文档中是否包含指定字段或没有某个字段,类似于SQL语句中的IS_NULL条件
{
"exists": {
"field": "title"
}
}
bool 过滤
- bool 过滤可以用来合并多个过滤条件查询结果的布尔逻辑,它包含一下操作符:
- must :: 多个查询条件的完全匹配,相当于 and。
- must_not :: 多个查询条件的相反匹配,相当于 not。
- should :: 至少有一个查询条件匹配, 相当于 or。
- 这些参数可以分别继承一个过滤条件或者一个过滤条件的数组
{
"bool": {
"must": { "term": { "folder": "inbox" }},
"must_not": { "term": { "tag": "spam" }},
"should": [
{ "term": { "starred": true }},
{ "term": { "unread": true }}
]
}
}
- bool 过滤可以用来合并多个过滤条件查询结果的布尔逻辑,它包含一下操作符:
match_all 查询
- 使用match_all 可以查询到所有文档,是没有查询条件下的默认语句。
{
"match_all": {}
}
match 查询
- match查询是一个标准查询,不管你需要全文本查询还是精确查询基本上都要用到它
- 如果你使用 match 查询一个全文本字段,它会在真正查询之前用分析器先分析match一下查询字符
{
"match": {
"tweet": "About Search"
}
}
multi_match 查询
- multi_match查询允许你做match查询的基础上同时搜索多个字段:
{
"multi_match": {
"query": "full text search",
"fields": [ "title", "body" ]
}
}
bool 查询
- bool 查询与 bool 过滤相似,用于合并多个查询子句。不同的是,bool 过滤可以直接给出是否匹配成功, 而bool 查询要计算每一个查询子句的 _score (相关性分值)。
must:: 查询指定文档一定要被包含。
must_not:: 查询指定文档一定不要被包含。
should:: 查询指定文档,有则可以为文档相关性加分。
- 以下查询将会找到 title 字段中包含 "how to make millions",并且 "tag" 字段没有被标为 spam。 如果有标识为 "starred" 或者发布日期为2014年之后,那么这些匹配的文档将比同类网站等级高
{
"bool": {
"must": { "match": { "title": "how to make millions" }},
"must_not": { "match": { "tag": "spam" }},
"should": [
{ "match": { "tag": "starred" }},
{ "range": { "date": { "gte": "2014-01-01" }}}
]
}
}
查询与过滤条件的合并
- 带过滤的查询语句
- search API中只能包含 query 语句,所以我们需要用 filtered 来同时包含 "query" 和 "filter" 子句:
- 在收信箱中匹配邮件
{
"filtered": {
"query": { "match": { "email": "business opportunity" }},
"filter": { "term": { "folder": "inbox" }}
}
}
- 我们在外层再加入 query 的上下文关系:
GET /_search
{
"query": {
"filtered": {
"query": { "match": { "email": "business opportunity" }},
"filter": { "term": { "folder": "inbox" }}
}
}
}
- ps: 过滤查询已被弃用,并在ES 5.0中删除。现在应该使用bool / must / filter查询
验证查询
- 查询语句可以变得非常复杂,特别是与不同的分析器和字段映射相结合后,就会有些难度
- validate API 可以验证一条查询语句是否合法
GET /ecommerce/product/_validate/query?explain
{
"query": {
"filtered":{
"query":{
"match":{
"name":"jiajieshi yagao"
}
},
"filter":{
"term":{
"price":40
}
}
}
}
}
结果
{
"valid": false,
"error": "org.elasticsearch.common.ParsingException: no [query] registered for [filtered]"
}
- ps:可以总结下碰到no [xxx] registered for [xxxx] 这种情况,很大可能是版本升级后,该方法被废除了
ElasticSearch权威指南学习(结构化查询)的更多相关文章
- ElasticSearch权威指南学习(索引管理)
创建索引 当我们需要确保索引被创建在适当数量的分片上,在索引数据之前设置好分析器和类型映射. 手动创建索引,在请求中加入所有设置和类型映射,如下所示: PUT /my_index { "se ...
- ElasticSearch权威指南学习(映射和分析)
概念 映射(mapping)机制用于进行字段类型确认,将每个字段匹配为一种确定的数据类型(string, number, booleans, date等).+ 分析(analysis)机制用于进行全文 ...
- ElasticSearch权威指南学习(文档)
什么是文档 在Elasticsearch中,文档(document)这个术语有着特殊含义.它特指最顶层结构或者根对象(root object)序列化成的JSON数据(以唯一ID标识并存储于Elasti ...
- ElasticSearch权威指南学习(分布式搜索)
查询阶段 在初始化查询阶段(query phase),查询被向索引中的每个分片副本(原本或副本)广播. 每个分片在本地执行搜索并且建立了匹配document的优先队列(priority queue). ...
- ElasticSearch权威指南学习(排序)
排序方式 相关性排序 默认情况下,结果集会按照相关性进行排序 -- 相关性越高,排名越靠前. 相关性分值会用_score字段来给出一个浮点型的数值,所以默认情况下,结果集以_score进行倒序排列. ...
- ElasticSearch权威指南学习(分布式文档存储)
路由文档到分片 当你索引一个文档,它被存储在单独一个主分片上.Elasticsearch是如何知道文档属于哪个分片的呢?当你创建一个新文档,它是如何知道是应该存储在分片1还是分片2上的呢? 进程不能是 ...
- ElasticSearch权威指南学习(分布式集群)
空集群 只有一个空节点的集群 一个节点(node)就是一个Elasticsearch实例,而一个集群(cluster)由一个或多个节点组成,它们具有相同的cluster.name,它们协同工作,分享数 ...
- ElasticSearch 5学习(10)——结构化查询(包括新特性)
之前我们所有的查询都属于命令行查询,但是不利于复杂的查询,而且一般在项目开发中不使用命令行查询方式,只有在调试测试时使用简单命令行查询,但是,如果想要善用搜索,我们必须使用请求体查询(request ...
- ElasticSearch(6)-结构化查询
引用:ElasticSearch权威指南 一.请求体查询 请求体查询 简单查询语句(lite)是一种有效的命令行_adhoc_查询.但是,如果你想要善用搜索,你必须使用请求体查询(request bo ...
随机推荐
- MySQL 物理文件体系结构的简单整理说明
本文出处:http://www.cnblogs.com/wy123/p/7102128.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...
- VS2017安装步骤详解
原文地址:https://www.ithome.com/html/win10/297093.htm 微软最近发布了正式版Visual Studio 2017并公开了其下载方式,不过由于VS2017采用 ...
- java学习笔记(一):开始第一个java项目
这里使用IntelliJ IDEA 来新建第一个java项目 在新建项目向导,你可以选择你的项目支持的技术,你正在做一个普通的Java项目,只需单击下一步. 下一步,新建一个test的项目. 新建一个 ...
- vue组件之时间组件
效果图 主要有两个注意点,前面时分,通过定时器,1秒钟取一次,只要数据变了立刻让他展示,当然也可以1分钟取一次,我看了下定时器和真正的时间 其实有一定的偏差的,大约要1分多才会改变,所以我用了1秒取一 ...
- ImportError: No module named MySQLdb问题的解决
今天在windows上撸python代码,遇到ImportError: No module named MySQLdb的问题,遂赶紧pip install mysql-python,结果还是不行,查看 ...
- 三次样条插值算法C++实现
三次样条插值算法 1 总体说明 三次样条插值算法是一种计算量和效果都比较理想的插值算法.关于三次样条插值算法的原理这里不做过多的解释,下面的代码是我在网上收集了两种C++实现版本的基础上自己整合的一个 ...
- python基础 (编码进阶,文件操作和深浅copy)
1.编码的进阶 字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码. 即先将其他编码的字符串解码(decode)成unicode,再从uni ...
- 判断是否是json
转:https://blog.csdn.net/dy_smile/article/details/46739251 function isJson(obj) { var isjson = typeof ...
- php上传多张图片
第一种:加后缀 代码实现(就是普通的上传图片,只是在外面加个foreach循环) $allow_file_types = '|GIF|JPG|PNG|BMP|SWF|DOC|XLS|PPT|MID|W ...
- Mysql知识点个人整理
1.概念 数据库:保存有组织的数据的容器. 表: 某种特定类型数据的结构化清单 模式:关于数据库和表的布局和特性的信息?(有时指数据库) 主键: primary key 一个列或一组列,其值能唯一区分 ...