MongoDB Query匹配单个条目和数组元素

时间:2016-09-27 13:09:35

标签: java json mongodb query-builder

我遇到MongoDB QueryBuilder的问题。

假设我有许多文档,可以包含一个或多个用户:

{
  "_id": "document1",
  "data": {
    "user": {
      "credentials": {
        "name": "John",
        "lastname": "Watson",
        "middle": "Hemish"
      }
    }
  }
}


{
  "_id": "document2",
  "data": {
    "user": [
      {
        "credentials": {
          "name": "John",
          "lastname": "Nicholson",
          "middle": "Joseph"
        }
      },
      {
        "credentials": {
          "name": "Mary",
          "lastname": "Watson",
          "middle": ""
        }
      }
    ]
  }
}


{
  "_id": "document3",
  "data": {
    "user": [
      {
        "credentials": {
          "name": "John",
          "lastname": "Watson",
          "middle": "Hemish"
        }
      },
      {
        "credentials": {
          "name": "John",
          "lastname": "Nicholson",
          "middle": "Joseph"
        }
      },
      {
        "credentials": {
          "name": "Mary",
          "lastname": "Watson",
          "middle": ""
        }
      }
    ]
  }
}

我要做的是查询,它只会返回包含John Watson作为用户的文档。

这是我到目前为止所得到的:

1

QueryBuilder qb = QueryBuilder.start("credentials.lastname").is("Watson").and("credentials.name").is("John");
DBObject query = QueryBuilder.start("data.user").elemMatch(qb.get()).get();

此查询将仅返回document3:document1中没有数组,document2中没有匹配(但我希望它返回document1和document3)

2

DBObject query = QueryBuilder.start("data.user.credentials.lastname").is("Watson").and("data.user.credentials.name").is("John").get();

这个将返回所有三个文档:document1和document3是匹配的,但是查询将匹配document2,因为它在数组中的查询字段中有Watson和John,无论它们是单独的条目。

有没有办法做出正确的查询,为John Watson返回document1和document3?

我试图用Java做,但任何其他例子都没问题。

现在我使用一种解决方法来合并两个查询的结果:首先我使用elementMatch()从查询获得限制(100)结果,然后,如果结果少于100,我会执行第二次查询并过滤所有错误火柴。但我希望有更好,更有效的方法来获得这些结果。

1 个答案:

答案 0 :(得分:1)

我最多可以像下面那样将user放在数组中作为键data的展开值。我认为更多的努力会引导您达到您想要的确切格式。

我正在分享它,因为我认为它应该达到目的,或者无论如何它应该帮助你。

汇总查询

db.tuttut.aggregate([
    {$unwind:"$data.user"},
    { $project: { 
        _id:1, 
        data:1, 
        temp: {name:"$data.user.credentials.name",
               lastname:"$data.user.credentials.lastname"}  
        } }  ,
    { $group:{ 
        _id:"$_id" , 
        data: {$addToSet: "$data"} , 
        temp:{ $addToSet: "$temp"  } }  }, 
    { $match:{ temp:{name:"John",lastname:"Watson"}  }  }  ,
    {$project:{_id:1, data:1}}
]).pretty()

返回结果:

{
        "_id" : "document1",
        "data" : [
                {
                        "user" : {
                                "credentials" : {
                                        "name" : "John",
                                        "lastname" : "Watson",
                                        "middle" : "Hemish"
                                }
                        }
                }
        ]
}
{
        "_id" : "document3",
        "data" : [
                {
                        "user" : {
                                "credentials" : {
                                        "name" : "John",
                                        "lastname" : "Watson",
                                        "middle" : "Hemish"
                                }
                        }
                },
                {
                        "user" : {
                                "credentials" : {
                                        "name" : "Mary",
                                        "lastname" : "Watson",
                                        "middle" : ""
                                }
                        }
                },
                {
                        "user" : {
                                "credentials" : {
                                        "name" : "John",
                                        "lastname" : "Nicholson",
                                        "middle" : "Joseph"
                                }
                        }
                }
        ]
}