在 mongodb 中查询文档数组的正确方法是什么?

What is the correct way to query in mongodb for the array of documents?

下面是合集里的mongodb

{
"name" : "Tom" ,
"occupation" : "employee" ,
"data" : [
        {
            "owns" : "Television" ,
            "company" : "xyz"   
        },
        {
            "owns" : "Television" ,
            "company" : "abc"   
        },
        {
            "owns" : "laptop" ,
            "company" : "abc"
        } ,
        {
            "owns" : "Television" ,
            "company" : "xyz"
        }

        ]   
}

当我查询时

   db.exp.find({"data.owns" : "Television"}) 

mongodb returns 结果集中有 "owns" :"laptop" 的文档。

当我查询

   db.exp.find({"data.owns": "Television"},{_id: 0, data: {$elemMatch: {"owns": "Television"}}}) 

结果仅显示数据字段中找到 "Television" 的第一个匹配项的一个文档

我如何查询以获取 Tom 拥有 Television 的所有 3 个文档,不包括笔记本电脑文档。 预期结果

 [
        {
            "owns" : "Television" ,
            "company" : "xyz"   
        },
        {
            "owns" : "Television" ,
            "company" : "abc"   
        },

        {
            "owns" : "Television" ,
            "company" : "xyz"
        }

 ]  

注意:我在这个例子中数据字段中只提到了 4 个文档,而原始集合有 50 多个文档。 抱歉我的英语不好:)。

假设您在集合中有两个文档 exp

[
  {
  "name" : "Tom" ,
  "occupation" : "employee" ,
  "data" : [ { "owns" : "Television" , "company" : "xyz" },
    { "owns" : "Television" , "company" : "abc" },
    { "owns" : "laptop" , "company" : "abc" } ,
    { "owns" : "Television" , "company" : "xyz" } ]   
  },
  {
  "name" : "Jerry" ,
  "occupation" : "employee" ,
  "data" : [ { "owns" : "Mobile" , "company" : "xyz" },
    { "owns" : "Mobile" , "company" : "abc" },
    { "owns" : "laptop" , "company" : "abc" } ,
    { "owns" : "Laptop" , "company" : "xyz" } ]   
  }
]

然后通过您的查询 db.exp.find({"data.owns" : "Television"}),您将得到

{ "_id" : 101, 
"name" : "Tom", 
"occupation" : "employee", 
"data" : [ 
  { "owns" : "Television", "company" : "xyz" }, 
  { "owns" : "Television", "company" : "abc" }, 
  { "owns" : "laptop", "company" : "abc" }, 
  { "owns" : "Television", "company" : "xyz" } 
 ] 
}

由于第一个文档的字段 owns 等于 Television,结果将是完整的第一个文档。(包括那些具有 owns 而不是 [=16= 的字段) ]) 第二个文档不会成为结果的一部分,因为它没有任何值为 Television.

owns 字段

$elemMatch 只会 return 一份文件。

http://docs.mongodb.org/manual/reference/operator/projection/elemMatch/

如果您只想要数组中以 Television 作为其值的那三个对象,那么您可以使用游标来存储查询的整个结果(在我们的例子中只有一个文档)。

var x = db.authors.find({"data.owns": "Television"},{_id: 0, "data.owns": 1})

现在,使用 for each 循环仅获取具有 owns 且值为 Television 的文档。

这可以使用 aggregation.

  • $unwind data 数组。
  • 使用 $match 阶段过滤 owns 值为 Television 的文档。
  • $group 阶段重新分组您的文档。
  • 重塑文档的 $project 阶段。
db.exp.aggregate(
    [
        { "$unwind": "$data" }, 
        { "$match": { "data.owns": "Television" }}, 
        {
            "$group": {
                          "_id": {
                                     "name": "$name",
                                     "occupation": "$occupation"
                                 }, 
                          "data": { "$push": "$data" }
                      }
        }, 
        {
            "$project": {
                            "name": "$_id.name", 
                            "occupation": "$_id.occupation", 
                            "data": 1, 
                            "_id": 0
                        }
        }
    ]
)

结果:

{
        "data" : [
                {
                        "owns" : "Television",
                        "company" : "xyz"
                },
                {
                        "owns" : "Television",
                        "company" : "abc"
                },
                {
                        "owns" : "Television",
                        "company" : "xyz"
                }
        ],
        "name" : "Tom",
        "occupation" : "employee"
}