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

C#环境下MongoDB嵌套数组过滤实现方法咨询

在C#中过滤MongoDB嵌套数组的实现方案

需求背景

现有MongoDB文档结构如下:

[
    {
        "Number": "2140007529",
        "Name": "ABC",
        "IsInactive": true,
        "EntryList": [
            {
                "Timestamp": "2022-06-01T14:00:00.000+00:00",
                "Value": 21564.0
            }
            // 其余条目省略
        ]
    },
    {
        "Number": "2220000784",
        "Name": "XYZ",
        "IsInactive": false,
        "EntryList": [
            {
                "Timestamp": "2022-09-26T13:00:00.000+00:00",
                "Value": 0.0
            },
            {
                "Timestamp": "2023-01-01T11:54:00.000+00:00",
                "Value": 528.56
            }
            // 其余条目省略
        ]
    }
]

需要实现两个筛选逻辑:

  1. 仅保留IsInactive为false的文档
  2. 对符合条件的文档,仅返回EntryList中Timestamp大于2022-12-31的条目

实现步骤

1. 定义C#实体模型

先对应MongoDB文档结构创建强类型模型:

public class Entry
{
    public DateTime Timestamp { get; set; }
    public double Value { get; set; }
}

public class Device
{
    public string Number { get; set; }
    public string Name { get; set; }
    public bool IsInactive { get; set; }
    public List<Entry> EntryList { get; set; }
}

2. 聚合管道实现(贴近MongoDB原生语法)

这种方式和你在MongoDB Compass中使用的聚合逻辑完全对应:

using MongoDB.Driver;
using MongoDB.Bson;
using System;
using System.Threading.Tasks;

// 初始化Mongo客户端和集合
var mongoClient = new MongoClient("mongodb://localhost:27017");
var db = mongoClient.GetDatabase("你的数据库名");
var collection = db.GetCollection<Device>("你的集合名");

// 定义时间阈值(使用UTC时间,和文档中的Timestamp格式匹配)
var cutoffDate = new DateTime(2023, 1, 1, 0, 0, 0, DateTimeKind.Utc);

// 构建聚合管道
var pipeline = new BsonDocument[]
{
    // 第一步:匹配IsInactive为false的文档
    new BsonDocument("$match", new BsonDocument("IsInactive", false)),
    // 第二步:过滤EntryList数组,保留符合时间条件的元素
    new BsonDocument("$addFields", new BsonDocument(
        "EntryList", new BsonDocument("$filter", new BsonDocument
        {
            { "input", "$EntryList" },
            { "cond", new BsonDocument("$gt", new BsonArray { "$$this.Timestamp", cutoffDate }) }
        })
    ))
};

// 执行聚合查询
var result = await collection.Aggregate<Device>(pipeline).FirstOrDefaultAsync();

3. LINQ方式实现(更符合C#习惯)

如果偏好LINQ语法,可以用更直观的写法:

using MongoDB.Driver;
using System;
using System.Threading.Tasks;

// 初始化客户端和集合(同上)
var mongoClient = new MongoClient("mongodb://localhost:27017");
var db = mongoClient.GetDatabase("你的数据库名");
var collection = db.GetCollection<Device>("你的集合名");

var cutoffDate = new DateTime(2023, 1, 1, 0, 0, 0, DateTimeKind.Utc);

// 用LINQ构建查询
var result = await collection.Aggregate()
    .Match(device => !device.IsInactive)
    .Project(device => new Device
    {
        Number = device.Number,
        Name = device.Name,
        IsInactive = device.IsInactive,
        EntryList = device.EntryList.Where(entry => entry.Timestamp > cutoffDate).ToList()
    })
    .FirstOrDefaultAsync();

注意事项

  • 确保时间类型的一致性:文档中的Timestamp是UTC格式,C#中必须使用DateTimeKind.Utc的时间实例,避免时区差异导致过滤结果错误。
  • 如果需要排除过滤后EntryList为空的文档,可以在聚合管道中添加额外的$match阶段:
    new BsonDocument("$match", new BsonDocument("EntryList", new BsonDocument("$ne", new BsonArray())))
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 17:05:21