弹性搜索基于嵌套字段值应用boost



下面是我的索引文档

{
"defaultBoostValue":1.01,
"boostDetails": [
{
"Type": "Type1",
"value": 1.0001
},
{
"Type": "Type2",
"value": 1.002
},
{
"Type": "Type3",
"value": 1.0005
}
]
}

我想根据传递的值应用boost,所以假设我通过Type1,那么应用的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"
}
}
}
}
]
}
}
}

从而加快函数分数查询。


使用有序值列表的备选方案

由于嵌套迭代很慢,动态映射会破坏索引,您可以将您的提升存储在每个文档的标准化有序列表中:

"boostValues": [1.0001, 1.002, 1.0005, ..., 1.1]

,并在构建查询的后端跟踪相应的boost类型的顺序:

var boostTypes = ["Type1", "Type2", "Type3", ..., "TypeN"]

也就是n个热向量

然后,当您构造Elasticsearch查询时,您将查找数组索引基于boostTypeboostValues的索引,并将该数组索引传递给上面的脚本查询,该脚本查询将访问相应的boostValuesdoc-value。

这保证比_source访问快。但是需要始终保持boostTypesboostValues同步——最好只追加(当你添加新的boostTypes时,列表在一个维度上增长)。

相关内容

  • 没有找到相关文章

最新更新