zoukankan      html  css  js  c++  java
  • Elasticsearch: 权威指南 » 深入搜索 » 多字段搜索 » 多数字段 good

    多数字段编辑

    全文搜索被称作是 召回率(Recall) 与 精确率(Precision) 的战场: 召回率 ——返回所有的相关文档;精确率 ——不返回无关文档。目的是在结果的第一页中为用户呈现最为相关的文档。

    为了提高召回率的效果,我们扩大搜索范围 ——不仅返回与用户搜索词精确匹配的文档,还会返回我们认为与查询相关的所有文档。如果一个用户搜索 “quick brown box” ,一个包含词语 fast foxes 的文档被认为是非常合理的返回结果。

    如果包含词语 fast foxes 的文档是能找到的唯一相关文档,那么它会出现在结果列表的最上面,但是,如果有 100 个文档都出现了词语 quick brown fox ,那么这个包含词语 fast foxes 的文档当然会被认为是次相关的,它可能处于返回结果列表更下面的某个地方。当包含了很多潜在匹配之后,我们需要将最匹配的几个置于结果列表的顶部。

    提高全文相关性精度的常用方式是为同一文本建立多种方式的索引, 每种方式都提供了一个不同的相关度信号 signal 。主字段会以尽可能多的形式的去匹配尽可能多的文档。举个例子,我们可以进行以下操作:

    • 使用词干提取来索引 jumps 、 jumping 和 jumped 样的词,将 jump 作为它们的词根形式。这样即使用户搜索 jumped ,也还是能找到包含 jumping 的匹配的文档。
    • 将同义词包括其中,如 jump 、 leap 和 hop 。
    • 移除变音或口音词:如 ésta 、 está 和 esta 都会以无变音形式 esta 来索引。

    尽管如此,如果我们有两个文档,其中一个包含词 jumped ,另一个包含词 jumping ,用户很可能期望前者能排的更高,因为它正好与输入的搜索条件一致。

    为了达到目的,我们可以将相同的文本索引到其他字段从而提供更为精确的匹配。一个字段可能是为词干未提取过的版本,另一个字段可能是变音过的原始词,第三个可能使用 shingles 提供 词语相似性 信息。这些附加的字段可以看成提高每个文档的相关度评分的信号 signals ,能匹配字段的越多越好。

    一个文档如果与广度匹配的主字段相匹配,那么它会出现在结果列表中。如果文档同时又与 signal 信号字段匹配,那么它会获得额外加分,系统会提升它在结果列表中的位置。

    我们会在本书稍后对同义词、词相似性、部分匹配以及其他潜在的信号进行讨论,但这里只使用词干已提取(stemmed)和未提取(unstemmed)的字段作为简单例子来说明这种技术。

    多字段映射编辑

    首先要做的事情就是对我们的字段索引两次: 一次使用词干模式以及一次非词干模式。为了做到这点,采用 multifields 来实现,已经在 multifields 有所介绍:

    DELETE /my_index
    
    PUT /my_index
    {
        "settings": { "number_of_shards": 1 }, 
        "mappings": {
            "my_type": {
                "properties": {
                    "title": { 
                        "type":     "string",
                        "analyzer": "english",
                        "fields": {
                            "std":   { 
                                "type":     "string",
                                "analyzer": "standard"
                            }
                        }
                    }
                }
            }
        }
    }

    参考 被破坏的相关度.

    title 字段使用 english 英语分析器来提取词干。

    title.std 字段使用 standard 标准分析器,所以没有词干提取。

    接着索引一些文档:

    PUT /my_index/my_type/1
    { "title": "My rabbit jumps" }
    
    PUT /my_index/my_type/2
    { "title": "Jumping jack rabbits" }

    这里用一个简单 match 查询 title 标题字段是否包含 jumping rabbits (跳跃的兔子):

    GET /my_index/_search
    {
       "query": {
            "match": {
                "title": "jumping rabbits"
            }
        }
    }

    因为有了 english 分析器,这个查询是在查找以 jump 和 rabbit 这两个被提取词的文档。两个文档的 title 字段都同时包括这两个词,所以两个文档得到的评分也相同:

    {
      "hits": [
         {
            "_id": "1",
            "_score": 0.42039964,
            "_source": {
               "title": "My rabbit jumps"
            }
         },
         {
            "_id": "2",
            "_score": 0.42039964,
            "_source": {
               "title": "Jumping jack rabbits"
            }
         }
      ]
    }

    如果只是查询 title.std 字段,那么只有文档 2 是匹配的。尽管如此,如果同时查询两个字段,然后使用 bool 查询将评分结果 合并 ,那么两个文档都是匹配的( title 字段的作用),而且文档 2 的相关度评分更高( title.std 字段的作用):

    GET /my_index/_search
    {
       "query": {
            "multi_match": {
                "query":  "jumping rabbits",
                "type":   "most_fields", 
                "fields": [ "title", "title.std" ]
            }
        }
    }

    我们希望将所有匹配字段的评分合并起来,所以使用 most_fields 类型。这让 multi_match 查询用 bool 查询将两个字段语句包在里面,而不是使用 dis_max 查询。

    {
      "hits": [
         {
            "_id": "2",
            "_score": 0.8226396, 
            "_source": {
               "title": "Jumping jack rabbits"
            }
         },
         {
            "_id": "1",
            "_score": 0.10741998, 
            "_source": {
               "title": "My rabbit jumps"
            }
         }
      ]
    }

     

    文档 2 现在的评分要比文档 1 高。

    用广度匹配字段 title 包括尽可能多的文档——以提升召回率——同时又使用字段 title.std 作为 信号 将相关度更高的文档置于结果顶部。

    每个字段对于最终评分的贡献可以通过自定义值 boost 来控制。比如,使 title 字段更为重要,这样同时也降低了其他信号字段的作用:

    GET /my_index/_search
    {
       "query": {
            "multi_match": {
                "query":       "jumping rabbits",
                "type":        "most_fields",
                "fields":      [ "title^10", "title.std" ] 
            }
        }
    }

    title 字段的 boost 的值为 10 使它比 title.std 更重要。

    https://www.elastic.co/guide/cn/elasticsearch/guide/current/most-fields.html

  • 相关阅读:
    【转】win8.1下安装ubuntu
    Codeforces 1025G Company Acquisitions (概率期望)
    Codeforces 997D Cycles in Product (点分治、DP计数)
    Codeforces 997E Good Subsegments (线段树)
    Codeforces 1188E Problem from Red Panda (计数)
    Codeforces 1284E New Year and Castle Building (计算几何)
    Codeforces 1322D Reality Show (DP)
    AtCoder AGC043C Giant Graph (图论、SG函数、FWT)
    Codeforces 1305F Kuroni and the Punishment (随机化)
    AtCoder AGC022E Median Replace (字符串、自动机、贪心、计数)
  • 原文地址:https://www.cnblogs.com/twodog/p/12139998.html
Copyright © 2011-2022 走看看