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

如何用IMongoCollection统计数组字段中不同值的出现次数?

数组分类字段的出现次数统计方案验证

需求说明

我有一个MongoDB文档集合,每个文档包含数组类型字段categories,示例如下:

  • doc1.categories = [sport, cinema, etc]
  • doc2.categories = [gaming, sport, etc]

需要基于IMongoCollection实现方法,返回各分类的出现次数,格式示例:
sport:2
cinema:1
gaming:1
...

现有代码方案验证

我找到了如下代码,请问这是否是合适的解决方案?

_collection.AsQueryable()
    .SelectMany(s => s.Categories)
    .GroupBy(s => s)
    .Select(g => new { Category = g.Key, Total = g.Count() })
    .ToList();

方案分析

这个方案完全可行,核心逻辑清晰:

  1. AsQueryable()将IMongoCollection转为支持LINQ查询的对象
  2. SelectMany把所有文档的categories数组扁平化,拆成单个分类项的集合
  3. GroupBy按分类名称分组,最后统计每组的元素数量得到出现次数

适用场景与注意事项

  • 中小数据量场景下,这个方案代码简洁易读,维护成本低,完全够用
  • 如果你的集合数据量极大(百万级以上),要注意:新版MongoDB驱动会将这套LINQ逻辑转化为服务器端的聚合操作($unwind + $group),但老版本驱动可能会把全量数据拉到客户端再处理,这时候性能会很差。这种情况下推荐用原生Mongo聚合管道实现,直接在服务器端完成统计:
var pipeline = new BsonDocument[]
{
    // 拆分categories数组为单个文档
    new BsonDocument("$unwind", "$categories"),
    // 按分类分组统计次数
    new BsonDocument("$group", new BsonDocument
    {
        { "_id", "$categories" },
        { "Total", new BsonDocument("$sum", 1) }
    }),
    // 调整输出格式
    new BsonDocument("$project", new BsonDocument
    {
        { "Category", "$_id" },
        { "Total", 1 },
        { "_id", 0 }
    })
};

var result = _collection.Aggregate<dynamic>(pipeline).ToList();

结论

你的代码在绝大多数业务场景下都是合适的解决方案;如果需要处理超大规模数据集,优先选择原生聚合管道以获得更好的性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 21:20:28