3
{
  "query": {
    "custom_filters_score": {
      "query": {
        "term": {
          "name": "user1234"
        }
      },
      "filters": [
        {
          "filter": {
            "term": {
              "subject": "math"
            }
          },
          "script": "_score + doc['subject_score'].value"
        }
      ]
    }
  }
}

如果脚本与上面类似,它会给出Error: unresolvable property or identifier: _score If script is like"script": "doc['subject_score'].value"它以类似 boost 的方式将 _score 相乘。我想用自定义分数替换 elasticsearch _score。

4

2 回答 2

5

如果我对您的理解正确,您想在主题不是数学的情况下使用弹性搜索评分,并且您想在主题是数学的情况下使用自定义评分。如果您使用的是 Elasticsearch v0.90.4 或更高版本,则可以使用新function_score查询来实现:

{
    "query": {
        "function_score": {
            "query": {
                "term": {
                    "name": "user1234"
                }
            },
            "functions": [{
                "filter": {
                    "term": {
                        "subject": "math"
                    }
                },
                "script_score": {
                    "script": "doc[\"subject_score\"].value"
                }
            }, {
                "boost_factor": 0

            }],
            "score_mode": "first",
            "boost_mode": "sum"
        }
    }
}

在 v0.90.4 之前,您将不得不使用custom_scoreand的组合custom_filters_score

{
    "query": {
        "custom_score": {
            "query": {
                "custom_filters_score": {
                    "query": {
                        "term": {
                            "name": "user1234"
                        }
                    },
                    "filters": [{
                        "filter": {
                            "term": {
                                "subject": "math"
                            }
                        },
                        "script": "-1.0"
                    }]
                }
            },
            "script": "_score < 0.0 ? _score * -1.0 + doc[\"subject_score\"].value : _score"
        }
    }
}

或如@javanna 建议的那样,使用多个由 bool 查询组合在一起的 custom_score 查询:

{
    "query": {
        "bool": {
            "disable_coord": true,
            "should": [{
                "filtered": {
                    "query": {
                        "term": {
                            "name": "user1234"
                        }
                    },
                    "filter": {
                        "bool": {
                            "must_not": [{
                                "term": {
                                    "subject": "math"
                                }
                            }]
                        }
                    }
                }
            }, {
                "filtered": {
                    "query": {
                        "custom_score": {
                            "query": {
                                "term": {
                                    "name": "user1234"
                                }
                            },
                            "script": "doc['subject_score'].value"
                        }
                    },
                    "filter": {
                        "term": {
                            "subject": "math"
                        }
                    }
                }
            }]
        }
    }
}
于 2013-07-18T02:03:28.223 回答
2

Firstly I'd like to say that there are many ways of customising the scoring in elasticsearch and it seems like you may have accidentally picked the wrong one. I will just summarize two and you will see what the problem is:

Custom Filters Score

If you read the docs (carefully) on custom_filters_score then you will see that it there for performance reasons, to be able to use for scoring the the faster filter machinery of elasticsearch. (Filters are faster as scoring is not calculated when computing the hit set, and they are cached between requests.)

At the end of the docs; it mentions custom_filters_score can take a "script" parameter to use instead of a "boost" parameter per filter. Best way to think of this is to calculate a number, which will be passed up to the parent query to be combined with the other sibling queries to calculate the total score for the document.

Custom Score Query

Reading the docs this is used when you want to customise the score from the query and change it how you wish. There is a _score variable available to you to use in your "script" which is the score of the query inside the custom_score query.

Try this:

"query": {
    "filtered": {
        "query": {
            "custom_score": {
                "query": { 
                    "match_all": {}
                },
                "script": "doc['subject_score'].value" //*see note below
            }
        },
        "filter": {
            "and": [
                {
                    "term": {
                        "subject": "math"
                    }
                },
                {
                    "term": {
                        "name": "user1234"
                    }
                }
            ]
        }
    }
}

*NOTE: If you wanted to you could use _score here. Also, I moved both your "term" parts to filters as any match of a term would get the same score and filters are faster.

Good luck!

于 2013-07-16T13:16:08.057 回答