我有以下查询:
BooleanExpression bex = qEntity.contacts.any().someField.eq(param1).and(qEntity.contacts.any().otherField.eq(param2));
但这对我的目的来说是错误的。我需要在同一个联系人对象上匹配someField和otherField。即使每个字段在不同的联系人对象上匹配,上面的查询也会返回true。
Entity
具有以下结构:
{
"contacts": [
{
"someField": "a",
"otherField": "b"
},
{
"someField": "c",
"otherField": "d"
}
]
}
我需要找到someField和otherField都匹配的contacts对象,
我该怎么做?
答案 0 :(得分:0)
使用Aggregation pipeline我们可以执行此操作,以下查询为我们提供了所需的结果。 Aggregation pipeline运营商使用$unwind,$project,$match
db.collection_name.aggregate([
{$unwind:"$contacts"},
{$project:{
contacts:1,
match:{"$eq":["$contacts.someField","$contacts.otherField"]}
}
},
{$match:{match:true}},
{$project:{_id:1, contacts:1}}
]);
示例文档
{
"_id" : ObjectId("5a55c7e1cf33f4a7eb8fafd0"),
"contacts" : [
{
"someField" : "a",
"otherField" : "b"
},
{
"someField" : "c",
"otherField" : "d"
}
]
}
{
"_id" : ObjectId("5a55c86dcf33f4a7eb8fafd1"),
"contacts" : [
{
"someField" : "a",
"otherField" : "a"
},
{
"someField" : "c",
"otherField" : "c"
}
]
}
在我们的案例中,
Contacts
是一系列文档,所以让我们来吧 $unwind个人文件。
展开样本文件后
{ "_id" : ObjectId("5a55c7e1cf33f4a7eb8fafd0"), "contacts" : { "someField" : "a", "otherField" : "b" } }
{ "_id" : ObjectId("5a55c7e1cf33f4a7eb8fafd0"), "contacts" : { "someField" : "c", "otherField" : "d" } }
{ "_id" : ObjectId("5a55c86dcf33f4a7eb8fafd1"), "contacts" : { "someField" : "a", "otherField" : "a" } }
{ "_id" : ObjectId("5a55c86dcf33f4a7eb8fafd1"), "contacts" : { "someField" : "c", "otherField" : "c" } }
使用$project我们可以为unwinded添加一个额外的属性 文档
match: true
,以识别具有的文档someField and otherField
为相同的值
执行项目后
{ "_id" : ObjectId("5a55c7e1cf33f4a7eb8fafd0"), "contacts" : { "someField" : "a", "otherField" : "b" }, "match" : false }
{ "_id" : ObjectId("5a55c7e1cf33f4a7eb8fafd0"), "contacts" : { "someField" : "c", "otherField" : "d" }, "match" : false }
{ "_id" : ObjectId("5a55c86dcf33f4a7eb8fafd1"), "contacts" : { "someField" : "a", "otherField" : "a" }, "match" : true }
{ "_id" : ObjectId("5a55c86dcf33f4a7eb8fafd1"), "contacts" : { "someField" : "c", "otherField" : "c" }, "match" : true }
使用$match我们可以过滤结果以仅显示匹配项 文件
执行匹配管道后
{ "_id" : ObjectId("5a55c86dcf33f4a7eb8fafd1"), "contacts" : { "someField" : "a", "otherField" : "a" }, "match" : true }
{ "_id" : ObjectId("5a55c86dcf33f4a7eb8fafd1"), "contacts" : { "someField" : "c", "otherField" : "c" }, "match" : true }
最后使用$project我们可以格式化输出(我们的最终结果有 到达$match阶段的输出,但它将有一个额外的 我们引入的名为match的属性)
最终结果
{ "_id" : ObjectId("5a55c86dcf33f4a7eb8fafd1"), "contacts" : { "someField" : "a", "otherField" : "a" } }
{ "_id" : ObjectId("5a55c86dcf33f4a7eb8fafd1"), "contacts" : { "someField" : "c", "otherField" : "c" } }