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

如何使用MongoDB C#驱动实现嵌套数组uid匹配指定字符串数组的in查询

MongoDB C# 驱动嵌套数组字段批量IN查询解决方案

问题背景

存储的文档对象结构如下:

public class Foo
{
    public string Id { get; set; }
    public List<FooBar> Bars { get; set; }
    
    // ...
}
    
public class FooBar
{
    public string uid { get; set; }
    
    // ...
}

现有查询条件数组:

var ArrayOfUid = new[] {"STK-00112","STK-00117","STK-00113","STK-00114"};

需求:查询所有满足嵌套对象FooBar.uid在ArrayOfUid范围内的文档,返回去重的产品列表。
已知MongoDB原生查询可正常执行:

db.collection.find({
    "foobar.uid": {
        $in: ["STK-00113","STK-00117","STK-00113","STK-00114"]
    }
})

目前单uid查询可正常运行:

var findFluent = collection.Find(Builders<Foo>.Filter.ElemMatch(
    foo => foo.Bars, 
    foobar => foobar.uid == "STK-00113"));

但使用BsonDocument构造的批量查询返回空结果:

public List<Produit> GetFromSitesAsync(List<string> productSites)
{
    // 运行无报错但返回空结果
    FilterDefinition<Produit> filter = new BsonDocument(
        "foobar.uid",
        new BsonDocument(
            "$in",
            BsonArray.Create(productSites)
        )
    );
    return _produits.Find(filter).ToList();
}

解决方案

推荐使用强类型Filter构造方式,避免手动写字段名导致的拼写错误、属性映射不匹配问题:

public List<Produit> GetFromSitesAsync(List<string> productSites)
{
    // 构造过滤条件:嵌套数组foobar中存在至少一个元素的uid在入参数组范围内
    var filter = Builders<Produit>.Filter.ElemMatch(
        product => product.foobar,
        foobar => productSites.Contains(foobar.uid)
    );

    // Find方法默认返回不重复的文档,不需要额外去重
    // 如果需要按业务字段(如uid)二次去重,可使用Distinct方法
    return _produits.Find(filter).ToList();
}

原有写法异常排查

如果要继续使用BsonDocument写法,可按以下两点排查:

  1. 确认字段映射关系:如果实体类中嵌套数组的属性名是Bars,但MongoDB中存储的字段名为foobar,需要给属性添加[BsonElement("foobar")]注解,或直接将BsonDocument中的字段名改为和实体类属性名一致。
  2. 确认入参格式:检查入参productSites的元素是否存在前后空格、大小写不匹配的情况,保证和数据库存储的uid格式完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 12:15:03