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

基于Elasticsearch嵌套对象的过滤和计数操作

锺超英
2023-03-14
"first_name" => [
 "type" => "text"
],
"last_name" => [
    "type"=> "text"
],
"email" => [
    "type"=> "text"
],
"total_spent" => [
    "type"=> "text"
],
"aov" => [
    "type"=> "float"
],
"orders_count" => [
    "type"=> "integer"
],
"orders" => [
    "type" => "nested",
    "properties" => [
        "order_id" => [
            "type"=>"text"
        ],
        "total_price" => [
            "type"=>"float"
        ]
    ]
]
    [
   {
      "_index":"customers_index",
      "_type":"_doc",
      "_id":"1",
      "_score":1,
      "_source":{
         "first_name":"Stephen",
         "last_name":"Long",
         "email":"egnition_sample_91@egnition.com",
         "total_spent":"0.00",
         "aov":0,
         "orders":[]
      }
   },
   {
      "_index":"customers_index",
      "_type":"_doc",
      "_id":"2",
      "_score":1,
      "_source":{
         "first_name":"Reece",
         "last_name":"Dixon",
         "email":"egnition_sample_57@egnition.com",
         "total_spent":"0.10",
         "aov":"0.1",
         "orders":[
            {
               "total_price":"0.10",
               "placed_at":"2020-09-24T20:08:35.000000Z",
               "order_id":2723671867546
            }
         ]
      }
   },
   {
      "_index":"customers_index",
      "_type":"_doc",
      "_id":"3",
      "_score":1,
      "_source":{
         "first_name":"John",
         "last_name":"Marshall",
         "email":"egnition_sample_94@egnition.com",
         "total_spent":"0.10",
         "aov":"0.04",
         "orders":[
            {
               "total_price":"0.10",
               "placed_at":"2020-09-24T20:10:52.000000Z",
               "order_id":2723675930778
            },
            {
               "total_price":"0.30",
               "placed_at":"2020-09-24T20:09:45.000000Z",
               "order_id":2723673899162
            },
            {
               "total_price":"0.10",
               "placed_at":"2020-09-16T09:55:22.000000Z",
               "order_id":2704717414554
            }
         ]
      }
   }
]

感谢您的回复

编辑:

我试图计数对象之间指定日期范围内的筛选器内的嵌套对象。在ElasticSearch上这样做可能吗?简单地说,我想查看,客户谁有1个订单或多个订单取决于输入在一个指定的日期。

我知道如何获得客户的每日计数,但如果我想计数在指定日期范围内有1个订单的客户在一组每日报表中怎么办?

我所期望的可能的回应:

{
...
"aggregations":[
{
"date":"2020-09-01",
"total_customers_zero_purchased":15
}
...
]
}

共有1个答案

姚俊材
2023-03-14

这里有一大堆问题,所以我将集中讨论最重要的部分。

首先,通常将某些文本字段设置为.keyword类型,这样我们以后就可以对它们进行聚合。这意味着:

PUT customers_index
{
  "mappings": {
    "properties": {
      "email": {
        "type": "keyword"    <--
      }
    }
  }
}

之后,我们可以继续查询,但必须注意,当我们迭代日期范围时,我们需要指定一个日期字段。含义:

    null

实际上,我们不能得到每天的滚动聚合(因为我们不知道我们不知道什么),而只能得到一个单日度量。例如

GET customers_index/_search
{
  "size": 0,
  "aggs": {
    "multibucket_simulator": {
      "filters": {
        "filters": {
          "all": {
            "match_all": {}
          }
        }
      },
      "aggs": {
        "all_customers": {
          "cardinality": {
            "field": "email"
          }
        },
        "customers_who_purchased_at_date": {
          "filter": {
            "nested": {
              "path": "orders",
              "query": {
                "range": {
                  "orders.placed_at": {
                    "gte": "2020-09-16T00:00:00.000000Z",
                    "lt": "2020-09-26T00:00:00.000000Z"
                  }
                }
              }
            }
          },
          "aggs": {
            "customer_count": {
              "cardinality": {
                "field": "email"
              }
            }
          }
        },
        "total_customers_zero_purchased": {
          "bucket_script": {
            "buckets_path": {
              "all": "all_customers.value",
              "filtered": "customers_who_purchased_at_date>customer_count.value"
            },
            "script": "params.all - params.filtered"
          }
        }
      }
    }
  }
}

屈服

"aggregations" : {
  "multibucket_simulator" : {
    ...
    "buckets" : {
      "all" : {
        ...
        "customers_who_purchased_at_date" : {
          ...
        },
        "all_customers" : {
          ...
        },
        "total_customers_zero_purchased" : {       <---
          "value" : 1.0
        }
      }
    }
  }
}

从而回答了这个问题:

 类似资料:
  • 我有多个嵌套文档doc。嵌套查询工作正常,但它们仍然会返回所有嵌套对象(即整个文档),即使搜索查询只匹配少数嵌套对象。但是,它确实将文档作为一个整体进行过滤。 下面是一个例子: 当在地址中搜索时,理想情况下,我应该只获得带有一个嵌套对象的,但我会获得所有嵌套对象。如何筛选返回的嵌套对象? 示例查询: 该查询的输出是和所有员工,而我只想要。

  • 问题内容: 我正在尝试基于一些嵌套对象来过滤数组。 输入数组如下所示: 我希望这种情况的输出如下所示: 我正在使用此公式来做到这一点: 输出几乎是好的,但它返回的对象带有所有带有姓氏的对象(最好检查一下小提琴:D),而不是将其删除。我如何改善过滤? 问题答案: 调用之后,您需要将结果通过管道传递到,如下所示: 我在这里假设您不想操纵原始数组。因此,我正在使用Object.assign。

  • 问题内容: 我有带有嵌套字段的文档,如下所示: 嵌套字段的映射如下所示: 在切换到elasticsearch 2之前,我有一个带有aggs的查询,该查询计算了没有结果的文档。这是查询的聚合部分: 现在我切换到elasticserach 2,它只计算所有文档。我已经尝试过其他操作,例如计算所有文档和计算结果,以便可以减去结果,但是 总是0 如何正确过滤/计数嵌套字段? 问题答案: 如果您要计算产生结

  • 问题内容: 我有这样的角度嵌套对象。有没有办法为嵌套属性过滤它 我只显示父元素,但想按两个元素进行过滤,例如: 问题答案: 是的,如果我正确理解您的示例,则可以。 根据集合的大小,计算迭代所用的集合可能会更好,这样过滤器就不会随着模型的更改而不断地进行操作。 http://jsfiddle.net/suCWn/ 基本上,如果我理解正确,您会执行以下操作:

  • 我有一个映射: 我使用三个条件进行筛选: “日志类型”是“爬虫” “2020-05-23”上的“创建数据” “resp”的大小=0 我试图过滤与查询: {"查询":{"bool":{"必须":[{"术语":{"_logType":{"value":"爬虫"}}},{"范围":{"_createdAt":{"gte":"2020-05-23","lte":"2020-05-23","time_zon

  • 问题内容: 我有以下ES内容,基本上是网站中包含嵌套商品的产品列表。 如何按站点详细信息的数量排序? tnx! 问题答案: 从问题的示例来看,它看起来像是单个文档,但是单个json文档不可能在同一级别具有相同名称的多个字段。 因此,假设每个字段代表一个不同的顶级文档