elasticsearch - Elasticsearch-multi_match和简短查询

标签 elasticsearch

我有这样的查询(我删除了排序部分,因为没有关系):

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不会得到任何结果。

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

最佳答案

之所以会出现这种现象,是因为您设置了"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搜索期间将获得的 token 。使用min_grammax_gram,您可以配置gram中字符的最小/最大长度。

如果您需要使用omething等处理情况(开头缺少字母),请尝试使用NGram analyzer进行处理。

关于elasticsearch - Elasticsearch-multi_match和简短查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45539976/

相关文章:

elasticsearch - Elasticsearch -有没有一种方法可以强制文档中可能符合 “must_not”标准的结果?

java - 在 Spring Boot 中将 Apache Mahout 与 ElasticSearch 集成

elasticsearch - 在添加到 ES 时 JSON 数组的 mapper_parsing_exception 错误

apache-spark - Spark 上下文 : Error initializing SparkContext While Running Spark Job

php - 设置elasticsearch php客户端的connect_timeout

docker - 如何为 Swisscom elasticsearch 公共(public)云 (CloudFoundry) 配置 Kibana

c# - Elastic Search提取附件插件 block

java - 查询 Spring Data Elasticsearch 的嵌套属性

elasticsearch - 在script_score中使用嵌套值

elasticsearch - 创建索引后创建自定义分析器