在ElasticSearch中基于优先级列表获取文档

j0pj023g  于 4个月前  发布在  ElasticSearch
关注(0)|答案(1)|浏览(69)

我的索引中的文档具有以下字段

{
  "weight" : int
  "tags" : string[]
}

字符串
tags是一个字符串列表。例如-["A", "B", "C", "D"]。让我们假设我的索引有以下数据

[
    {
        "weight": 1,
        "tags": [
            "B",
            "C"
        ]
    },
    {
        "weight": 2,
        "tags": [
            "A"
        ]
    },
    {
        "weight": 3,
        "tags": [
            "B"
        ]
    },
    {
        "weight": 4,
        "tags": [
            "A",
            "C"
        ]
    },
    {
        "weight": 5,
        "tags": [
            "C"
        ]
    }
]


我有一个参数priority = ["A", "C"]。我想根据优先级列表来获取文档。因此,由于“A”在列表中出现在第一位,所以带有标签“A”的文档应该首先出现在输出中。如果doc1doc2都有相同的标签,那么带有更大weight的文档应该首先出现在输出中。因此输出应该是

[
    {
        "weight": 4,
        "tags": [
            "A",
            "C"
        ]
    },
    {
        "weight": 2,
        "tags": [
            "A"
        ]
    },
    {
        "weight": 5,
        "tags": [
            "C"
        ]
    },
    {
        "weight": 1,
        "tags": [
            "B",
            "C"
        ]
    }
]


我们可以在ElasticSearch中实现这一点吗?我也听说过Painless脚本。如果可以的话,我们如何在这里使用Painless脚本?

s4n0splo

s4n0splo1#

你需要知道的第一件事是,在tags数组中索引的标签不一定按照你在源代码中指定的顺序索引。通常,词汇顺序占主导地位,虽然它适用于像ABC这样的简单字母,但你的真实的标签可能不同,并且不按词汇顺序列出。总结一下,你不能依靠标签列表的顺序来提升某些文档相对于其他文档的质量。
类似地,如果在查询中指定terms子句,使AC具有给予更高的重要性(如在priority = ["A", "C"]中),则ES不一定使用该顺序执行查询。
下面我给你的解决方案尊重你的优先级的概念排序,通过使用bool/should查询,其中第一个元素的提升因子比第二个大,第二个元素的提升因子比第三个大,等等。我们应该将A提升到C之上,所以我给标签为A的文档提升2,标签为C的文档提升1。如果你有三个标签,你会从3开始,相反.这将适当地提高文件按照你想要的优先级.
下一部分是考虑具有相等分数的文档,为此,我们可以简单地按降序权重排序:

GET prio/_search
{
  "sort": [
    {
      "_score": {
        "order": "desc"
      }
    },
    {
      "weight": {
        "order": "desc"
      }
    }
  ], 
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "tags.keyword": {
              "value": "A",
              "boost": 2
            }
          }
        },
        {
          "term": {
            "tags.keyword": {
              "value": "C",
              "boost": 1
            }
          }
        }
      ]
    }
  }
}

字符串
上面的查询,当在您的文档样本集上执行时,将产生您期望的结果:

"hits": [
  {
    "_index": "prio",
    "_id": "4",
    "_score": 2.5930133,
    "_source": {
      "weight": 4,
      "tags": [
        "A",
        "C"
      ]
    },
    "sort": [
      2.5930133,
      4
    ]
  },
  {
    "_index": "prio",
    "_id": "2",
    "_score": 1.9826791,
    "_source": {
      "weight": 2,
      "tags": [
        "A"
      ]
    },
    "sort": [
      1.9826791,
      2
    ]
  },
  {
    "_index": "prio",
    "_id": "5",
    "_score": 0.6103343,
    "_source": {
      "weight": 5,
      "tags": [
        "C"
      ]
    },
    "sort": [
      0.6103343,
      5
    ]
  },
  {
    "_index": "prio",
    "_id": "1",
    "_score": 0.6103343,
    "_source": {
      "weight": 1,
      "tags": [
        "B",
        "C"
      ]
    },
    "sort": [
      0.6103343,
      1
    ]
  }
]

相关问题