【问题标题】:Name searching in ElasticSearchElasticSearch 中的名称搜索
【发布时间】:2017-04-12 09:30:26
【问题描述】:

我在 ElasticSearch 中创建了一个索引,其字段名称用于存储一个人的全名:姓名和姓氏。我想对该字段执行全文搜索,因此我使用分析器对其进行了索引。

我现在的问题是,如果我搜索: “约翰·拉姆·拉姆”

在我有“John Rham Rham Luck”的索引中,该值的得分高于“John Rham Rham”。 是否有可能在确切字段上比在字符串中具有更多值的字段中获得更好的分数?

提前致谢!

【问题讨论】:

    标签: elasticsearch full-text-search fulltext-index


    【解决方案1】:

    我设计了一个小例子(假设你在 ES 5.x 上运行导致得分差异的原因):

    DELETE test
    PUT test
    {
      "settings": {
        "similarity": {
          "my_bm25": {
            "type": "BM25",
            "b": 0
          }
        }
      },
      "mappings": {
        "test": {
          "properties": {
            "name": {
              "type": "text",
              "similarity": "my_bm25",
              "fields": {
                "length": {
                  "type": "token_count",
                  "analyzer": "standard"
                }
              }
            }
          }
        }
      }
    }
    
    POST test/test/1
    {
      "name": "John Rham Rham"
    }
    POST test/test/2
    {
      "name": "John Rham Rham Luck"
    }
    GET test/_search
    {
      "query": {
        "function_score": {
          "query": {
            "match": {
              "name": {
                "query": "John Rham Rham",
                "operator": "and"
              }
            }
          },
          "functions": [
            {
              "script_score": {
                "script": "_score / doc['name.length'].getValue()"
              }
            }
          ]
        }
      }
    }
    

    此代码执行以下操作:

    • 用自定义的替换默认的 BM25 实现,调整 B 参数(字段长度标准化) -- 您还可以将相似度更改为“经典”以返回没有此规范化的 TF/IDF
    • 为您的姓名字段创建一个内部字段,用于计算您姓名字段中的标记数。
    • 根据令牌长度更新分数

    这将导致:

    "hits": {
        "total": 2,
        "max_score": 0.3596026,
        "hits": [
          {
            "_index": "test",
            "_type": "test",
            "_id": "1",
            "_score": 0.3596026,
            "_source": {
              "name": "John Rham Rham"
            }
          },
          {
            "_index": "test",
            "_type": "test",
            "_id": "2",
            "_score": 0.26970196,
            "_source": {
              "name": "John Rham Rham Luck"
            }
          }
        ]
      }
    }
    

    不确定这是否是最好的方法,但它可能会为您指明正确的方向:)

    【讨论】:

      猜你喜欢
      • 2014-05-27
      • 1970-01-01
      • 2014-01-05
      • 2013-05-18
      • 2014-04-25
      • 2021-09-17
      • 1970-01-01
      • 1970-01-01
      • 2021-06-07
      相关资源
      最近更新 更多