将多个不同的function_score与Elasticsearch组合在一起

时间:2019-06-02 12:10:41

标签: elasticsearch

我有几个不同的Elasticsearch function_score,但是我不确定如何将它们组合

这是我正在查看的测试集(我添加了注释,以便能够引用问题中的特定项目,这些注释实际上不在索引中)

[
    { // Item 1
        "priority": 0.7,
        "classification": [
            {
                "feature": "A",
                "confidence": 0.4
            },
            {
                "feature": "C",
                "confidence": 0.3
            },
            {
                "feature": "B",
                "confidence": 0.6
            }
        ]
    },
    { // Item 2
        "priority": 0.8,
        "classification": [
            {
                "feature": "A",
                "confidence": 0.3
            },
            {
                "feature": "C",
                "confidence": 0.6
            }
        ]
    },
    { // Item 3
        "priority": 0.4,
        "classification":  [
            {
                "feature": "D",
                "confidence": 0.6
            },
            {
                "feature": "C",
                "confidence": 0.8
            }
        ]
    }
]

现在假设我要对以下权重的项目进行评分:

  • “ A”,权重为2
  • 重量为3的“ B”

我想执行以下操作:

  1. 仅针对功能“ A”和“ B”计算每个项目的平均置信度(例如,项目1的平均置信度为0.5)
  2. 计算每个项目的优先级(例如0.8个项目2的受欢迎程度)
  3. 计算每个项目要素的权重总和(如果项目具有要素“ A”,则其权重为2,如果 它具有特征“ B”,它的权重为3。项目1的权重为5,项目2的权重为2)
  4. 将不同的计算合并为最终分数

我知道如何为平均置信度创建function_score,就像这样:

{
  "nested": {
    "path": "classification",
    "query": {
       "function_score": {
          "functions": [
              {
                  "field_value_factor": {
                      "field": "classification.confidence",
                      "missing": 0
                  },
                  "weight": 0
              }
          ],
          "query": {
              "terms": {
                  "classification.feature": [
                      "A",
                      "B"
                  ]
              }
          },
          "score_mode": "avg"
        }
    }
  }
}

我也知道如何为优先级字段创建功能分数,就像这样:

{
    "function_score": {
        "functions": [
            {
                "field_value_factor": {
                    "field": "popularity",
                    "missing": 0
                },
                "weight": <some-weight>
            }
        ],
        "score_mode": "sum"
    }
}

我认为(但不确定)我知道如何为特征权重的总和创建函数得分(忽略不匹配“ A”或“ B”的特征的权重)。可能是这样的:

{
  "query": {
        "function_score": {
            "query": {
                "bool": {
                    "should": [
                        { "match": { "classification.feature": "A" } },
                        { "match": { "classification.feature": "B" } }
                    ]
                }
            },
            "functions": [
              {
                  "filter": { "match": { "classification.feature": "A" } },
                  "weight": 2
              },
              {
                  "filter": { "match": { "classification.feature": "B" } },
                  "weight": 3
              },
            ],
            "score_mode":"sum"
        }
    }
}

但是我不知道如何组合这3个不同的功能分数(我目前不确定实际的组合功能是什么。我将需要使用不同的功能并确定哪个功能最适合我,但对于我们可以说我想对3个function_score的结果取平均值)

所以我的问题是:

  1. 是否可以定义多个function_score,然后定义如何组合它们?
  2. 如果无法合并多个function_score,我应该采用哪种方法来解决此问题? (我不固定使用3个不同的function_score,但不确定如何使用此功能)
  3. 尽管我说过我想对所有function_score结果进行平均,但以后我可能想做一些 有点像这样:score("popularity") + (score("feature-weight") * score("confidence"))-是 有没有办法做到这一点?

我目前正在ES 2.4.5上对此进行测试(我不赞成使用它)。我们将很快升级 无论如何,除了:

  • 是否只能使用更高版本的ES来实现?
  • 即使只有在更高版本的ES中才有可能,我仍然想知道如何实现它(并在升级后使用它)

使用谷歌搜索并没有任何有用的信息

预先感谢

1 个答案:

答案 0 :(得分:1)

我认为您应该使用script_score。它允许使用字段文档的值来计算分数。使用script_score,您无需编写多个function_score

您还可以将参数传递给功能分数,以在查询时设置功能的权重。

Elasticsearch 2有一个很好的示例,用于script_score的高级用法:https://www.elastic.co/guide/en/elasticsearch/guide/current/script-score.html