以字段为中心的查询(Field-centric Queries)

上述提到的三个问题都来源于most_fields是以字段为中心(Field-centric),而不是以词条为中心(Term-centric):它会查询最多匹配的字段(Most matching fields),而我们真正感兴趣的最匹配的词条(Most matching terms)。

NOTE

best_fields同样是以字段为中心的,因此它也存在相似的问题。

首先我们来看看为什么存在这些问题,以及如何解决它们。

问题1:在多个字段中匹配相同的单词

考虑一下most_fields查询是如何执行的:ES会为每个字段生成一个match查询,让后将它们包含在一个bool查询中。

我们可以将查询传入到validate-query API中进行查看:

GET /_validate/query?explain
{
"query": {
"multi_match": {
"query": "Poland Street W1V",
"type": "most_fields",
"fields": [ "street", "city", "country", "postcode" ]
}
}
}

它会产生下面的解释(explaination):

(street:poland street:street street:w1v) (city:poland city:street city:w1v) (country:poland country:street country:w1v) (postcode:poland postcode:street postcode:w1v)

你可以发现能够在两个字段中匹配poland的文档会比在一个字段中匹配了poland和street的文档的分值要高。

问题2:减少长尾

精度控制(Controlling Precision)一节中,我们讨论了如何使用and操作符和minimum_should_match参数来减少相关度低的文档数量:

{
"query": {
"multi_match": {
"query": "Poland Street W1V",
"type": "most_fields",
"operator": "and",
"fields": [ "street", "city", "country", "postcode" ]
}
}
}

但是,使用best_fields或者most_fields,这些参数会被传递到生成的match查询中。该查询的解释如下(译注:通过validate-query API):

(+street:poland +street:street +street:w1v) (+city:poland +city:street +city:w1v) (+country:poland +country:street +country:w1v) (+postcode:poland +postcode:street +postcode:w1v)

换言之,使用and操作符时,所有的单词都需要出现在相同的字段中,这显然是错的!这样做可能不会有任何匹配的文档。

问题3:词条频度

什么是相关度(What is Relevance)一节中,我们解释了默认用来计算每个词条的相关度分值的相似度算法TF/IDF:

词条频度(Term Frequency)

在一份文档中,一个词条在一个字段中出现的越频繁,文档的相关度就越高。

倒排文档频度(Inverse Document Frequency)

一个词条在索引的所有文档的字段中出现的越频繁,词条的相关度就越低。

当通过多字段进行搜索时,TF/IDF会产生一些令人惊讶的结果。

考虑使用first_name和last_name字段搜索"Peter Smith"的例子。Peter是一个常见的名字,Smith是一个常见的姓氏 - 它们的IDF都较低。但是如果在索引中有另外一个名为Smith Williams的人呢?Smith作为名字是非常罕见的,因此它的IDF值会很高!

像下面这样的一个简单查询会将Smith Williams放在Peter Smith前面(译注:含有Smith Williams的文档分值比含有Peter Smith的文档分值高),尽管Peter Smith明显是更好的匹配:

{
"query": {
"multi_match": {
"query": "Peter Smith",
"type": "most_fields",
"fields": [ "*_name" ]
}
}
}

smith在first_name字段中的高IDF值会压倒peter在first_name字段和smith在last_name字段中的两个低IDF值。

解决方案

这个问题仅在我们处理多字段时存在。如果我们将所有这些字段合并到一个字段中,该问题就不复存在了。我们可以向person文档中添加一个full_name字段来实现:

{
"first_name": "Peter",
"last_name": "Smith",
"full_name": "Peter Smith"
}

当我们只查询full_name字段时:

  • 拥有更多匹配单词的文档会胜过那些重复出现一个单词的文档。
  • minimum_should_match和operator参数能够正常工作。
  • first_name和last_name的倒排文档频度会被合并,因此smith无论是first_name还是last_name都不再重要。

尽管这种方法能工作,可是我们并不想存储冗余数据。因此,ES为我们提供了两个解决方案 - 一个在索引期间,一个在搜索期间。下一节对它们进行讨论。

