You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elasticsearch 7.13.2 如何实现多字段组合的cardinality去重计数

Elasticsearch 多字段组合去重计数方案

问题背景

当前使用Elasticsearch 7.13.2版本,索引名为r2332,需要统计maid和date两个字段组合的唯一去重计数,原有两种实现方案均存在错误无法得到正确结果。

原有方案错误原因

  • 运行时字段方案错误:
    • 自定义的运行时字段名为type_and_promoted,但cardinality聚合中错误填写字段值为runtime_mappings,没有指向正确的运行时字段
    • 多余添加了reverse_nested聚合,无嵌套文档场景下不需要该配置
  • 脚本直接聚合方案错误:
    • 脚本语法错误:doc'date'].value缺失左方括号,正确写法为doc['date'].value
    • date字段为date类型,直接拼接需要先转为字符串格式,避免类型不兼容报错

正确实现方案

方案1:修正后的运行时字段方案

{
    "size": 0,
    "query": {
        "bool": {
            "filter": [
                {
                    "terms": {
                        "site_id": [7560, 7566]
                    }
                },
                {
                    "range": {
                        "date": {
                            "gte": "2021-09-01",
                            "lte": "2021-09-15"
                        }
                    }
                }
            ]
        }
    },
    "runtime_mappings": {
        "maid_date_combine": {
            "type": "keyword",
            "script": """
                // 先判断字段非空,避免空指针报错
                if(doc['maid'].size()!=0 && doc['date'].size()!=0){
                    emit(doc['maid'].value + '#' + doc['date'].value.toString())
                }
            """
        }
    },
    "aggs": {
        "group_by": {
            "terms": {
                "field": "site_id",
                "size": 100
            },
            "aggs": {
                "bydate": {
                    "terms": {
                        "field": "date",
                        "size": 100
                    },
                    "aggs": {
                        "byhour": {
                            "terms": {
                                "field": "hour",
                                "size": 24
                            },
                            "aggs": {
                                "uv": {
                                    "cardinality": {
                                        "field": "maid_date_combine"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

方案2:修正后的cardinality直接使用脚本方案

{
    "size": 0,
    "query": {
        "bool": {
            "filter": [
                {
                    "terms": {
                        "site_id": [7560, 7566]
                    }
                },
                {
                    "range": {
                        "date": {
                            "gte": "2021-09-01",
                            "lte": "2021-09-15"
                        }
                    }
                }
            ]
        }
    },
    "aggs": {
        "group_by": {
            "terms": {
                "field": "site_id",
                "size": 100
            },
            "aggs": {
                "bydate": {
                    "terms": {
                        "field": "date",
                        "size": 100
                    },
                    "aggs": {
                        "byhour": {
                            "terms": {
                                "field": "hour",
                                "size": 24
                            },
                            "aggs": {
                                "uv": {
                                    "cardinality": {
                                        "script": {
                                            "source": """
                                                if(doc['maid'].size()!=0 && doc['date'].size()!=0){
                                                    return doc['maid'].value + '#' + doc['date'].value.toString();
                                                }
                                                return "";
                                            """
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

注意事项

  • 如果对去重计数的精度要求极高,可以调整cardinality聚合的precision_threshold参数,最高可设置为40000,低于该阈值的去重计数误差接近0
  • 如果该统计是高频查询,建议在数据写入时提前拼接好maid和date的组合字段存入索引,查询性能远高于运行时计算和脚本计算

内容的提问来源于stack exchange,提问作者Apricot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 15:39:02