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

如何在C# MongoDB聚合查询中获取最小值对应的Timestamp?

获取MongoDB集合最小值及对应Timestamp的C#聚合方案

我来帮你搞定这个需求!既然你已经能成功获取集合的最小值,现在要加上对应的Timestamp字段,其实核心就是找到那个拥有最小值的文档,再提取它的时间戳就行。下面分两种常见场景给你具体的实现方案:

场景1:全局获取最小值及对应Timestamp(无分组)

这种情况最简单,直接按目标数值字段升序排序,然后取第一条文档,就能同时拿到最小值和对应的Timestamp。代码示例如下(假设你的实体类是Reading,包含Value(数值字段)和Timestamp(时间戳字段)):

// 假设你的集合对象是IMongoCollection<Reading> collection
var minWithTimestamp = collection.Aggregate()
    // 按Value升序排序,最小值会排在最前面
    .Sort(Builders<Reading>.Sort.Ascending(r => r.Value))
    // 只取第一条数据
    .Limit(1)
    // 投影出需要的字段
    .Project(r => new 
    {
        MinValue = r.Value,
        CorrespondingTimestamp = r.Timestamp
    })
    .FirstOrDefault();

这种方式代码简洁,而且如果给Value字段建了索引,排序性能会非常好。

场景2:分组获取每组的最小值及对应Timestamp

如果需要按某个字段(比如设备ID DeviceId)分组,然后获取每组的最小值和对应时间戳,就需要在聚合管道里先分组保存相关数据,再通过投影匹配出对应时间戳。这里给你两种实现方式:

方式1:用$push+$indexOfArray+$arrayElemAt

var groupedResult = collection.Aggregate()
    .Group(new BsonDocument
    {
        { "_id", "$DeviceId" }, // 按DeviceId分组
        { "minValue", new BsonDocument("$min", "$Value") }, // 计算每组最小值
        // 把每组的Value和Timestamp存入数组
        { "docs", new BsonDocument("$push", new BsonDocument 
            { 
                { "value", "$Value" }, 
                { "timestamp", "$Timestamp" } 
            }) }
    })
    .Project(new BsonDocument
    {
        { "_id", 1 }, // 保留分组ID
        { "minValue", 1 }, // 保留最小值
        // 通过最小值找到对应数组索引,再取出对应的Timestamp
        { "correspondingTimestamp", new BsonDocument("$arrayElemAt", new BsonArray 
            { 
                "$docs.timestamp", 
                new BsonDocument("$indexOfArray", new BsonArray { "$docs.value", "$minValue" }) 
            }) }
    })
    .ToList();

方式2:用$push+$filter+$first(更直观)

这种方式先把每组的完整文档存入数组,再过滤出等于最小值的文档,最后取第一个的Timestamp:

var groupedResult = collection.Aggregate()
    .Group(new BsonDocument
    {
        { "_id", "$DeviceId" },
        { "minValue", new BsonDocument("$min", "$Value") },
        { "allDocs", new BsonDocument("$push", "$$ROOT") } // 存入每组的完整文档
    })
    .Project(new BsonDocument
    {
        { "_id", 1 },
        { "minValue", 1 },
        // 过滤出Value等于最小值的文档,取第一个的Timestamp
        { "correspondingTimestamp", new BsonDocument("$first", 
            new BsonDocument("$filter", new BsonDocument
            {
                { "input", "$allDocs" },
                { "cond", new BsonDocument("$eq", new BsonArray { "$$this.Value", "$minValue" }) }
            })["Timestamp"]) }
    })
    .ToList();

注意点

  • 如果同一组内有多个文档拥有相同的最小值,上面两种方式都会返回第一个匹配到的文档的Timestamp;如果需要所有匹配的时间戳,去掉$first直接返回过滤后的数组即可。
  • 数据量较大时,给分组字段和Value字段建立复合索引,能大幅提升聚合性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:31:29