首页 > 其他分享 >elasticsearch best_fields most_fields cross_fields从内在实现看区别——本质就是前两者是以field为中心,后者是词条为中心

elasticsearch best_fields most_fields cross_fields从内在实现看区别——本质就是前两者是以field为中心,后者是词条为中心

时间:2023-07-04 18:33:03浏览次数:42  
标签:last name fields smith cross field 字段 query

1.最佳字段(Best fields)::

假设我们有一个让用户搜索博客文章的网站(允许多字段搜索,最佳字段查询),就像这两份文档一样:

PUT /my_index/my_type/1
{
    "title": "Quick brown rabbits",
    "body":  "Brown rabbits are commonly seen."
}

PUT /my_index/my_type/2
{
    "title": "Keeping pets healthy",
    "body":  "My quick brown fox eats rabbits on a regular basis."
}

// SENSE: 110_Multi_Field_Search/15_Best_fields.json

用户输入了"Brown fox",文档2匹配的更好一些,因为它包含了用户寻找的两个单词。

{
    "multi_match": {
        "query":                "Quick brown fox",
        "type":                 "best_fields", <1>
        "fields":               [ "title", "body" ],
        "tie_breaker":          0.3,
        "minimum_should_match": "30%" <2>
    }
}
2.多数字段(Most fields)::

一个用来调优相关度的常用技术是将相同的数据索引到多个字段中。它用来尽可能多地匹配文档。

考虑一下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" ]
    }
  }
}

// SENSE: 110_Multi_Field_Search/40_Entity_search_problems.json