[Elasticsearch] 多字段搜索 (五) - 以字段为中心的查询的更多相关文章

  1. [Elasticsearch] 多字段搜索 (二) - 最佳字段查询及其调优

    最佳字段(Best Fields) 假设我们有一个让用户搜索博客文章的网站,就像这两份文档一样: PUT /my_index/my_type/1 { "title": " ...

  2. [Elasticsearch] 多字段搜索 (二) - 最佳字段查询及其调优(转)

    最佳字段(Best Fields) 假设我们有一个让用户搜索博客文章的网站,就像这两份文档一样: PUT /my_index/my_type/1 { "title": " ...

  3. [Elasticsearch2.x] 多字段搜索 (二) - 最佳字段查询及其调优 <译>

    最佳字段(Best Fields) 假设我们有一个让用户搜索博客文章的网站,就像这两份文档一样: PUT /my_index/my_type/ { "title": "Q ...

  4. Elasticsearch通关教程(五):如何通过SQL查询Elasticsearch

    前言 这篇博文本来是想放在全系列的大概第五.六篇的时候再讲的,毕竟查询是在索引创建.索引文档数据生成和一些基本概念介绍完之后才需要的.当前面的一些知识概念全都讲解完之后再讲解查询是最好的,但是最近公司 ...

  5. Elasticsearch系列---初识搜索

    概要 本篇主要介绍搜索的报文结构含义.搜索超时时间的处理过程,提及了一下多索引搜索和轻量搜索,最后将精确搜索与全文搜索做了简单的对比. 空搜索 搜索API最简单的形式是不指定索引和类型的空搜索,它将返 ...

  6. ElasticSearch 2 (15) - 深入搜索系列之多字段搜索

    ElasticSearch 2 (15) - 深入搜索系列之多字段搜索 摘要 查询很少是简单的一句话匹配(one-clause match)查询.很多时候,我们需要用相同或不同的字符串查询1个或多个字 ...

  7. Elasticsearch 多字段搜索

    查询很少是对一个字段做 match 查询,通常都是一个 query 查询多个字段,比如一个 doc 有 title.content.pagetag 等文本字段,要在这些字段查询含多个 term 的 q ...

  8. [Elasticsearch] 多字段搜索 (三) - multi_match查询和多数字段 <译>

    multi_match查询 multi_match查询提供了一个简便的方法用来对多个字段执行相同的查询. NOTE 存在几种类型的multi_match查询,其中的3种正好和在“了解你的数据”一节中提 ...

  9. elasticsearch多字段搜索

    https://blog.csdn.net/Ricky110/article/details/78888711 多字段搜索多字符串查询boost 参数 “最佳” 值,较为简单的方式就是不断试错,比较合 ...

随机推荐

  1. php第一节(入门语法、数据类型)

    <?php /** * 变量命名用 $ 符 * 变量名称的命名规范 * 1.变量名称以$标示 * 2.变量名称只能以字母和下划线开头 * 3.变量的名称只能包含字母.下划线.数字 * 4.变量名 ...

  2. kali linux (Raspberry Pi 3b) 更新失败 出现上面的问题

    Invalid signature for Kali Linux repositories : “The following signatures were invalid: EXPKEYSIG ED ...

  3. ABAP术语-Interface Parameter

    Interface Parameter 原文:http://www.cnblogs.com/qiangsheng/archive/2008/02/26/1081800.html Parameter t ...

  4. yum仓库客户端搭建和NTP时间同步客户端配置

    一.yum仓库客户端搭建 yum源仓库搭建分为服务器端和客户端. 服务端主要提供软件(rpm包)和yumlist.也就是提供yum源的位置.一般是通过http或者ftp提供位置. 客户端的配置:yum ...

  5. MIP缓存加速原理 MIP不仅仅只是CDN

    什么是MIP?我想我们现在都知道.可是你真的了解MIP吗?MIP加速原理是什么?MIP 是用 CDN 做加速的么?准确答案是:是,但不只是. 很多人并认为MIP百度排名会靠前,甚至权重会提高?作为一个 ...

  6. BigData--hadoop集群搭建之hbase安装

    之前在hadoop-2.7.3 基础上搭建hbase 详情请见:https://www.cnblogs.com/aronyao/p/hadoop.html 基础条件:先配置完成zookeeper 准备 ...

  7. Leecode刷题之旅-C语言/python-1.两数之和

    开学后忙的焦头烂额(懒得很),正式开始刷leecode的题目了. 想了想c语言是最最基础的语言,虽然有很多其他语言很简单,有更多的函数可以用,但c语言能煅炼下自己的思考能力.python则是最流行的语 ...

  8. 人人都会设计模式:观察者模式--Observer

    https://segmentfault.com/a/1190000012295887 观察者模式是抽像通知者和观察者,达到具体通知者跟具体观察者没有偶合.能达到不管是切换通知者,或者是切换观察者,都 ...

  9. 利用nodejs实现商品管理系统(二)

    下面实现商品管理系统 第一步:对应的ejs与数据交换的编写格式. 商品列表界面product.ejs <% for(var i=0;i<list.length;i++){%> < ...

  10. CUBLAS基础实验

    一.概述 最近在试图进行cuda并行编程,目标是编写一段矩阵计算代码,将计算结果存储进入GPU的缓冲区当中,并在达到某些要求后强制刷新缓冲区,取得计算结果. 但是考虑时间紧任务重的状况和实际的性能要求 ...