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

如何使用C#控制MongoDB的Projection实现字典字段键过滤

结论

该需求完全可实现,你最后尝试的Expression类型投影思路是正确的,报错是因为低版本MongoDB C#驱动暂不支持直接解析Dictionary键过滤的LINQ表达式,替换为兼容的投影写法即可。

正确实现方案

写法1:原生Bson操作投影(全版本兼容)

利用MongoDB的三个原生操作符实现字典过滤:

  • $objectToArray:将BSON对象(即你的Dictionary字段)转换为[{k:"键",v:"值"}]格式的数组
  • $filter:过滤数组中键满足前缀匹配要求的条目
  • $arrayToObject:将过滤后的数组转回BSON对象,映射回C#的Dictionary类型

代码如下:

// 定义投影
ProjectionDefinition<Thing> projection = new BsonDocument
{
    { nameof(Thing.Id), 1 },
    { nameof(Thing.Name), 1 },
    { nameof(Thing.Stuff), new BsonDocument("$arrayToObject", 
        new BsonDocument("$filter", new BsonDocument
        {
            { "input", new BsonDocument("$objectToArray", "$Stuff") },
            { "cond", new BsonDocument("$regexMatch", new BsonDocument
                {
                    { "input", "$$this.k" },
                    { "regex", "^duck" } // 匹配以duck开头的键
                })
            }
        })
    )}
};

// 查询调用
Thing result = await _dbContext.Things
    .Find(x => x.Name == name)
    .Project<Thing>(projection)
    .SingleOrDefaultAsync(token);

写法2:强类型LINQ表达式投影(驱动版本≥2.19支持)

如果你使用的MongoDB C#驱动版本在2.19及以上,调整你最后写的表达式即可直接运行:

ProjectionDefinition<Thing, Thing> projection = Builders<Thing>.Projection
    .Expression(a => new Thing
    {
        Id = a.Id,
        Name = a.Name,
        Stuff = a.Stuff
            .Where(kv => kv.Key.StartsWith("duck"))
            .ToDictionary(kv => kv.Key, kv => kv.Value)
    });

// 查询调用和上面一致
Thing result = await _dbContext.Things
    .Find(x => x.Name == name)
    .Project<Thing>(projection)
    .SingleOrDefaultAsync(token);

可参考的搜索关键词

  • MongoDB C#驱动 条件投影 Dictionary过滤
  • MongoDB $objectToArray $filter 嵌套对象过滤
  • MongoDB 投影 过滤对象键

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 01:06:05