最近,项目中用到了elastic的查询。我发现目前查询大致有两种方式:Match和Term。那么这两种方式都有什么区别呢?又各自应用于什么场合合适呢?下面我将这两种方式的使用过程mark一下。
1. 两者的使用的根本区别是什么?
根据官网介绍,“The term query finds documents that contain the exact term specified in the inverted index.it doesn’t know anything about the field’s analyzer” 意思是term查询意味着从elastic的倒序index中精准匹配对应的短语。并不包括短语的解析。何为精准?就是大小写都一样,完全匹配。“Hello”和“hello”就是不同的两个短语,是会区分大小写的。“hello world” 就是“hello world", 而不会去查询“Hello world”,更不会将短语拆开为“hello”和“world” 来匹配。而match查询呢,“match queries accept text/numerics/dates, analyzes them, and constructs a query.” 这里很明确地,就是match会进行短语解析来进行匹配。如“hello world” 短语会被解析为“Hello world”等各种大小写都符合条件,并且拆开后的hello, world任意出现一个(或的关系)也会认为是匹配项。
由此可见,两者的根本区别是match包含了elastic的filed‘s analyzer,而term只是简单的判断两个短语是否相等。
2. 两者查询对比验证
在清楚1两者的根本的区别后,我们就用官网给出的查询例子的结果来说明一下:
/put my_index/_doc/1 {"full_text": "Quick Foxes!"} 默认情况下,不定义对应的mapping关系,则full_text字段对应的是elastic 的text类型。此时我们按照下面的方式来查询:
1) /my_index/search {"query":{"match":{"full_text": "Quick Foxes!"}}} 则记录1这条会返回;那么我们改成
2)/my_index/search {"query":{"term":{"full_text": "Quick Foxes!"}}} 则记录1这条会返回吗?答案是: 不会!!!
从1的分析我们知道,term查询只能是短语精确匹配对应的倒序索引才能返回。那么,这里就涉及到短语“Quick Foxes!“ 的倒序索引是什么呢?从elastic的官网我们得知,如果这个字段类型是text,则倒序索引是一个词语数组["quick","foxes"], 此时,“Quick Foxes!" 则和这个倒序索引的任何一个元素都不一样,因此查询返回空。但如果这个字段定义为keyword,则情况就不一样了,它告诉elastic,这个字段的短语是不可分割的,其整体作为倒序索引的一个元素。因此,如果我们定义表mapping如下:
PUT my_index { "mappings": {"_doc": { "properties": {"full_text": { "type": "text" }, "exact_value": { "type": "keyword"}}}}}
然后,创建index如下:
PUT my_index/_doc/1 { "full_text": "Quick Foxes!", "exact_value": "Quick Foxes!" }
此时我们将查询条件改成:
1) /my_index/search {"query":{"match":{"exact_value": "Quick Foxes!"}}}
2)/my_index/search {"query":{"term":{"exact_value": "Quick Foxes!"}}}
3) /my_index/search {"query":{"match":{"exact_value": "quick foxes!"}}}
4)/my_index/search {"query":{"term":{"exact_value": "quick foxes!"}}}
5) /my_index/search {"query":{"match":{"exact_value": "foxes!"}}}
运行结果测试如下:
1)有结果返回。
2)有结果返回。
3)有结果返回。
4)无结果返回。
5)有结果返回。
对于exact_value字段,因为类型是keyword,所以倒序索引就是它本身。因此上面只有2)精确匹配才能返回。而对于match,会自动拆解分析,所以都有返回。 因此,结论就是:
1.在采用默认mapping情况下,因为是text类型,必须要采用match来匹配才能查到结果;
2.若要达到精确的短语匹配,可以改变类型为keyword,自建mapping来创建index。然后可以用term查询来获取精准匹配结果。
参考文章:
1.https://www.elastic.co/guide/en/elasticsearch/reference/6.2/query-dsl-term-query.html
网友评论