zoukankan      html  css  js  c++  java
  • Elasticsearch搜索之cross_fields分析

    cross_fields类型采用了一种以词条为中心(Term-centric)的方法,这种方法和best_fields及most_fields采用的以字段为中心(Field-centric)的方法有很大的区别。

    它将所有的字段视为一个大的字段,然后在任一字段中搜索每个词条。 

    operator:operator设为了and,表示所有的词条都需要出现;

    minimum_should_match:表示文本匹配度,控制搜索精度,向下取整。

    相比most_fields与best_fields,解释起来可能费力一些,我们不妨根据问题来引导说明。

      一、cross_fields能解决什么问题?

       有一类实体存储,比如人名,地址等,不是存储在单一的field里边,人名可以分为first_name,last_name。

       地址有street, country, city等字段组成。这类实体查询的特殊性在于,每一个single query string都是跨越了多个字段(请仔细理解这句话)。

       前边用的most_field的方法并不能满足我们的要求,会带来错误的结果。原因有几个:

       1)  most_field是用来找出最佳的field,这个field能满足最多的word的匹配,而不是跨越多个field去寻找最佳满足words的匹配。
       2) 不能使用operator和minimum_should_match来减少相关性低的doc的长尾问题
       3) 每一个field的tf是不一样的,相互之间交错会产生不好的排序结果。

       most_field问题的根本原因就在于:most_field是field centric的,目的就是寻找最佳匹配的field,而我们想要的是最佳匹配的term。
       best_field也存在同样问题,他们都是field centric。我们来看看问题是如何产生的,如何解决之。

      (1)在多个field中匹配到同样的word

        most_field实质是生成了多个match子查询,每个子查询针对一个field,然后包装成一个bool查询。
        因此,如果同一个word在多个field中都出现,相比,两个word同时在一个field中出现,谁得分更高?显然是第一个,但不是我们想要的结果。

         演示过程在most_field章节有具体的说明。


    (2)运用operator/minimun_should_match来解决长尾

        显而易见,如果指定了operator=AND,没有一个doc可以match到,从语义上也是错误的。

       (3)  现在我们查询Peter Smith,在first_name和last_name中。Peter是一个很普遍的first_name,smith是一个很普遍的last_name。因此两者都具有较低的idf。

         但是,如果我们有一个doc是Smith Williams?smith可是一个不常见的first_name。但        是返回结果呢?Smith Williams得分更高,但是我们要查询的是Peter Smith啊???原因就在于Smith在first_name中的高idf已经压过了peter作为一个低      idf出现在的first_name中和smith作为一个低idf出现在last_name中。

      解决方案:

      以上原因在于我们是在多个field中处理。因此我们只需要将多个field的信息整合成一个即可。

      比如:生成一个full_name字段(可以用custom _all field的方法,mapping中设置copyto参数),包括first_name和last_name。

      我们针对full_name做查询,以上三个问题就不会出现。

      但是,我们存储了冗余的信息。elasticsearch考虑到这一点,提出了另外一个解决方案,就是cross fields query。

    二、cross fields query

    对于上述问题,custom all是一种不过的解决方案,除了冗余信息以外,这种方案是在index过程中就要指定的,有没有在查询时的解决方法呢?es提供了cross field query的解决方案。

    best field 和 most field是field centric的,而cross field是term centric的。这是最大的不同。cross field把multi field 看做一整个field,在这一个field里边去match 每一个term,相当于在多个field中match。

    field centric的逻辑是这样的(operator=AND):

    (+first_name Peter +first_name Smith)

    (+last_name Peter +last_name Smith)

    term centric的逻辑是这样的(operator=AND):

    +(first_name Peter last_name Peter)

    +(last_name Smith last_name Smith)

    也就是说peter必须出现在其中一个字段中,同时smith也必须出现在其中一个字段中。

    所以cross field其实是首先分析query string 产生一个 term list,针对每一个term在任何一个field中match。

    因为6中问题1 问题2就解决了,问题3呢?

    cross field 在field之间把inf混合起来,作为一个整体。

    +blended(“peter” fields:[ "first_name", "last_name"])

    +blended(“smith” fields:[ "first_name", "last_name"])

    也就是说同时在first_name和last_name中查询smith的idf,取最小值。这样smith作为一个普通的last_name,也作为一个普通的first_name。

    问题3解决。

    注意一点:cross fields search中的field要使用同样的analyzer。如果使用不同的analyzed,则会按照analyzer对fields进行分组blended,工作模式类似于best field。

    比如title使用了一个analyzer,first_name 和last_name 使用了另外一个analyzer,则

    (+title peter +title smitch)



    +blended(“peter” fields:[ "first_name", "last_name"])

    +blended(“smith” fields:[ "first_name", "last_name"])



    cross field相对于custom all的优势在于:可以在查询时指定每一个field的boost值。

  • 相关阅读:
    【项目】 技术选型 平台和语言
    WCF 常见逻辑和代码 1.错误处理和配置
    一个挺有意思的Javascript小问题
    【设计原则和建议】 方法返回值
    一次HTTP请求中的缓存
    【设计原则和建议】 方法
    【设计原则和建议】 字段
    Express全系列教程之(一):Express的安装 和第一个程序
    js switch语句祥解[范围判断]
    修改notepad++ zencodeing 插件的配置路径
  • 原文地址:https://www.cnblogs.com/clonen/p/6674939.html
Copyright © 2011-2022 走看看