elasticsearch 基于嵌套字段值的弹性搜索应用boost,elasticsearch,kibana,elasticsearch-7,elasticsearch,Kibana,Elasticsearch 7" /> elasticsearch 基于嵌套字段值的弹性搜索应用boost,elasticsearch,kibana,elasticsearch-7,elasticsearch,Kibana,Elasticsearch 7" />

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

elasticsearch 基于嵌套字段值的弹性搜索应用boost,elasticsearch,kibana,elasticsearch-7,elasticsearch,Kibana,Elasticsearch 7,下面是我的索引文档 { "defaultBoostValue":1.01, "boostDetails": [ { "Type": "Type1", "value": 1.0001 }, { "Type": "Type2", "value": 1.002

下面是我的索引文档

 {
  "defaultBoostValue":1.01,
  "boostDetails": [
    {
      "Type": "Type1",
      "value": 1.0001
    },
    {
      "Type": "Type2",
      "value": 1.002
    },
    {
      "Type": "Type3",
      "value": 1.0005
    }
  ]
}
我想基于传递的值应用boost,所以假设我传递类型1,那么应用的boost将是1.0001,如果类型1不存在,那么它将使用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映射的结构有帮助,那么我可以,但请解释它如何有帮助,并加快查询速度。如果答案包含修改映射,请提供映射类型和修改的结构。

使用动态映射(许多字段) 与之前的相比,您似乎调整了文档结构

上面的查询被认为是针对嵌套字段的,由于性能原因,这些字段无法在脚本中轻松迭代。话虽如此,上面的方法是一种更慢的解决方法,它可以访问文档的源代码并迭代其内容。但是请记住,不建议在脚本中访问
\u源代码

如果您的文档不再嵌套,您可以访问所谓的查询时间访问优化程度更高的:

{
  "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"]
差不多吧

然后,在构造Elasticsearch查询时,您将根据
boostType
查找
boostValues
数组索引,并将此数组索引传递给脚本查询,脚本查询将从上面访问相应的
boostValues
文档值


这保证比源代码访问速度更快但需要始终保持
boostTypes
boostValues
同步
——最好只追加(当您添加新的
boostTypes
时,列表会在一维中增长)。

谢谢,如果索引结构类似于{boost:{Type1:1.00003},{Type2:1.222},那么上面的方法就行了,对吗,它应该。这将需要有动态索引,我正在寻找没有动态索引的解决方案。我已经编辑了问题以匹配原始问题,还添加了原始问题的链接您将有多少类型?知道吗?