Elasticsearch 中指定数组字段的统计查询记录
一、基本的数据结构说明
对应 ES 索引:sell_product_order
针对假设 ES 文档的基本结构内容如下:
{ "id": "2024041801000115936701", "sellingProducts": [ "FUND_20150718000230030000000000002549", "STOCK_656", "STOCK_4055", "STOCK_1720", "FUND_20180920000230030000000000015303" ] }
我们针对里面的 sellingProducts 字段进行一些基本的统计操作,本次记录一下相关的基本操作。
二、基本的统计记录
(一)统计当前索引中 sellingProducts 的所有类型
从 sell_product_order 索引中检索数据,然后根据 sellingProducts 字段中的内容,聚合出售产品的类型信息,并返回前 10 个最频繁出现的产品类型。
GET /sell_product_order/_search { "size": 0, "aggs": { "types": { "terms": { "script": { "source": """ HashSet types = new HashSet(); for (item in doc['sellingProducts']) { int delimiterIndex = item.indexOf('_'); if (delimiterIndex > -1) { types.add(item.substring(0, delimiterIndex)); } } return types; """, "lang": "painless" }, "size": 10 } } } }
(二)检索指定文档中 sellingProducts 的数据总量
从索引为 sell_product_order 中检索数据,并返回指定 _id 的文档,并在结果中包含一个名为 sellingProducts_count 的脚本字段,用于计算每个文档中 sellingProducts 字段的大小。
GET /sell_product_order/_search { "query": { "terms": { "_id": [ "2024041801000115936701" ] } }, "script_fields": { "sellingProducts_count": { "script": { "lang": "painless", "source": "doc['sellingProducts'].size()" } } } }
(三)检索指定文档中 sellingProducts 指定类型的数量统计
从 sell_product_order 索引中检索具有指定 _id 的文档,并在结果中返回两个计算字段,分别是 fund_count 和 stock_count,它们分别表示文档中以 'FUND_' 和 'STOCK_' 开头的元素的数量。
GET /sell_product_order/_search { "query": { "terms": { "_id": ["2024041801000115936701"] } }, "script_fields": { "fund_count": { "script": { "lang": "painless", "source": "int fundCount = 0; for (String item : doc['sellingProducts']) { if (item.startsWith('FUND_')) { fundCount++; } } return fundCount;" } }, "stock_count": { "script": { "lang": "painless", "source": "int stockCount = 0; for (String item : doc['sellingProducts']) { if (item.startsWith('STOCK_')) { stockCount++; } } return stockCount;" } } } }
(四)统计所有文档中 sellingProducts 中所有元素的总数
从 sell_product_order 索引中检索所有文档,并计算 sellingProducts 字段中所有元素的总数,将结果作为 total_sellingProducts_items 的值返回。
GET /sell_product_order/_search { "size": 0, "aggs": { "total_sellingProducts_items": { "sum": { "script": { "source": "doc['sellingProducts'].size()", "lang": "painless" } } } } }
(五)统计所有文档中 sellingProducts 中详细分类总数统计
计算 sellingProducts 字段中以 FUND_ 开头和以 STOCK_ 开头的元素数量,将结果以 fund_count 和 stock_count 的形式返回。
GET /sell_product_order/_search { "size": 0, "aggs": { "totals": { "scripted_metric": { "init_script": "state.fund_count = 0; state.stock_count = 0;", "map_script": """ if (doc.containsKey('sellingProducts')) { for (def item : doc['sellingProducts']) { if (item.startsWith('FUND_')) { state.fund_count++; } if (item.startsWith('STOCK_')) { state.stock_count++; } } } """, "combine_script": "return state", "reduce_script": """ def total_fund_count = 0; def total_stock_count = 0; for (state in states) { total_fund_count += state.fund_count; total_stock_count += state.stock_count; } return ['fund_count': total_fund_count, 'stock_count': total_stock_count]; """ } } } }
三、总结
在本文中,我们探讨了如何在 Elasticsearch 中对 sell_product_order 索引中的 sellingProducts 字段进行基本的统计操作。通过具体的查询示例,展示了多种数据检索和聚合的技巧,帮助从海量数据中提取出有价值的信息。
首先,介绍了数据结构的基本概念,明确了如何定位目标字段。随后,演示了几种不同的统计方法,包括计算产品类型的出现频率、检索指定文档中产品数量、以及对产品类型进行细分统计。这些操作不仅为数据分析提供了基础支持,也为业务决策提供了有力的数据依据。
通过这些示例,可以看到 Elasticsearch 的强大灵活性,以及它在处理复杂数据查询时的高效性。这些技巧适用于特定的业务场景,也为进一步的深入分析和数据挖掘奠定了基础。


