MongoDB基于BsonDocument实现嵌套字段条件过滤查询方法
MongoDB C# 驱动BsonDocument嵌套字段筛选实现
问题背景
现有类型为List<BsonDocument>的集合数据,示例内容如下:
{ "_id" : 123, "IDD" : 123, "Sc" : { "Field1" : null, "Field2" : "some text|some text|"} } { "_id" : 124, "IDD" : 124, "Sc" : { "Field1" : { "fl" : "something" }, "Field2" : ""} } { "_id" : 125, "IDD" : 125, "Sc" : { "Field1" : { }, "Field2" : null} }
数据通过以下基础查询语句获取:
var builder = Builders<BsonDocument>.Filter; var filter = builder.Gt("IDD", 122); var collection = database.GetCollection<BsonDocument>("coll").Find(filter).ToList();
要求不定义映射实体类,仅通过BsonDocument方式实现两个筛选需求:
- 需求1:等价SQL逻辑
SELECT * FROM coll WHERE Sc.Field2 != "" && Sc.Field2 != null,预期仅返回_id=123的文档 - 需求2:等价SQL逻辑
SELECT * FROM coll WHERE Sc.Field1 != {} && Sc.Field2 != null,预期仅返回_id=124的文档
此前尝试使用以下语句构造筛选条件未生效:
filter &= !builder.ElemMatch<BsonValue>("Sc", new BsonDocument { { "Field2", BsonNull.Value } })
实现方案
无效原因说明
ElemMatch方法仅用于数组类型字段的元素匹配,而Sc是嵌套对象类型,并非数组,因此该写法无法得到预期结果。嵌套字段直接通过点号路径访问即可完成筛选。
需求1代码实现
通过Ne(Not Equal)方法分别排除空字符串、null值,多条件通过逻辑与拼接:
var builder = Builders<BsonDocument>.Filter; var baseFilter = builder.Gt("IDD", 122); // 拼接Sc.Field2筛选条件:非空字符串、非null var field2Filter = builder.And( builder.Ne("Sc.Field2", ""), builder.Ne("Sc.Field2", BsonNull.Value) ); var finalFilter = baseFilter & field2Filter; var result = database.GetCollection<BsonDocument>("coll").Find(finalFilter).ToList();
补充说明:MongoDB中如果字段不存在,查询时会判定为等于
BsonNull.Value,上述写法会同时过滤掉Sc.Field2字段不存在的文档,和SQL的null判断逻辑一致。
需求2代码实现
空对象{}对应C#驱动中的空BsonDocument实例,直接通过Ne方法判断不等于空对象即可:
var builder = Builders<BsonDocument>.Filter; var baseFilter = builder.Gt("IDD", 122); // 拼接筛选条件:Sc.Field1非空对象、Sc.Field2非null var requirement2Filter = builder.And( builder.Ne("Sc.Field1", new BsonDocument()), builder.Ne("Sc.Field2", BsonNull.Value) ); var finalFilter = baseFilter & requirement2Filter; var result = database.GetCollection<BsonDocument>("coll").Find(finalFilter).ToList();
内容的提问来源于stack exchange,提问作者Common Work
相关产品推荐
相关产品推荐

