• 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

  • 相关阅读:
    使用yield实现一个协成
    串讲-Python基础练习
    Linux练习
    列表生成式
    Jupyter Notebook的快捷键帮助文档
    mysql字段类型
    爬取12306火车票信息
    【Lodop】02 C-Lodop手册阅读上手
    【Lodop】01 Lodop手册阅读上手
    【Redis】06 事务
  • 原文地址:https://www.cnblogs.com/softidea/p/7128031.html
Copyright © 2020-2023  润新知