繁体   English   中英

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

[英]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访问更快。 但是要求您始终保持您的boostTypesboostValues同步——最好只追加(当您添加新的boostTypes时,列表会在一维中增长)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM