实现类似于关系型数据库中的like'%querystring%'之前一直基于ik分词,以为无法实现完全匹配。现在实现整理出来,记录下备忘、共享。先看下ES提供的NGramTokenizer实现完全匹配
NGramTokenizer
1、先看下NGram分词器属性min_gram:单个词的最小长度,默认1max_gram:但歌词的最大长度,默认2token_chars:大概就是es会按照不在列表中的字符集合进行文本分割(具体意思大家看图原文^_^)
2、token_chars字符classes:letterforexamplea,b,ïor京digitforexample3or7whitespaceforexample""or"\n"punctuationforexample!or"symbolforexample$or√
3、先看个example,curl-XPUT霁授作犬9;localhost:9200/test'-d刻八圄俏9;{"settings":{"analysis":{"analyzer":{"my_ngram_analyzer":{"tokenizer":"my_ngram_tokenizer"}},"tokenizer":{"my_ngram_tokenizer":{"type":"nGram","min_gram":"2","max_gram":"3","token_chars":["letter","digit"]}}}}}'
4、看下这个的分词效果curl'localhost:9200/test/_analyze?pretty=1&analyzer=my_ngram_analyzer'-d'中华人民共和国'
完全匹配实现
1、定义一个charsplit的分析器,使用的ngram分瓠鲺闲剔词。min_gram、max_gram为1,同时我只需要匹配letter、digit、punctuat足毂忍珩ion。curl-XPUT'localhost:9200/dm_v1'-d'{"settings":{"analysis":{"analyzer":{"charSplit":{"type":"custom","tokenizer":"ngram_tokenizer"}},"tokenizer":{"ngram_tokenizer":{"type":"nGram","min_gram":"1","max_gram":"1","token_chars":["letter","digit","punctuation"]}}}}}'
2、接下来创建mapping,可以参考我前面的学习四里面创建mapping,指定分析器为前面一步中定义的
3、接下来使用完全匹配查询试试啦.只出一条完全匹配的数据,搞定!{"query":{"multi_match":{"query":"query_string","type":"phrase","slop":0,"fields":["content"],"analyzer":"charSplit","max_expansions":1}}}
4、最后记录一个组合的多条件查询要求:查出样本1中,内容或者url或标题包含‘new’的所有记录。需要注意的是fields中的属性include_in_all都是true的,这样_all才能对该字段搜索{"query":{"bool":{"must":[{"term":{"sample":1}},{"multi_match":{"query":"new","type":"phrase","slop":0,"fields":["content","url","bid_title"],"analyzer":"charSplit","max_expansions":1}}]}}}