如何用Elasticsearch对嵌套字段进行脚本排序?

ws51t4hk  于 2022-11-22  发布在  ElasticSearch
关注(0)|答案(1)|浏览(218)

我正在处理的文档如下所示:

{
  "product_name": "abc",
  "prices": {
    "regular": 9.99,
    "pricing_tables": [
     { "id": 1, "price": 8.99 },
     { "id": 2, "price": 7.99 }
    ]
  }
}

其中 prices.pricing_tables 是一个嵌套字段。
我想做的是用下面的逻辑排序,给定一个定价表id:

  • 如果嵌套字段包含给定的id,则使用pricing_tables.price
  • 如果嵌套字段不包含id,则使用prices.regular

到目前为止我尝试使用的查询:

"sort": [
{
  "_script": {
    "type": "number",
    "script": {
      "lang": "painless",
      "source": """
        if(doc['prices.pricing_tables.price'].size() != 0) { 
          return doc['prices.pricing_tables.price'].value; 
        } 
        else {
          return doc['prices.regular'].value;
        }
        """
    },
    "nested": {
      "path": "prices.pricing_tables",
      "filter": {
        "term": {"prices.pricing_tables.id": 1}
      }
    },
    "order": "asc"
  }
}  
]

但是,它并没有按预期方式工作。如果pricing_tables嵌套对象中没有条目,则结果中的排序值始终为1。7976931348623157E308
我错过了什么?这是可能的吗?

kjthegm6

kjthegm61#

你的nested过滤器实际上是排除所有pricing_tables.id不等于1的文档。然后Elasticsearch为这些文档分配1.79E308的排序值。这个数字不是随机的--它确实是Double.MAX_VALUE,并且是ES在asc排序的情况下默认的值。
但是回到你的脚本排序,我不认为你可以很容易地访问prices.pricing_tables.price的doc-values而不使prices本身成为nested
您可以做的是:

  • 将基础_source作为HashMap访问
  • 迭代pricing_tables(如果适用)
  • 降回正常价格

下面是一个例子:

{
  "sort": [
    {
      "_script": {
        "type": "number",
        "script": {
          "lang": "painless",
          "params": {
            "table_id": 1
          },
          "source": """
            def regular = doc['prices.regular'].value;
            def raw_prices = params._source['prices']['pricing_tables'];
          
            if (raw_prices.length != 0) { 
              for (def pair : raw_prices) {
                if (pair['id'] == params.table_id) {
                  return pair['price'];
                }
              }
              return regular; 
            }
            
            return regular;
          """
        },
        "order": "asc"
      }
    }
  ]
}

请记住,与访问doc-values相比,访问_source会使排序性能下降。

相关问题