如何使用MongoDB C#驱动FilterDefinition实现多AND条件手机号查询
用MongoDB C#驱动的FilterDefinition实现数组多嵌套文档匹配查询
问题分析
你原有代码的核心问题是:直接对数组字段的嵌套属性做等值匹配,会匹配到不同数组元素分别满足条件的情况,而非同一个数组元素同时满足Type和Value的对应关系;同时,要确保文档同时包含指定的home和cell号码,需要分别约束每个号码的匹配逻辑。
正确实现代码
强类型写法(推荐)
利用Lambda表达式直接绑定实体类属性,类型更安全:
var filterBuilder = Builders<Applicant>.Filter; // 匹配数组中存在Type为home且Value为指定值的元素 var homePhoneFilter = filterBuilder.ElemMatch( applicant => applicant.PhoneNumbers, phone => phone.Type == "home" && phone.Value == "111-111-1111" ); // 匹配数组中存在Type为cell且Value为指定值的元素 var cellPhoneFilter = filterBuilder.ElemMatch( applicant => applicant.PhoneNumbers, phone => phone.Type == "cell" && phone.Value == "222-222-2222" ); // 组合两个条件,要求同时满足 var queryFilter = filterBuilder.And(homePhoneFilter, cellPhoneFilter);
字符串路径写法
如果需要使用字符串指定字段路径,可以这么写:
var filterBuilder = Builders<Applicant>.Filter; var phoneFilterBuilder = Builders<PhoneNumber>.Filter; var homePhoneFilter = filterBuilder.ElemMatch("PhoneNumbers", phoneFilterBuilder.And( phoneFilterBuilder.Eq("Type", "home"), phoneFilterBuilder.Eq("Value", "111-111-1111") ) ); var cellPhoneFilter = filterBuilder.ElemMatch("PhoneNumbers", phoneFilterBuilder.And( phoneFilterBuilder.Eq("Type", "cell"), phoneFilterBuilder.Eq("Value", "222-222-2222") ) ); var queryFilter = filterBuilder.And(homePhoneFilter, cellPhoneFilter);
生成的MongoDB查询语句
上述代码会生成正确的查询逻辑,对应原生MongoDB查询如下:
{ "$and": [ { "PhoneNumbers": { "$elemMatch": { "Type": "home", "Value": "111-111-1111" } } }, { "PhoneNumbers": { "$elemMatch": { "Type": "cell", "Value": "222-222-2222" } } } ] }
关于你期望的查询语句说明
你期望的写法存在语法错误:$elemMatch内部不能包含多个$and关键字。正确的逻辑是通过两个独立的$elemMatch,再用$and组合,确保数组中同时存在两个分别满足条件的元素。
原有代码的问题
你的原有代码生成的查询会忽略重复的字段键,且匹配逻辑是“数组中存在某元素Type为home、某元素Value为111-111-1111,同时存在某元素Type为cell、某元素Value为222-222-2222”,而非“存在home类型的指定号码和cell类型的指定号码这两个元素”,这会导致不符合预期的结果。
内容的提问来源于stack exchange,提问作者Hrishikesh Mehta
相关产品推荐
相关产品推荐

