![](/img/trans.png)
[英]Elastic search apply boost only for certain documents based on their field value
[英]Elastic search apply boost based on nested field value
下面是我的索引文档
{
"defaultBoostValue":1.01,
"boostDetails": [
{
"Type": "Type1",
"value": 1.0001
},
{
"Type": "Type2",
"value": 1.002
},
{
"Type": "Type3",
"value": 1.0005
}
]
}
我想根据传递的值应用 boost,所以假设我传递 Type 1,那么 boost 应用的将是 1.0001,如果 Type1 不存在,那么它将使用 defaultBoostValue 下面是我的查询,它工作但很慢,有什么方法可以优化它进一步
原始问题上述查询有效,但由于我们使用 _source 很慢
{
"query": {
"function_score": {
"boost_mode": "multiply",
"functions": [
"script_score": {
"script": {
"source": """
double findBoost(Map params_copy) {
for (def group : params_copy._source.boostDetails) {
if (group['Type'] == params_copy.preferredBoostType ) {
return group['value'];
}
}
return params_copy._source['defaultBoostValue'];
}
return findBoost(params)
""",
"params": {
"preferredBoostType": "Type1"
}
}
}
}
]
}
}
}
我已经删除了没有动态映射的条件,如果更改 boostDetails 映射的结构可以提供帮助,那么我可以,但请解释它如何帮助并更快地查询如果答案包含修改映射,请提供映射类型和修改后的结构。
与原始问题相比,您似乎调整了文档结构。
上面的查询被认为是嵌套字段,出于性能原因,这些字段无法在脚本中轻松迭代。 话虽如此,上面是一个更慢的解决方法,它访问文档的_source
并迭代其内容。 但请记住,不建议在脚本中访问_source
!
如果您的文档不再嵌套,您可以访问所谓的文档值,这些值针对查询时访问进行了更优化:
{
"query": {
"function_score": {
...
"functions": [
{
...
"script_score": {
"script": {
"lang": "painless",
"source": """
try {
if (doc['boost.boostType.keyword'].value == params.preferredBoostType) {
return doc['boost.boostFactor'].value;
} else {
throw new Exception();
}
} catch(Exception e) {
return doc['fallbackBoostFactor'].value;
}
""",
"params": {
"preferredBoostType": "Type1"
}
}
}
}
]
}
}
}
从而加快您的 function 分数查询。
由于嵌套迭代很慢并且动态映射会破坏您的索引,因此您可以将您的提升存储在每个文档的标准化有序列表中:
"boostValues": [1.0001, 1.002, 1.0005, ..., 1.1]
并在构建查询的后端跟踪相应的提升类型的顺序:
var boostTypes = ["Type1", "Type2", "Type3", ..., "TypeN"]
所以像n-hot 向量这样的东西。
然后,当您构建 Elasticsearch 查询时,您将根据boostType
查找boostValues
的数组索引,并将此数组索引从上面传递给脚本查询,该脚本查询将访问相应的boostValues
文档值。
这保证比_source
访问更快。 但是要求您始终保持您的boostTypes
和boostValues
同步——最好只追加(当您添加新的boostTypes
时,列表会在一维中增长)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.