我有一个名为“Applicants”的 MongoDB 集合,其中包含有关申请人信息的文档,包括他们的姓氏、类型以及一系列不同类型的电话号码,例如“家庭”、“手机”和“办公室”。
以下是“申请人”文档的 JSON 表示示例:
{
"_id": ObjectId("61791ecf2abf206fd5e5e322"),
"LastName": "Smith",
"Type": "P",
"PhoneNumbers": [
{ "Type": "home", "Value": "111-111-1111" },
{ "Type": "cell", "Value": "222-222-2222" },
{ "Type": "office", "Value": "333-333-3333" }
]
}
现在,我需要执行查询来查找具有特定电话号码的申请人,例如“家庭”和“手机”电话号码。我正在使用 MongoDB C# 驱动程序并希望使用
FilterDefinition
。
我尝试过在多个条件下使用
ElemMatch
方法,但它似乎没有按预期工作。这是我目前的尝试:
var filterBuilder = Builders<Applicant>.Filter;
var homePhoneFilter = filterBuilder.Eq("PhoneNumbers.Type", "home") & filterBuilder.Eq("PhoneNumbers.Value", "111-111-1111");
var cellPhoneFilter = filterBuilder.Eq("PhoneNumbers.Type", "cell") & filterBuilder.Eq("PhoneNumbers.Value", "222-222-2222");
var queryFilter = homePhoneFilter & cellPhoneFilter;
不幸的是,这不会返回任何结果,我怀疑使用
homePhoneFilter
组合 cellPhoneFilter
和 &
可能不是正确的方法。
渲染查询:
以下是预期的渲染查询:
{
"PhoneNumbers": {
"$elemMatch": { "$and": [ { "Type": "home" }, { "Value": "111-111-1111" } ], "$and": [ { "Type": "cell" }, { "Value": "222-222-2222" } ] }
}
}
任何有关如何在 C# 中使用
FilterDefinition
为我的 MongoDB 查询正确实现多个 AND 条件的指导,我们将不胜感激。
预先感谢您的帮助!
同意@user20042973的评论,您的查询不正确。应该是:
解决方案1
db.collection.find({
$and: [
{
PhoneNumbers: {
"$elemMatch": {
"Type": "home",
"Value": "111-111-1111"
}
}
},
{
PhoneNumbers: {
"$elemMatch": {
"Type": "cell",
"Value": "222-222-2222"
}
}
}
]
})
对于 MongoDB .NET 语法:
var filterBuilder = Builders<Applicant>.Filter;
var homePhoneFilter = filterBuilder.ElemMatch(
x => x.PhoneNumbers,
y => y.Type == "home" && y.Value == "111-111-1111");
var cellPhoneFilter = filterBuilder.ElemMatch(
x => x.PhoneNumbers,
y => y.Type == "cell" && y.Value == "222-222-2222");
var queryFilter = homePhoneFilter & cellPhoneFilter;
解决方案 2:使用 $all 运算符
运算符选择字段值为包含所有指定元素的数组的文档。$all
db.collection.find({
PhoneNumbers: {
$all: [
{
$elemMatch: {
"Type": "home",
"Value": "111-111-1111"
}
},
{
$elemMatch: {
"Type": "cell",
"Value": "222-222-2222"
}
}
]
}
})
对于 MongoDB .NET 语法:
var filterBuilder = Builders<Applicant>.Filter;
var queryFilter = filterBuilder.All(x => x.PhoneNumbers, new List<PhoneNumber>
{
new PhoneNumber { Type = "home", Value = "111-111-1111" },
new PhoneNumber { Type = "cell", Value = "222-222-2222" }
});