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

C#操作MongoDB如何查询嵌套数组与指定ID集合存在交集的文档

实现前提

首先确认你已定义对应数据模型,示例参考如下:

// 根文档模型,对应MongoDB集合存储结构
public class RootDocument
{
    public ObjectId Id { get; set; }
    public List<ObjectItem> objects { get; set; }
}

public class ObjectItem
{
    public int id { get; set; }
    public List<TrackingData> tracking_datas { get; set; }
}

public class TrackingData
{
    public int id { get; set; }
    public List<int> polygons { get; set; }
}

实现代码(C# MongoDB 驱动)

这里提供两种可直接使用的写法,适配不同驱动版本:

写法1:强类型表达式写法(推荐,驱动v2.14+支持)

// 注入/获取MongoDB集合实例
var mongoCollection = mongoDatabase.GetCollection<RootDocument>("你的集合名");
// 你的参考条件数组
var requiredPolygons = new List<int> { 1, 2 };

// 1. 匹配条件:筛选出至少有一个符合要求的tracking_datas的文档
var matchFilter = Builders<RootDocument>.Filter
    .ElemMatch(root => root.objects,
        obj => obj.tracking_datas.Any(td => td.polygons.Any(p => requiredPolygons.Contains(p))));

// 2. 投影过滤:仅保留tracking_datas中符合条件的子项
var projection = Builders<RootDocument>.Projection.Expression(root => new RootDocument
{
    Id = root.Id,
    objects = root.objects.Select(obj => new ObjectItem
    {
        id = obj.id,
        // 过滤不符合条件的tracking_datas子项
        tracking_datas = obj.tracking_datas
            .Where(td => td.polygons.Intersect(requiredPolygons).Any())
            .ToList()
    })
    // 如果需要过滤掉tracking_datas为空的object,可打开下面的注释
    // .Where(obj => obj.tracking_datas.Any())
    .ToList()
});

// 执行查询
var result = await mongoCollection.Find(matchFilter)
    .Project(projection)
    .ToListAsync();

写法2:Bson原生聚合写法(兼容所有驱动版本)

如果旧版本驱动无法解析Linq表达式,用原生聚合管道实现:

var mongoCollection = mongoDatabase.GetCollection<RootDocument>("你的集合名");
var requiredPolygons = new List<int> { 1, 2 };
var requiredBsonArray = new BsonArray(requiredPolygons);

var pipeline = new BsonDocumentStagePipelineDefinition<RootDocument, RootDocument>(
    new List<BsonDocument>
    {
        // 匹配阶段
        new BsonDocument("$match", new BsonDocument
        {
            { "objects.tracking_datas.polygons", new BsonDocument("$in", requiredBsonArray) }
        }),
        // 投影过滤阶段
        new BsonDocument("$project", new BsonDocument
        {
            { "_id", 1 },
            { "objects", new BsonDocument("$map", new BsonDocument
                {
                    { "input", "$objects" },
                    { "as", "obj" },
                    { "in", new BsonDocument
                        {
                            { "id", "$$obj.id" },
                            { "tracking_datas", new BsonDocument("$filter", new BsonDocument
                                {
                                    { "input", "$$obj.tracking_datas" },
                                    { "as", "td" },
                                    // 判断两个数组是否有交集
                                    { "cond", new BsonDocument("$gt", new BsonArray
                                        {
                                            new BsonDocument("$size", 
                                                new BsonDocument("$setIntersection", 
                                                    new BsonArray { "$$td.polygons", requiredBsonArray })),
                                            0
                                        })
                                    }
                                })
                            }
                        }
                    }
                })
            }
        })
    });

var result = await mongoCollection.Aggregate(pipeline).ToListAsync();

优化提示

  • 建议给objects.tracking_datas.polygons字段添加索引,大幅提升大数量级下的查询效率
  • 如果你的集合直接存储ObjectItem列表(最外层没有objects数组),只需去掉代码中对应objects层级的操作即可

内容的提问来源于stack exchange,提问作者Mehmet Serkan Ekinci

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 09:09:02