当前位置: 首页 > 知识库问答 >
问题:

ElasticSearch按嵌套文档之和筛选

荀增
2023-03-14
{
  "product": {
    "properties": {
      "warehouses": {
        "type": "nested",
        "properties": {
          "stock_level": {
            "type": "integer"
          }
        }
      }
    }
  }
}
{
  "id": 1,
  "warehouses": [
    {
      "id": 2001,
      "stock_level": 5
    },
    {
      "id": 2002,
      "stock_level": 0
    },
    {
      "id": 2003,
      "stock_level": 2
    }
  ]
}
GET products/_search
{
  "query": {
    "bool": {
      "filter": [
        [
          {
            "script": {
              "script": {
                "source": """
int total = 0;
for (def warehouse: params['_source']['warehouses']) {
  if (params.warehouse_ids == null || params.warehouse_ids.contains(warehouse.id)) {
    total += warehouse.stock_level;
  }
}
boolean gte = true;
boolean lte = true;
if (params.gte != null) {
  gte = (total >= params.gte);
}
if (params.lte != null) {
  lte = (total <= params.lte);
}
return (gte && lte);

""",
                "lang": "painless",
                "params": {
                  "gte": 4
                }
              }
            }
          }
        ]
      ]
    }
  }
}
    null

我也尝试使用scripted_field,但是脚本字段似乎是在最后一个阶段计算的,在查询过程中不可用。

我也有一个按照相同逻辑进行排序的方法(根据给定仓库中库存的总和对产品进行排序),它像一个魅力一样工作:

  "sort": {
    "warehouses.stock_level": {
      "order": "desc",
      "mode": "sum",
      "nested": {
        "path": "warehouses"
        "filter": {
           "terms": {
             "warehouses.id": [2001, 2003]
           }
        }
      }
    }
  }

但我也找不到访问此排序值的方法:(

共有1个答案

公羊伟志
2023-03-14

我最近也有同样的问题。事实证明,在重构过程中,更改发生在6.4左右的某个地方,虽然强烈不鼓励访问_source,但看起来人们仍然在使用/希望使用它。

这里有一个利用include_in_root参数的变通方法。

  1. 调整映射
PUT product
{
  "mappings": {
    "properties": {
      "warehouses": {
        "type": "nested",
        "include_in_root": true,     <--
        "properties": {
          "stock_level": {
            "type": "integer"
          }
        }
      }
    }
  }
}
GET product/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "script": {
            "script": {
              "source": """
                  int total = 0;
                  
                  def ids = doc['warehouses.id'];
                  def levels = doc['warehouses.stock_level'];
                  
                  for (def i = 0; i <  ids.length; i++) {
                    def warehouse = ['id':ids[i], 'stock_level':levels[i]];
                    
                    if (params.warehouse_ids == null || params.warehouse_ids.contains(warehouse.id)) {
                      total += warehouse.stock_level;
                    }
                  }
                  
                  boolean gte = true;
                  boolean lte = true;
                  if (params.gte != null) {
                    gte = (total >= params.gte);
                  }
                  if (params.lte != null) {
                    lte = (total <= params.lte);
                  }
                  return (gte && lte);
              """,
              "lang": "painless",
              "params": {
                  "gte": 4
              }
            }
          }
        }
      ]
    }
  }
}
 类似资料:
  • 在这里给ElasticSearch的初学者排名。 我有一个客户列表,他们的订单作为一个嵌套字段。假设文档结构如下: 我想查询的是:在两个日期之间订购了一定数量的用户列表。我希望能够将它与例如生日的范围查询结合起来。 我已经到了这样的地步,我可以使用聚合来获得每个订户在两个日期之间的排序总和: 但是,我想限制查询部分返回的结果,以便更好地与所有其他过滤器混合。 我的第一个想法是使用一个脚本过滤器,并

  • 问题内容: 我正在编写资产管理应用程序。它允许用户通过向资产添加html控件(例如文本字段,选择菜单等)来存储任意资产属性。然后,该属性的JSON表示成为存储在beddb中的资产JSON文档的一部分。资产在ouchdb中具有以下结构: 我不确定将属性放入数组是否是允许基于属性值搜索资产的最佳方法。将属性直接附加到资产作为属性会更好吗?我正在用Elasticsearch做实验。如果我尝试按原样存储文

  • 我是elasticsearch的新手,对如何进行过滤器、查询和聚合有一些想法,但不确定如何解决下面的问题。我希望能够从下面显示的文档中只查询公司的最新交付(日期和crate_quantity)。我不确定如何去做。有没有办法使用最大聚合从每个文档中只提取最近的交付?

  • 问题内容: 我正在尝试使用以下映射搜索文档: 我想在“ naam”,“ omschrijving”等中进行搜索,但也想在嵌套文档“ kenmerken”的动态映射中进行搜索,因此我创建了两个搜索查询,但它们似乎都不起作用。 我应该使用布尔还是过滤器?或两者结合? 我什至靠近吗? 问题答案: 由于需要解决方案,因此我决定创建一个单独的字符串字段,在其中分解“ kenmerken”字段。目前,此方法可

  • 我是Elasticsearch的新手,我试图创建一个过滤器来检索具有特定属性的文档。 属性在映射中定义为嵌套对象,如下所示: 我试图以以下形式执行一个复杂的查询: 这是elasticsearch 2.x。我做错了什么?

  • 我试图构造一个ElasticSearch查询,但没有得到预期的结果。任何帮助都将不胜感激! 映射详细信息: null null 目前,每个嵌套的轮班文档都包含一个嵌套的calendarBlock文档,其中包含开始和结束日期时间字段,以及一个可以注册该轮班的最大志愿者人数字段。 查询 我试图构造的查询是经过筛选的查询。从Web上的窗体传入查询字符串。然后,我需要以编程方式将至少三个筛选器附加到这个查