1. 请求体查询
请求体查询,并不仅仅用来处理查询,而且还可以高亮返回结果中的片段,并且给出帮助你的用户找寻最好 结果的相关数据建议。
1.1 空查询
空查询将会返回索引中所有的文档。
同字符串查询一样,你可以查询一个,多个或 _all 索引(indices)或类型(types):
你可以使用 from 及 size 参数进行分页:
search API同样支持 POST 请求,类似于这样:
2. 结构化查询 Query DSL
使用结构化查询,你需要传递 query 参数:
空查询 - {} - 在功能上等同于使用 match_all 查询子句,正如其名字一样,匹配所有的文档:
2.1 查询子句
一个查询子句一般使用这种结构:
或指向一个指定的字段:
例如,你可以使用 match 查询子句用来找寻在 tweet 字段中找寻包含 elasticsearch 的成员:
GET /_search {
"query": {
"match": {
"tweet": "elasticsearch"
}
}
}
2.2 合并多子句
- 简单子句(leaf clauses)(比如 match 子句)用以在将查询字符串与一个字段(或多字段)进行比较
- 复合子句(compound)用以合并其他的子句。例如, bool 子句允许你合并其他的合法子句,无论是 must , must_not 还 是 should :
着复合子句可以相互嵌套,从而实现非常复杂的逻辑。
以下实例查询在inbox中或未标记spam的邮件中找出包含 “business opportunity” 的星标(starred)邮件:
3. 查询与过滤
前面我们讲到的是关于结构化查询语句,事实上我们可以使用两种结构化语句: 结构化查询(Query DSL)和结构化过滤 (Filter DSL)。 查询与过滤语句非常相似,但是它们由于使用目的不同而稍有差异。
3.1 过滤语句
一条过滤语句会询问每个文档的字段值是否包含着特定值:
- 是否 created 的日期范围在 2013 到 2014 ?
- 是否 status 字段中包含单词 “published” ?
- 是否 lat_lon 字段中的地理位置与目标点相距不超过10km ?
3.2 查询语句
一条查询语句与过滤语句相似,但问法不同:
查询语句会询问每个文档的字段值与特定值的匹配程度如何?
查询语句的典型用法是为了找到文档:
- 查找与 full text search 这个词语最佳匹配的文档
- 查找包含单词 run ,但是也包含 runs , running , jog 或 sprint 的文档
- 同时包含着 quick , brown 和 fox — 单词间离得越近,该文档的相关性越高
- 标识着 lucene , search 或 java — 标识词越多,该文档的相关性越高
一条查询语句会计算每个文档与查询语句的相关性,会给出一个相关性评分 _score ,并且 按照相关性对匹配到的文档进行 排序。 这种评分方式非常适用于一个没有完全配置结果的全文本搜索。
3.3 性能差异
使用过滤语句得到的结果集 – 一个简单的文档列表,快速匹配运算并存入内存是十分方便的, 每个文档仅需要1个字节。这 些缓存的过滤结果集与后续请求的结合使用是非常高效的。
查询语句不仅要查找相匹配的文档,还需要计算每个文档的相关性,所以一般来说查询语句要比 过滤语句更耗时,并且查询 结果也不可缓存。
幸亏有了倒排索引,一个只匹配少量文档的简单查询语句在百万级文档中的查询效率会与一条经过缓存 的过滤语句旗鼓相 当,甚至略占上风。 但是一般情况下,一条经过缓存的过滤查询要远胜一条查询语句的执行效率。
过滤语句的目的就是缩小匹配的文档结果集,所以需要仔细检查过滤条件。
3.4 什么情况下使用
原则上来说,使用查询语句做全文本搜索或其他需要进行相关性评分的时候,剩下的全部用过滤语句