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

如何使用MongoDB聚合对层级地址数组分组统计各层级用户数

MongoDB 层级地址用户数统计实现方案

可以通过MongoDB聚合操作实现该需求,完整聚合管道如下:

db.user.aggregate([
  // 阶段1:生成每个用户所有层级的地址节点,记录完整路径、节点名、层级深度
  {
    $addFields: {
      levels: {
        $reduce: {
          input: "$location",
          initialValue: [],
          in: {
            $concatArrays: [
              "$$value",
              [
                {
                  path: { $concatArrays: [ "$$value.path", [ "$$this" ] ] },
                  name: "$$this",
                  depth: { $add: [ { $size: "$$value.path" }, 1 ] }
                }
              ]
            ]
          }
        }
      }
    }
  },
  // 阶段2:打散所有层级节点为独立文档
  { $unwind: "$levels" },
  // 阶段3:按地址完整路径分组,统计对应节点的用户数量
  {
    $group: {
      _id: "$levels.path",
      name: { $first: "$levels.name" },
      depth: { $first: "$levels.depth" },
      userCount: { $sum: 1 }
    }
  },
  // 阶段4:按层级深度升序排序,方便后续构建嵌套树结构
  { $sort: { depth: 1 } },
  // 阶段5:聚合所有节点,通过JS函数构建嵌套的层级树
  {
    $group: {
      _id: null,
      nodes: { $push: "$$ROOT" }
    }
  },
  {
    $project: {
      _id: 0,
      result: {
        $function: {
          body: function(nodes) {
            const nodeMap = {};
            const rootNodes = [];
            // 初始化所有节点的items字段,建立路径映射
            nodes.forEach(node => {
              nodeMap[node._id.join('|')] = { name: node.name, userCount: node.userCount, items: [] };
            });
            // 遍历节点挂载到对应父节点下
            nodes.forEach(node => {
              const currentPath = node._id;
              const currentNode = nodeMap[currentPath.join('|')];
              if (currentPath.length === 1) {
                rootNodes.push(currentNode);
                return;
              }
              const parentPath = currentPath.slice(0, -1);
              const parentNode = nodeMap[parentPath.join('|')];
              parentNode && parentNode.items.push(currentNode);
            });
            return rootNodes;
          },
          args: [ "$nodes" ],
          lang: "js"
        }
      }
    }
  },
  // 阶段6:格式化输出结构,和预期格式完全对齐
  { $unwind: "$result" },
  { $replaceRoot: { newRoot: "$result" } }
])

注意事项

  • 上述方案依赖MongoDB 4.4及以上版本的$function操作符支持
  • 如果你使用的MongoDB版本不支持$function,可以只运行前4个聚合阶段拿到扁平的各层级统计数据,把树结构构建逻辑迁移到应用层实现
  • 统计逻辑为只要用户地址包含对应层级节点就算入该节点用户数,和需求预期的统计结果完全匹配

内容的提问来源于stack exchange,提问作者Ramesh Kithsiri HettiArachchi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 11:30:02