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

如何使用C# MongoDB Driver根据传入数组过滤子文档列表?

MongoDB C#驱动过滤嵌套数组元素问题

模型结构

public class Box
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string? Id { get; set; }

    [BsonElement("relatedJobs")]
    public List<BoxJobs> RelatedJobs { get; init; } = default!;

    //更多属性

    public class BoxJobs
    {
        [BsonElement("partnerId")]
        public string PartnerId { get; init; } = null!;
        
        //更多属性
    }
}

需求

根据传入的partnerIds数组过滤所有Box文档,需满足:Box至少包含一个relatedJob,且该relatedJob的partnerId存在于传入的数组中。

尝试的代码及错误

尝试使用以下代码实现过滤:

var builder = Builders<Box>.Filter;
var filter = new FilterDefinitionBuilder<Box>().Empty;
filter &= !partnerIds.Any()
        ? new FilterDefinitionBuilder<Box>().Empty
        : builder.AnyIn(box => box.RelatedJobs.Select(relatedJob => relatedJob.PartnerId), partnerIds);
var cursor = Collection.Find(filter);

运行后出现错误:

Unable to determine the serialization information for box => box.RelatedJobs.Select(relatedJob => relatedJob.PartnerId).

解决方案

MongoDB C#驱动无法解析LINQ的Select表达式来映射到BSON的嵌套数组字段路径,需要直接针对嵌套数组的属性构建过滤条件,有两种可行方式:

方式一:使用AnyIn指定数组元素属性

利用驱动的特殊语法[-1]表示数组中的任意元素,直接指向relatedJobs数组内元素的PartnerId字段:

var builder = Builders<Box>.Filter;
FilterDefinition<Box> filter;

if (!partnerIds.Any())
{
    filter = builder.Empty; // partnerIds为空时返回所有文档,或按需改为builder.Where(b => b.RelatedJobs.Any())
}
else
{
    // 匹配relatedJobs数组中存在任意元素的PartnerId在partnerIds中
    filter = builder.AnyIn(box => box.RelatedJobs[-1].PartnerId, partnerIds);
}

var cursor = Collection.Find(filter);

方式二:使用ElemMatch结合In

通过ElemMatch筛选数组中符合条件的元素,效果和方式一一致:

var builder = Builders<Box>.Filter;
FilterDefinition<Box> filter;

if (!partnerIds.Any())
{
    filter = builder.Empty;
}
else
{
    filter = builder.ElemMatch(box => box.RelatedJobs, job => job.PartnerId.In(partnerIds));
}

var cursor = Collection.Find(filter);

说明

  • 两种方式都能正确映射到MongoDB的查询语法,驱动会将其转换为对应的BSON查询条件。
  • 如果需要额外确保RelatedJobs数组不为空(即使partnerIds为空时也过滤掉无关联Job的Box),可以在partnerIds为空时将filter改为builder.Where(b => b.RelatedJobs.Any())。

内容的提问来源于stack exchange,提问作者cs.kali

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 14:06:55