目录javascript
term query
: 把检索串看成一个总体来执行检索, 即不会对检索串分词.java
term是彻底匹配检索, 要用在不分词的字段上, 若是某个field在映射中被分词了, term检索将不起做用.
因此, 不分词的field, 要在mapping中设置为不分词.web
—— ES 5.x以后, 为每一个text类型的字段新增了名为keyword的子字段, 是不分词的, 默认保留256个字符.编程
—— 可使用keyword字段进行term检索. 示例:json
GET shop/_search { "query": { "term": { "name.keyword": "Java编程思想" } } }
terms
, 至关于多个term
检索, 相似于SQL中in关键字的用法, 即在某些给定的数据中检索:并发
GET shop/_search { "query": { "terms": { "name.keyword": [ "Java编程思想", "Java并发编程的艺术" ] } } }
prefix query
, 就是前缀检索. 好比商品name中有多个以"Java"开头的document, 检索前缀"Java"时就能检索到全部以"Java"开头的文档.app
—— 扫描全部倒排索引, 性能较差.post
GET shop/_search { "query": { "prefix": { "name": "java" } } }
扫描全部倒排索引, 性能较差.性能
GET shop/_search { "query": { "wildcard": { "name": "ja*" } } }
扫描全部倒排索引, 性能较差.this
GET shop/_search { "query": { "regexp": { "name": "jav[a-z]*" } } }
fuzziness
的默认值是2 —— 表示最多能够纠错两次.
说明: fuzziness
的值太大, 将削弱检索条件的做用, 也就是说纠错次数太多, 就会致使限定检索结果的检索条件被改变, 失去了限定做用.
示例: 检索name中包含"Java"的文档, Java中缺失了一个字母a:
GET shop/_search { "query": { "match": { "name": { "query": "Jav", "fuzziness": 1, "operator": "and" } } } }
经过boost参数, 令知足某个条件的文档的得分更高, 从而使得其排名更靠前.
GET shop/_search { "query": { "bool": { "must": [ { "match": { "name": "编程思想"} } ], "should": [ { "match": { "name": { "query": "艺术", "boost": 2 // 提高评分权重 } } } ] } } }
通常检索中, 检索条件会被分词, bool检索构建多个子检索 (must
| must_not
| should
| filter
), 这些子检索可能会包含多个field. 这时:
多个子检索的field各自匹配少许关键字的文档的分数 > 某个子检索的field匹配大量关键字的文档的分数.
若是咱们但愿检索结果中 (检索串被分词后的) 关键字匹配越多, 这样的文档就越靠前, 而不是多个子检索中匹配少许分词的文档靠前.
⇒ 此时可使用dis_max和tie_breaker.
tie_breaker的值介于0~1之间, Elasticsearch将
bool检索的分数 * tie_breaker
的结果与dis_max的最高分进行比较, 除了取dis_max的最高分之外, 还会考虑其余的检索结果的分数.
为了增长精准度, 经常使用的是配合boost、minimum_should_match等参数控制检索结果.
GET shop/_search { "query": { "dis_max": { "queries": [ { "match": { "name": "虚拟机" } }, { "match": { "desc": "经典" } } ], "tie_breaker": 0.2 // 对同时知足的文档的分值进行提高 } } } GET shop/_search { "query": { "dis_max": { "queries": [ { "match": { "name": { "query": "虚拟机", "minimum_should_match": "50%", "boost": 2 } } }, { "match": { "desc": { "query": "经典", "minimum_should_match": "50%", "boost": 3 } } } ], "tie_breaker": 0.3 } } }
这是Elasticsearch 2.x中的API, 后续版本再也不支持.
检索出版时间在2012-07以后, 且至少知足下述条件中一个的文档:
a. 名称(name)中包含"并发";
b. 描述(desc)中包含"java";
c. 出版社(publisher)名称中不包含"电子".
GET shop/_search { "query": { "bool": { "filter": { // 按时间过滤 "range": { "date": {"gte": "2012-07"} } }, "should": [ // 可匹配, 可不匹配 { "match": { "name": "并发" } }, { "bool": { "must": { // 必须匹配 "match": { "desc": "java" } }, "must_not": { // 不能匹配 "match": { "publisher": "电子" } } } } ], "minimum_should_match": 1 // 至少知足should中的一个条件 } }, // 自定义排序 "sort": [ { "price": { "order": "desc" } } ] }
注意: 排序的字段最好是数字, 或日期, 由于字符串字段会被分词, ES会经过分词后的某个词去排序, 结果难以预测.
匹配检索: name中包含"java"却不包含"虚拟机";
范围检索: 价格大于50、小于80;
结果排序: 按照价格升序排序.
GET shop/_search { "query": { "bool": { "must": { // 必须匹配 "match": { "name": "java" } }, "must_not": { // 必须不匹配 "match": { "name": "虚拟机" } }, "filter": { "range": { "price": { "gte": 40, "lte": 80, "boost": 2.0 // 设置得分的权重值(提高值), 默认是1.0 } } } } } }
关于范围检索的使用, 请参考下篇文章: ES 22 - Elasticsearch对数值或日期类型进行范围检索
(1) 默认排序规则:
ES默认是按检索结果的分值(_score)降序排列的.
某些状况下, 可能存在无实际意义的_score, 好比filter时全部_score的值都相同:
GET website/_search { "query": { "bool": { "filter": { "term": { "author_id": 5520 // 此时全部符合条件的_score都为0 } } } } } // 或经过constant_score过滤: GET website/_search { "query": { "constant_score": { "filter": { "term": { "author_id": 5520 // 此时全部符合条件的_score都为1 } } } } }
(2) 定制排序规则:
GET website/_search { "query": { "constant_score": { "filter": { "term": { "author_id": 5520 } } } }, "sort": [ { "post_date": { "order": "asc" } } ] }
版权声明
出处: 博客园 马瘦风的博客(https://www.cnblogs.com/shoufeng)
感谢阅读, 若是文章有帮助或启发到你, 点个[好文要顶👆] 或 [推荐👍] 吧😜
本文版权归博主全部, 欢迎转载, 但 [必须在文章页面明显位置标明原文连接], 不然博主保留追究相关人员法律责任的权利.