MongoDB querydsl:使用和运算符查询相同对象上的两个字段

时间:2018-01-10 07:41:43

标签: json spring mongodb querydsl

我有以下查询:

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对象,

我该怎么做?

1 个答案:

答案 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" } }