按嵌套字段匹配的百分比对 ElasticSearch 结果进行排序

Order ElasticSearch results by percentage of nested field matches

我想根据嵌套字段的匹配百分比对 ElasticSearch 查询结果进行排序。

例如,假设我有一个结构如下的 ElasticSearch 索引:

{
    "properties": {
        "name": {
            "type": "text"
        },
        "jobs": {
            "type": "nested",
            "properties": {
                "id": {
                    "type": "long"
                }
            }
        }
    }
}

具有以下文件:

{
    "name": "Alice",
    "jobs": [
        { "id": 1 },
        { "id": 2 },
        { "id": 3 },
        { "id": 4 }
    ]
}
{
    "name": "Bob",
    "jobs": [
        { "id": 1 },
        { "id": 2 },
        { "id": 3 }
    ]
}
{
    "name": "Charles",
    "jobs": [
        { "id": 2 },
        { "id": 3 }
    ]
}

现在,我想执行查询以查找哪些文档具有特定职位,按匹配职位的百分比排序。 例如:

到目前为止,我使用的是以下查询,但它按匹配数而不是百分比排序:

{
    "query": {
        "nested": {
            "path": "jobs",
            "query": {
                "bool": {
                    "should": [
                        {
                            "match": {
                                "jobs.id": "1"
                            }
                        },
                        {
                            "match": {
                                "jobs.id": "2"
                            }
                        }
                    ]
                }
            },
            "score_mode":"sum"
        }
    }
}

script_score 似乎可以做到:

{
  "query": {
    "function_score": {
      "query": {
        "nested": {
          "path": "jobs",
          "query": {
            "bool": {
              "should": [
                {
                  "match": {
                    "jobs.id": "1"
                  }
                },
                {
                  "match": {
                    "jobs.id": "2"
                  }
                }
              ]
            }
          },
          "score_mode": "sum"
        }
      },
      "script_score": {
        "script": {
          "source": "_score / params['_source']['jobs'].length"
        }
      }
    }
  }
}