multi_match 查询
multi_match 查询允许你做 match 查询的基础上同时搜索多个字段
{ "multi_match": { "query": "full text search", "fields": [ "title", "body" ] } }
POST http://localhost:9200/book/novel/_search
{ "query":{ "multi_match":{ "query":"李四", "fields":["author","title"] } } }
bool 查询
bool 查询与 bool 过滤相似, 用于合并多个查询子句。 不同的是, bool 过滤可以直接给出是否匹配成功, 而 bool 查询要计算每一个查询子句的 _score (相关性分值)
- must :: 查询指定文档一定要被包含。
- must_not :: 查询指定文档一定不要被包含。
- should :: 查询指定文档, 有则可以为文档相关性加分
{ "bool": { "must": { "match": { "title": "how to make millions" } }, "must_not": { "match": { "tag": "spam" } }, "should": [ { "match": { "tag": "starred" } }, { "range": { "date": { "gte": "2014-01-01" } } } ] } }
上述查询将会找到 title 字段中包含 “how to make millions”, 并且 “tag” 字段没有被标为 spam. 如果有标识为 "starred"或者发布日期为2014年之前, 那么这些匹配的文档将比同类网站等级高.
如果 bool 查询下没有 must 子句, 那至少应该有一个 should 子句。 但是 如果有 must 子句, 那么没有 should 子句也可以进行查询。
Filter DSL
term 过滤
term 主要用于精确匹配哪些值, 比如数字, 日期, 布尔值或 not_analyzed 的字符串(未经分析的文本数据类型)
term仅允许指定一个匹配条件 ,即 value只能有一个值
举例:过滤查询"public_date" 精确匹配 "2017-08-15"的数据
{ "query":{ "term":{ "public_date": "2017-08-15" } } }
POST http://localhost:9200/book/novel/_search
terms 过滤
terms 允许指定多个匹配条件。 如果某个字段指定了多个值, 那么文档需要一起去做匹配。
例子 查询author匹配 "李三"或者"孙悟空"的数据
POST http://localhost:9200/book/novel/_search
{ "query":{ "terms":{ "author":["李三","孙悟空"] } } }
range 过滤
range 过滤 按照指定范围查找一批数据
范围操作符包含:
- gt 大于
- gte 大于等于
- lt 小于
- lte 小于等于
例子: 过滤查询 字数 大于等于1000 小于2000的数据
POST http://localhost:9200/book/novel/_search
{ "query":{ "range":{ "word_count":{ "gte":1000, "lt":"2000" } } } }
exists 和 missing 过滤
exists 和 missing 过滤可以用于查找文档中是否包含指定字段或没有某个字段, 类似于SQL语句中的 IS_NULL 条件。
这两个过滤只是针对已经查出一批数据来, 但是想区分出某个字段是否存在的时候使用。
目前es不推荐使用missing过滤, 使用bool.must_not + exists来替代
"bool": { "must_not": { "exists": { "field": "title" } } }
例子 查询是否存在 名为 xxxx 的字段
POST http://localhost:9200/book/novel/_search
{ "query":{ "exists":{ "field":"xxxx" } } }
bool 过滤
bool 过滤可以用来合并多个过滤条件查询结果的布尔逻辑,它包含一下操作符:
- must :: 多个查询条件的完全匹配,相当于 and。
- must_not :: 多个查询条件的相反匹配,相当于 not。
- should :: 至少有一个查询条件匹配, 相当于 or。
这些参数可以分别继承一个过滤条件或者一个过滤条件的数组:
例子
{ "query": { "bool": { "must": { "term": { "folder": "inbox" } }, "must_not": { "term": { "tag": "spam" } }, "should": [ { "term": { "starred": true } }, { "term": { "unread": true } } ] } } }
查询与过滤条件的合并
查询语句和过滤语句可以放在各自的上下文中。 在 ElasticSearch API 中我们会看到许多带有 query 或 filter 的语句。
这些语句既可以包含单条 query 语句, 也可以包含一条 filter 子句。
换句话说, 这些语句需要首先创建一个 query 或 filter 的上下文关系。
复合查询语句可以加入其他查询子句, 复合过滤语句也可以加入其他过滤子句。 通常情况下, 一条查询语句需要过滤语句的辅助, 全文本搜索除外。
所以说, 查询语句可以包含过滤子句, 反之亦然。 以便于我们切换 query 或 filter 的上下文。 这就要求我们在读懂需求的同时构造正确有效的语句。
带过滤的查询语句
假设我们有这样一条查询语句:
{ "match": { "email": "business opportunity" } }
然后我们想要让这条语句加入 term 过滤, 在收信箱中匹配邮件:
{ "term": { "folder": "inbox" } }
search API中只能包含 query 语句, 所以我们需要用 filtered 来同时包含 “query” 和 “filter” 子句 【过滤查询已被弃用,并在ES 5.0中删除,如下会在我们用的5.x版本中报错】
{ "filtered": { "query": { "match": { "email": "business opportunity" } }, "filter": { "term": { "folder": "inbox" } } } }
我们在外层再加入 query 的上下文关系:
{ "query": { "filtered": { "query": { "match": { "email": "business opportunity" } }, "filter": { "term": { "folder": "inbox" } } } } }
报错了。。。。改成使用bool / must / filter查询
{ "query": { "bool": { "must": { "match": { "email": "business opportunity" } }, "filter": { "term": { "folder": "inbox" } } } } }
单条过滤语句
在 query 上下文中, 如果你只需要一条过滤语句, 比如在匹配全部邮件的时候, 你可以 省略 query 子句( 5.x以后的版本 需要用bool 代替 filtered):
{ "query": { "bool": { "filter": { "term": { "folder": "inbox" } } } } }
如果一条查询语句没有指定查询范围, 那么它默认使用 match_all 查询 ,等同于
{ "query": { "bool": { "must": { "match_all": {} }, "filter": { "term": { "folder": "inbox" } } } } }
上面说的是 查询中使用过滤。 那过滤中使用查询呢?
我们很少用到的过滤语句中包含查询,为了语法的完整性,ES也支持这种。 只有在过滤中用到全文本匹配时候才会使用这种结构。
验证查询 (_validate)
查询语句可以变得非常复杂, 特别是与不同的分析器和字段映射相结合后。
validate API 可以验证一条查询语句是否合法。
POST http://localhost:9200/book/novel/_validate/query
重点看 valid 的返回结果
查看错误信息
想知道语句非法的具体错误信息, 需要加上 explain 参数:
POST: http://localhost:9200/book/novel/_validate/query?explain
查看ES如何执行的
如果是合法语句的话, 使用 explain 参数可以返回一个带有查询语句的可阅读描述, 可以帮助了解查询语句在ES中是如何执行的
以 以下的JSON为例
{ "query":{ "match":{ "title":"Elasticserach" } } }
POST http://localhost:9200/book/novel/_validate/query?explain
关键请求: /_validate/query?explain
返回:
{ "valid": true, "_shards": { "total": 1, "successful": 1, "failed": 0 }, "explanations": [ { "index": "book", "valid": true, "explanation": "+title:elasticserach #_type:novel" } ] }
explanation 会为每一个索引返回一段描述, 因为每个索引会有不同的映射关系和分析器. 上面的就只有一个。 ES如何查询是和分词器有关的。








