目录html
今天再读庄子的《逍遥游》,其中鲲鹏之扶摇直上九万里之气势,蜩(tiao)与学鸠之眇小之对比,使人印象深入,并对鲲鹏之志心生向往。而郭象在注《庄子》卷中却说,"苟足于其性,则虽大鹏无以自贵于小鸟,小鸟无羡于天池,而荣愿有余矣。故小大虽殊,逍遥一也。"观看自身,虽然不是什么领导,老总,但也彻底没必要感到为职业生涯忧虑,只要热爱程序员这个工做,享受编码的乐趣,作到 80 岁又有何妨。java
书归正传,今天咱们聊聊 Match Phase Query。程序员
match_phrase
查询针对的是一个语句,好比 "like football", 分析时也会将整个语句做为总体,而不会像上篇的 match 查询 会将整个语句拆分为单个词条。json
举个例子,建立一个 match_phase type 并塞进去一个文档, message 是 I like swimming and riding!api
PUT matchphasetest {} PUT matchphasetest/_mapping/match_phase { "properties": { "message": { "type": "text" } } } PUT matchphasetest/match_phase/1 { "message": "I like swimming and riding!" } GET matchphasetest/_search { "query": { "match_phrase": { "message": "I like swimming" } } }
默认使用 match_phrase
时会精确匹配查询的短语,须要所有单词和顺序要彻底同样,标点符号除外。app
这种精确匹配在大部分状况下显得太严苛了,有时咱们想要包含 ""I like swimming and riding!"" 的文档也可以匹配 "I like riding"。这时就要以用到 "slop" 参数来控制查询语句的灵活度。elasticsearch
slop
参数告诉 match_phrase
查询词条相隔多远时仍然能将文档视为匹配 什么是相隔多远? 意思是说为了让查询和文档匹配你须要移动词条多少次?ide
以 "I like swimming and riding!" 的文档为例,想匹配 "I like riding",只须要将 "riding" 词条向前移动两次,所以设置 slop
参数值为 2, 就能够匹配到。ui
GET matchphasetest/_search { "query": { "match_phrase": { "message": { "query": "I like riding", "slop": 2 } } } }
match_phrase
语句也能够设置 analyzer
参数来定义查询语句时对其中词条执行的分析过程。this
默认状况下,使用的是建立 mapping 时的分析器,若是没有指定就会使用默认的查询分析器。这里举个例子(只是如何使用)
GET /_search { "query": { "match_phrase" : { "message" : { "query" : "this is a test", "analyzer" : "my_analyzer" } } } }
match_phrase
也接受 zero_terms_query
为参数,使用方式和 match
查询语句相同
match_phrase_prefix
和 match_phrase
用法是同样的,区别就在于它容许对最后一个词条前缀匹配。以上节的数据为例,查询 I like sw
就能匹配到
I like swimming and riding
。
GET matchphasetest/_search { "query": { "match_phrase_prefix": { "message": "I like swi" } } }
官方文档中说 match_phrase_prefix
查询中有个参数 max_expansions
说的是参数 max_expansions
控制着能够与前缀匹配的词的数量,默认值是 50。
以 I like swi
查询为例,它会先查找第一个与前缀 swi
匹配的词,而后依次查找搜集与之匹配的词(按字母顺序),直到没有更多可匹配的词或当数量超过 max_expansions
时结束。
可是我在使用时,故意造出了数十个以 swi
开头的词,而将 max_expansions
的值设为 10。可是却返回了全部的结果。在 elasitc 官网也有对该问题的讨论, 也是没有找到答案。这个问题做为一个公案权且记下,若是您知道缘由,麻烦告诉我,很是感谢。
这里也贴出个例子,以备后面排查
GET matchphaseprefixtest/_search { "query": { "match_phrase_prefix": { "message": { "query": "I like sw", "max_expansions": 10 } } } }
match_phrase_prefix
用起来很是方便,可以实现输入即搜索的效果,可是也会出现问题。 假如说查询 I like s
而且想要匹配 I like swimming
,结果是默认状况下它会搜索出前 50 个组合,若是前 50 个没有 swimming
,那就不会显示出结果。只能是用户继续输入后面的字母才可能匹配出结果。
要实现更好的即便搜索的特性,能够看看 completion suggester 和
Index-Time Search-as-You-Type 能不能实现。
本文论述了 Match Phase Query 和 Match Phrase 前缀查询 的使用,下文会讲解 Multi Match Query 敬请期待。