它会产生下面的解释(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的文档的分值要高。

3.跨字段(Cross fields)::

对于一些实体,标识信息会在多个字段中出现,每个字段中只含有一部分信息:

  • Person: first_name 和 last_name
  • Book: titleauthor, 和 description
  • Address: streetcitycountry, 和 postcode

此时,我们希望在任意字段中找到尽可能多的单词。我们需要在多个字段中进行查询,就好像这些字段是一个字段那样。

用户也许会搜索名为"Peter Smith"的人,或者名为"Poland Street W1V"的地址。每个查询的单词都出现在不同的字段中。

如果你在索引文档前就能够自定义_all字段的话,那么使用_all字段就是一个不错的方法。但是,ES同时也提供了一个搜索期间的解决方案:使用类型为cross_fields的multi_match查询。cross_fields类型采用了一种以词条为中心(Term-centric)的方法,这种方法和best_fields及most_fields采用的以字段为中心(Field-centric)的方法有很大的区别。它将所有的字段视为一个大的字段,然后在任一字段中搜索每个词条。

为了阐述以字段为中心和以词条为中心的查询的区别,看看以字段为中心的most_fields查询的解释(译注:通过validate-query API得到):

GET /_validate/query?explain
{
    "query": {
        "multi_match": {
            "query":       "peter smith",
            "type":        "most_fields",
            "operator":    "and", <1>
            "fields":      [ "first_name", "last_name" ]
        }
    }
}

// SENSE: 110_Multi_Field_Search/50_Cross_field.json

<1> operator设为了and,表示所有的词条都需要出现。

对于一份匹配的文档,peter和smith两个词条都需要出现在相同的字段中,要么是first_name字段,要么是last_name字段:

(+first_name:peter +first_name:smith)
(+last_name:peter  +last_name:smith)

而以词条为中心的方法则使用了下面这种逻辑:

+(first_name:peter last_name:peter)
+(first_name:smith last_name:smith)

换言之,词条peter必须出现在任一字段中,同时词条smith也必须出现在任一字段中。

cross_fields类型首先会解析查询字符串来得到一个词条列表,然后在任一字段中搜索每个词条。仅这个区别就能够解决在以字段为中心的查询中提到的3个问题中的2个,只剩下倒排文档频度的不同这一问题。

幸运的是,cross_fields类型也解决了这个问题,从下面的validate-query请求中可以看到:

GET /_validate/query?explain
{
    "query": {
        "multi_match": {
            "query":       "peter smith",
            "type":        "cross_fields", <1>
            "operator":    "and",
            "fields":      [ "first_name", "last_name" ]
        }
    }
}

// SENSE: 110_Multi_Field_Search/50_Cross_field.json

<1> cross_fields 使用以词条为中心(Term-centric)进行匹配。

它通过混合(Blending)字段的倒排文档频度来解决词条频度的问题:

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

换言之,它会查找词条smith在first_name和last_name字段中的IDF值,然后使用两者中较小的作为两个字段最终的IDF值。因为smith是一个常见的姓氏,意味着它也会被当做一个常见的名字。

提示:为了让cross_fields查询类型能以最佳的方式工作,所有的字段都需要使用相同的解析器。使用了相同的解析器的字段会被组合在一起形成混合字段(Blended Fields)。

如果你包含了使用不同解析链(Analysis Chain)的字段,它们会以和best_fields相同的方式被添加到查询中。比如,如果我们将title字段添加到之前的查询中(假设它使用了一个不同的解析器),得到的解释如下所示:

(+title:peter +title:smith)
(
  +blended("peter", fields: [first_name, last_name])
  +blended("smith", fields: [first_name, last_name])
)

当使用了minimum_should_match以及operator参数时,这一点尤为重要。

摘自:https://es.xiaoleilu.com/110_Multi_Field_Search/50_Cross_field.html

 

标签:last,name,fields,smith,cross,field,字段,query
From: https://blog.51cto.com/u_11908275/6624065

相关文章

  • IDEA:MAVEN:先:An illegal reflective access operation has occurred 后:Cannot access d
    maven打包发现出现以下警告,但是可以运行 通过在 VM选项中添加 --illegal-access=deny--add-opensjava.base/java.lang=ALL-UNNAMED 不再出现刚才提示。之后出现CannotaccessdefaultsfieldofProperties发现自己新创建的项目,没有配置相应插件就使用了。添加即可......
  • Netty-LengthFieldBasedFrameDecoder-解决拆包粘包问题的解码器
    LengthFieldBasedFrameDecoder的构造器参数中包括:maxFrameLength:指定解码器所能处理的数据包的最大长度,超过该长度则抛出TooLongFrameException异常。lengthFieldOffset:指定长度字段的起始位置。lengthFieldLength:指定长度字段的长度。lengthAdjustment:指定长度字段所表示......
  • 关于 SAP UI5 的 CrossApplicationNavigation 服务
    从SAPUI5应用启动时观察Chrome开发者工具console面板,看到如下提示的错误消息:sap.ui.comp.navpopover.SemanticObjectController:Service'CrossApplicationNavigation'couldnotbeobtained-SAPUI5CrossApplicationNavigation是一种用于在SAPFioriLaunchpad......
  • UnrecognizedPropertyException: Unrecognized field 解决
    转载请注明出处:在项目得不同环境上对接外部的服务接口,且存在不同版本间可能有字段不同得问题,遇到这种问题在使用jackson解析时,如果格式化得字符串与定义得java类不能完全对应时,就会报错:Unrecognizedfield,代码还原:importcom.fasterxml.jackson.annotation.JsonProperty;......
  • Cross-thread operation not valid: Control 'txtMessage' accessed from a thread ot
    WinformTextBox Cross-threadoperationnotvalid:Control'txtMessage'accessedfromathreadotherthanthethreaditwascreatedon. (330条消息)解决Cross-threadoperationnotvalid的问题_GuanXX的博客-CSDN博客  privatevoidsafeSetText(stringt......
  • 关于 cross-env 和 process.env
    cross-envkentcdodds/cross-env:......
  • Markov Transition Field,马尔可夫转移场(matlab版)
    MarkovTransitionField,马尔可夫转移场(matlab版)将一维时间序列转成二维数据可以对原数据进行更好地表征,从而基于新的表征结合深度学习机器视觉技术来发掘更多的规律和信息。这使得MarkovTransitionField,马尔可夫转移场在金融,能源电力,水利,气象、机械设备,交通等领域时间序列分析......
  • cross socket ICrossHttpServer
    crosssocketICrossHttpServercrosssocket是delphi跨平台的一个socket库。///<author>cxg2023-2-12</author>///TStream(ARequest.body),autobefreeunitsock.CrossHttpSvr;interfaceusessystem.JSON,json.help,keyValue.serialize,api.router,N......
  • 海康SDK注册报错 Structure.getFieldOrder() on class com.xxx.sdk.HCNetSDK$NET_DVR_
    Structure.getFieldOrder()onclasscom.xxx.sdk.HCNetSDK$NET_DVR_DEVICEINFO_V30doesnotprovideenoughnames[0]海康依赖的版本较低,项目引用的较高,导致海康注册报错,所以降低jna版本 <dependency><groupId>net.java.dev.jna</groupId><artifactId>jna<......
  • opcenter camstar designer基础知识--Fields
    点击工具栏的Fields 最左侧的窗格包含一个选择树,其中列出了所有可用的字段类型类别。展开类别可显示更具体的字段类型定义。右键单击字段类型可执行以下任务:• add添加字段定义• Rename重命名字段定义• Remove移除字段定义“重命名字段定义”和“移除字段......