在 Elasticsearch 中执行此类查询的正确方法是什么?

时间:2021-03-04 10:58:54

标签: elasticsearch elasticsearch-7

我正在尝试在 Elasticsearch 中进行查询,以提供比我今天所做的更准确的结果。

在我的文档中,我有一个 brand 属性、一个 description 属性和一个 size 属性。示例文档可以是:

{
  brand: "Coca Cola",
  size: "1l",
  description: "drink"
}

假设用户搜索 "Coca Cola drink 1l"。现在,我想要以下提升值:

  • brand4
  • description1
  • size2

每个属性都可以包含任何类型的字符串值,并且不受任何限制。此外,每个属性都使用自己的分析器(但为了简单起见已从示例中删除)。

现在,实现上述目标的最佳方法是什么?

我的尝试

方法一

这种方法搜索每个属性中的每个词,每个属性具有不同的权重。它确保所有单词单独匹配至少一个属性。

{
  "query": {
    "bool": {
      "must": [
        {
          "bool": {
            "should": [
              { "match": { "brand": { "boost": 4, "query": "Coca" } } },
              { "match": { "description": { "boost": 1, "query": "Coca" } } },
              { "match": { "size": { "boost": 2, "query": "Coca" } } }
            ],
            "minimum_should_match": 1
          }
        },
        {
          "bool": {
            "should": [
              { "match": { "brand": { "boost": 4, "query": "Cola" } } },
              { "match": { "description": { "boost": 1, "query": "Cola" } } },
              { "match": { "size": { "boost": 2, "query": "Cola" } } }
            ],
            "minimum_should_match": 1
          }
        },
        {
          "bool": {
            "should": [
              { "match": { "brand": { "boost": 4, "query": "drink" } } },
              { "match": { "description": { "boost": 1, "query": "drink" } } },
              { "match": { "size": { "boost": 2, "query": "drink" } } }
            ],
            "minimum_should_match": 1
          }
        },
        {
          "bool": {
            "should": [
              { "match": { "brand": { "boost": 4, "query": "1l" } } },
              { "match": { "description": { "boost": 1, "query": "1l" } } },
              { "match": { "size": { "boost": 2, "query": "1l" } } }
            ],
            "minimum_should_match": 1
          }
        }
      ]
    }
  }
}

上述方法的问题是升压关闭。品牌 "Coca Cola" 由两个词组成,然后使用 8 而不是 4 的值进行提升。

方法二

我尝试使用多匹配查询(最低应匹配“100%”,每个属性都有单独的提升。

我觉得这样好一些,但我无法为每个单独的属性指定一个分析器。

方法 3

我尝试对每个单独的属性使用整个句子。我觉得这是正确的方法,但是搜索 "foobar" 仍然会产生 1 个结果(出于某种原因)。

{
  "query": {
    "bool": {
      "should": [
         { "match": { "brand": { "minimum_should_match": 1, "boost": 4, "query": "Coca Cola drink 1l" } } },
         { "match": { "description": { "minimum_should_match": 1, "boost": 1, "query": "Coca Cola drink 1l" } } },
         { "match": { "size": { "minimum_should_match": 1, "boost": 2, "query": "Coca Cola drink 1l" } } }
      ],
      "minimum_should_match": 1
    }
  }
}

1 个答案:

答案 0 :(得分:0)

在这种情况下,要走的路是使用 Multi Match Query,有多种方法可以根据您的需要处理评分。

索引文档

POST test_mathias/_doc
{
  "brand": "Coca Cola",
  "size": "1l",
  "description": "drink"
}

查询

POST test_mathias/_search
{
  "query": {
    "multi_match": {
      "query": "Cola",
      "fields": ["brand^4", "description^1", "size^2"]
    }
  }
}

回复

{
  "took" : 10,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.1507283,
    "hits" : [
      {
        "_index" : "test_mathias",
        "_type" : "_doc",
        "_id" : "QdBP_XcB46EpgstaAC0C",
        "_score" : 1.1507283,
        "_source" : {
          "brand" : "Coca Cola",
          "size" : "1l",
          "description" : "drink"
        }
      }
    ]
  }
}