【问题标题】:Elastic search filter based on array of object基于对象数组的弹性搜索过滤器
【发布时间】:2021-01-13 01:23:39
【问题描述】:

下面是我的映射

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

我想根据 type 应用 boost 类型,所以如果 boostType 是 Type3 那么 boostFactor 应该是 1.0005,如果它没有那个 boostType,它应该应用 "defaultBoostValue" 作为 boost 以下是我尝试过的查询

{
  "query": {
    "function_score": {
      "boost_mode": "multiply",
      "functions": [
        {
          "filter": {
            "match": {
              "boostDetails.Type": "Type1"
            }
          },
          "field_value_factor": {
            "field": "boostDetails.value",
            "factor": 1,
            "missing": 1
          }
        }
      ]
    }
  }
}

它没有按预期工作,因为 boostDetails 是对象数组,我们如何在这种情况下应用过滤器

【问题讨论】:

    标签: elasticsearch kibana elasticsearch-7


    【解决方案1】:

    您可以使用Script Score function_score query

    {
      "query": {
        "function_score": {
          "boost_mode": "multiply",
          "functions": [
            {
              "filter": {
                "match": {
                  "boostDetails.Type": "Type1"
                }
              },
              "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"
                  }
                }
              }
            }
          ]
        }
      }
    }
    

    但请记住,如果给定文档中不存在这种特定的提升类型 (Type1),则 function_score 查询的 filter 将阻止激活此脚本 -> defaultBoostValue 不会'根本不会默认。

    所以我建议改为使用match_all 过滤器,当然还要保留preferredBoostType

    {
      "query": {
        "function_score": {
          "boost_mode": "multiply",
          "functions": [
            {
              "filter": {
                "match_all": {}                          <---
              },
              "script_score": {
                "script": {
                  "source": """
    
                    ...
    
                  """,
                  "params": {
                    "preferredBoostType": "Type1"
                  }
                }
              }
            }
          ]
        }
      }
    }
    

    顺便说一句,如果您的 boostDetails 数组不是 nested 类型,您可能会遇到意想不到的看似结果,正如 herehere 所解释的那样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-10
      • 2020-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-07
      • 1970-01-01
      相关资源
      最近更新 更多