基于对象数组的弹性搜索过滤器 [英] Elastic search filter based on array of object

查看:83
本文介绍了基于对象数组的弹性搜索过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我所拥有的地图

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

我想基于类型应用boost类型,因此,如果boostType为Type3,则boostFactor应该为1.0005,如果它没有该boostType,则应该应用"defaultBoostValue".作为助推器 以下是我尝试过的查询

I want to apply boost type based on type , so if boostType is Type3 then boostFactor should be 1.0005, and if it does not have that boostType, it should apply "defaultBoostValue" as boost below is the query which i have tried

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

由于boostDetails是对象数组,因此无法正常工作,如何在这种情况下应用过滤器

it is not working as expected as boostDetails is array of object, how can we apply filter on such case

推荐答案

您可以使用

You could use a 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根本不会默认.

but keep in mind that if this particular boost type (Type1) does not exist in a given document, the filter of your function_score query will prevent this script from activation -> the defaultBoostValue won't be defaulted to at all.

所以我建议使用的是match_all过滤器,当然还要保留preferredBoostType:

So what I'd recommend instead is using a match_all filter instead and of course keeping the preferredBoostType:

{
  "query": {
    "function_score": {
      "boost_mode": "multiply",
      "functions": [
        {
          "filter": {
            "match_all": {}                          <---
          },
          "script_score": {
            "script": {
              "source": """

                ...

              """,
              "params": {
                "preferredBoostType": "Type1"
              }
            }
          }
        }
      ]
    }
  }
}

顺便说一句,如果您的boostDetails数组不是nested类型,您可能会遇到意料之外的结果,如这里这里.

BTW, if your boostDetails array is not of type nested, you'll probably encounter unexpected and seemingly results as explained here and here.

这篇关于基于对象数组的弹性搜索过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