大家好,我是Edison。
相信很多童鞋和我一样,有点傻傻分不清Term查询和全文查询的区别,那么今天我们就来一起梳理一下。
Term(词项)是ES中表达语义的最小单位,搜索和利用统计语言模型进行自然语言处理都需要处理Term。
ES中Term Query包含了:
Term Query / Range Query / Exist Query / Prefix Query / Wildcard Query
ES中Term的特点:
特点1:在ES中,Term查询对输入不做分词。换句话说,它会将输入作为一个整体,在倒排索引中查找准确的词项,并且使用相关度算分公式为每个包含该词项的文档进行相关度算分 - 例如“Apple Store”。
可能上面有点难理解,现在我们通过一个实例来理解。
首先,我们先插入几条示例数据:
然后,我们通过以下Term Query查询desc为iPhone的记录:
当你执行这条查询后,你会发现,ES居然没有查到这条记录,明明我们刚刚插入的就是它啊!
别急,这恰恰是因为Term查询不对输入做分词,会将输入作为一个整体,进而导致我们搜索不到。 我们进一步将上面的查询改为以下方式就可以查询到记录:将iPhone改为全小写的iphone即可。
同时,如果我们想实现一个精确匹配,我们可以使用term的keyword关键字来实现,如下查询所示:精确匹配一个productID。这也说明,在ES中通过keyword关键字查询,它也不会做分词处理。
我们还会发现,Term查询会返回一个算分:0.9808292,代表匹配的精准度。
特点2:可以使用Constant Score将查询转换成一个Filtering,避免算分,并利用缓存,提高性能。
刚刚提到ES会在倒排索引中进行相关性算分,这在一定程度上会带来一些查询上的开销。我们可以通过ConstantScore将Query转成Filter,来避免相关性算分的开销,还可以有效利用缓存,提高查询的效率!
查询结果显示也可以证明它会跳过算分步骤:
基于全文的查询,ES提供了以下Query(我们在第6篇Query DSL中学习的就是全文查询):
Match Query / Match Phrase Query / Query String Query
基于全文的查询具有以下的特点:
特点1:索引和搜索时都会进行分词,查询字符串先传到一个合适的分词器,然后生成一个待查询的词项列表。
特点2:查询会对每个词项进行底层的查询,再将结果进行合并,还会为每个文档生成一个算分。
针对这两个特点,我们通过一个示例来串一下:
例如,查询“Matrix reloaded”,会查到包括Matrix或者reload的所有结果。
首先,构建一个Match Query:
ES会返回title字段中包括Matrix 或者 reloaded的所有记录:
其次,如果你希望查询title字段中同时包含Matrix reloaded,那你可以修改默认的operator为AND来提高精准度:
然后,如果你希望查询的是只要出现Matrix 和 reloaed,其中间可以间隔一些单词,那么你也可以使用match phrase 和 slop参数设置分词出现的最大间隔距离:
最后,这个基于全文的查询在ES中的基本查询过程如下所示:
本篇,我们了解了ElasticSearch的Term和全文查询的基本概念及其特点,利用这些特点在指定的场景会有是事半功倍的效果!
极客时间,阮一鸣,《ElasticSearch核心技术与实战》