【问题标题】:Elasticsearch - multi_match together with short queriesElasticsearch - multi_match 和短查询
【发布时间】:2017-08-07 15:26:07
【问题描述】:

我有这样的查询(我已经删除了排序部分,因为它无关紧要):

GET _search
{
  "query": {
    "multi_match": {
        "query":  "somethi",
        "fields": [ "title", "content"],
        "fuzziness" : "AUTO",
        "prefix_length" : 0
    }
  }
}

运行此程序时,我得到如下结果:

"hits": [
  {
    "_index": "test_index",
    "_type": "article",
    "_id": "2",
    "_score": 0.083934024,
    "_source": {
      "title": "Matching something abc",
      "content": "This is a piece of content",
      "categories": [
        {
          "name": "B",
          "weight": 4
        }
      ]
    },
    "sort": [
      4,
      0.083934024,
      "article#2"
    ]
  },
  {
    "_index": "test_index",
    "_type": "article",
    "_id": "3",
    "_score": 0.18436861,
    "_source": {
      "title": "Matching something abc",
      "content": "This is a piece of content containing something",
      "categories": [
        {
          "name": "C",
          "weight": 3
        }
      ]
    },
    "sort": [
      3,
      0.18436861,
      "article#3"
    ]
  },
  ...

所以得到预期的结果没有问题。但是我注意到,我从查询中删除了一个字母以改为 someth,Elasticsearch 不会返回任何结果。

这对我来说很奇怪。 multi_match 似乎在进行部分匹配,但不知何故需要使用最少的 x 个字符。同样,如果我尝试输入查询,例如omethin 我会得到结果,但只使用omethi 我不会得到任何结果。

是否有任何设置来设置查询中的最小字符数,或者我可能需要重写我的查询以实现我想要的?我想在多个字段上运行匹配(在上面对标题和内容字段的查询中),这将允许部分匹配和模糊性。

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    你得到这个行为是因为你有 "fuzziness": "AUTO" 参数集,这意味着在一个超过 5 个字符的单词中,最多可以放错两个字符。通常,fuzziness parameter 告诉 elasticsearch 查找最多有两个更改的所有术语,其中更改是单个字符的插入、删除或替换。对于模糊性,不可能有两个以上的更改。

    如果您需要能够使用部分匹配进行搜索,您可以尝试使用Edge NGram analyzer 配置索引并将其设置为您的titlecontent 字段。您可以轻松测试它的工作原理:

    使用以下映射创建 na 索引:

    PUT http://127.0.0.1:9200/test
    {
      "settings": {
        "analysis": {
          "analyzer": {
            "edge_ngram_analyzer": {
              "tokenizer": "my_tokenizer"
            }
          },
          "tokenizer": {
            "my_tokenizer": {
              "type": "edge_ngram",
              "min_gram": 2,
              "max_gram": 10,
              "token_chars": [
                "letter",
                "digit"
              ]
            }
          }
        }
      }
    }
    

    然后运行这个查询:

    curl -X POST \
      'http://127.0.0.1:9200/test/_analyze?pretty=true' \
      -d '{
      "analyzer" : "edge_ngram_analyzer",
      "text" : ["something"]
    }'
    

    结果你会得到:

    {
        "tokens": [
            {
                "token": "so",
                ...
            },
            {
                "token": "som",
                ...
            },
            {
                "token": "some",
                ...
            },
            {
                "token": "somet",
                ...
            },
            {
                "token": "someth",
                ...
            },
            {
                "token": "somethi",
                ...
            },
            {
                "token": "somethin",
                ...
            },
            {
                "token": "something",
                ...
            }
        ]
    }
    

    这些是您在使用edge_ngram_analyzer 进行搜索时将获得的令牌。使用 min_grammax_gram,您可以配置 gram 中字符的最小/最大长度。

    如果您需要处理omething 等的情况(开头缺少字母)尝试与NGram analyzer 相同。

    【讨论】:

    • 谢谢。我今天在玩 NGRAM analyer,它似乎完成了这项工作。我和fuzinness一起使用没有更大的问题
    猜你喜欢
    • 1970-01-01
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-16
    相关资源
    最近更新 更多