在嵌套属性中使用 function_score 进行弹性搜索提升

Øyv*_*ind 5 elasticsearch

在 Elasticsearch 中,给定以下文档结构:

"workhistory": {
  "positions": [{
    "company": "Some company",
    "position": "Some Job Title",
    "start": 1356998400,
    "end": 34546576576,
    "description": "",
    "source": [
       "some source", 
       "some other source"
    ]
  },
  {
    "company": "Some other company",
    "position": "Job Title",
    "start": 1356998400,
    "end": "",
    "description": "",
    "source": [
       "some other source"
    ]
  }]
}
Run Code Online (Sandbox Code Playgroud)

和此结构的映射:

  workhistory: {
    properties: {    
      positions: {
        type: "nested", 
        include_in_parent: true, 
        properties: {                 
          company: {
            type: "multi_field",
            fields: {
              company: {type: "string"},
              original: {type : "string", analyzer : "string_lowercase"} 
            }              
          }, 
          position: {
            type: "multi_field",
            fields: {
              position: {type: "string"},
              original: {type : "string", analyzer : "string_lowercase"} 
            }              
          }                                                       
        }
      }        
    }
  }
Run Code Online (Sandbox Code Playgroud)

如果 company = "some company" 等,我希望能够搜索“company”并匹配文档。然后我想获得 tf idf _score。我还想根据“源”字段数组的值创建一个 function_score 查询来提高此匹配的分数。基本上,如果源包含“某些源”,则用 x 量提升 _score。如果需要,我可以更改“源”属性的结构。

这是我到目前为止得到的:

{
   "bool": {
      "should": [
         {
            "filtered": {
               "query": {
                  "bool": {
                     "should": [
                        {
                           "bool": {
                              "should": [
                                 {
                                    "match": {
                                       "workhistory.positions.company.original": "some company"
                                    }
                                 }
                              ]
                           }
                        }
                     ],
                     "minimum_should_match": "100%"
                  }
               },
               "filter": {
                  "and": [
                     {
                        "bool": {
                           "should": [
                              {
                                 "term": {
                                    "workhistory.positions.company.original": "some company"
                                 }
                              }
                           ]
                        }
                     }
                  ]
               }
            }
         },
         {
            "function_score": {
               "query": {
                  "bool": {
                     "should": [
                        {
                           "bool": {
                              "should": [
                                 {
                                    "match": {
                                       "workhistory.positions.company.original": "some company"
                                    }
                                 }
                              ]
                           }
                        }
                     ],
                     "minimum_should_match": "100%"
                  }
               },
               "filter": {
                  "and": [
                     {
                        "bool": {
                           "should": [
                              {
                                 "term": {
                                    "workhistory.positions.company.original": "some company"
                                 }
                              }
                           ]
                        }
                     }
                  ]
               }
            }
         }
      ]
   }
}
Run Code Online (Sandbox Code Playgroud)

这里也有一些过滤器,因为我只想返回带有过滤值的文档。在这个例子中,过滤器和查询基本相同,但在这个查询的更大版本中,我有一些其他的“可选”匹配来提升可选值等。 function_score 现在没有做太多,因为我真的不知道了解如何使用它。目标是能够在我的应用程序代码中调整提升的数量并将其传递给搜索查询。

我使用的是 Elasticsearch 1.3.4 版。

And*_*fan 2

老实说,我不知道你为什么重复所有这些过滤器和查询。也许我错过了一些东西,但根据你的描述,我相信你所需要的只是一个“function_score”。从文档中:

function_score 允许您修改查询检索的文档的分数。

因此,您定义一个查询(例如 - 匹配公司名称),然后定义一个函数列表,这些函数应该提高特定文档子集的 _score。来自同一文档:

此外,可以组合多种功能。在这种情况下,人们可以选择仅当文档与给定过滤器匹配时才应用该函数

因此,您有一个查找具有特定名称的公司的查询,然后您有一个函数的过滤器,用于操作与过滤器匹配的文档的 _score 。在这种情况下,您的过滤器是应该包含某些内容的“源”。该函数本身是一个脚本:_score + 2. 最后,我的想法是:

    {
      "query": {
        "bool": {
          "should": [
            {
              "function_score": {
                "query": {
                  "bool": {
                    "should": [
                      {
                        "bool": {
                          "should": [
                            {
                              "match": {
                                "workhistory.positions.company.original": "some company"
                              }
                            }
                          ]
                        }
                      }
                    ],
                    "minimum_should_match": "100%"
                  }
                },
                "functions": [
                  {
                    "filter": {
                      "nested": {
                        "path": "workhistory.positions",
                        "query": {
                          "bool": {
                            "should": [
                              {
                                "match": {
                                  "workhistory.positions.source": "some source"
                                }
                              }
                            ]
                          }
                        }
                      }
                    },
                    "script_score": {
                  "script": "_score + 2"
                }
              },
              {
                "filter": {
                  "nested": {
                    "path": "workhistory.positions",
                    "query": {
                      "bool": {
                        "should": [
                          {
                            "match": {
                              "workhistory.positions.source": "xxx"
                            }
                          }
                        ]
                      }
                    }
                  }
                },
                "script_score": {
                  "script": "_score + 4"
                }
              }
            ],
            "max_boost": 5,
            "score_mode": "sum",
            "boost_mode": "sum"
          }
        }
      ]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)