只获得子元素

时间:2015-01-13 21:25:08

标签: mongodb

如果我有以下文件

{
    "_id" : ObjectId("54986d5531a011bb5fb8e0ee"),
    "owner" : "54948a5d85f7a9527a002917",
    "type" : "group",
    "deleted" : false,
    "participants" : [
        { "_id": "54948a5d85f7a9527a002917", "name": "user1" },
        { "_id": "5491234568f7a9527a002918", "name": "user2" },
        { "_id": "5491234568f7a9527a002918", "name": "user3" },
        { "_id": "1234567aaaa7a9527a002917", "name": "user2" }
    ]
}

如何获取name ='user2'的所有记录?

我正在尝试跟进:

db.users.find({ _id: ObjectId('54a7103b1a57eee00bc0a9e4') }, 
{ 'participants.$.name': 'user2') }).pretty()

...我得到以下内容:

error: {
    "$err" : "Can't canonicalize query: BadValue Positional projection 'participants.$.name' does not match the query document.",
    "code" : 17287
}

1 个答案:

答案 0 :(得分:1)

虽然位置运算符($)会为参与者数组提供第一个匹配元素。如果您需要名为user2的所有参与者,则需要汇总结果。

  • Match包含所需_id的文档。

  • 使用redact运算符仅保留所有子文档 参与者,他们的名字为user2

代码:

var search = "user2";
db.users.aggregate([
{$match:{"_id":ObjectId("54986d5531a011bb5fb8e0ee")}},
{$redact:{$cond:[{$eq:[{$ifNull:["$name",search]},search]},
                 "$$DESCEND",
                 "$$PRUNE"]}},
{$project:{"participants":1,"_id":0}} // set _id:1, if you need the _id.
])

O / P:

{
        "participants" : [
                {
                        "_id" : "5491234568f7a9527a002918",
                        "name" : "user2"
                },
                {
                        "_id" : "1234567aaaa7a9527a002917",
                        "name" : "user2"
                }
        ]
}

来到您的查询,

db.users.find({ _id: ObjectId('54a7103b1a57eee00bc0a9e4') }, 
              { 'participants.$.name': 'user2'}).pretty()

位置运算符只能应用于数组,在find函数的查询文档中引用。上述查询文档没有对名为participants的数组的引用,仅引用_id字段来匹配文档。因此你得到了错误。

来自docs

  

受限制的字段必须出现在查询文档

因此,更改查询以在查询文档中包含参与者数组将修复错误。

  db.users.find({ "_id":ObjectId('54a7103b1a57eee00bc0a9e4'),
                  "participants.name": "user2"
                }, 
                {"participants.$.name":"user2"}).pretty()

但它只返回与查询文档中的条件匹配的第一个参与者。

来自docs

  

在find()方法或findOne()的投影文档中使用$   当您只需要选中一个特定数组元素时的方法   文档。

O / P:

{
        "_id" : ObjectId("54986d5531a011bb5fb8e0ee"),
        "participants" : [
                {
                        "_id" : "5491234568f7a9527a002918",
                        "name" : "user2"
                }
        ]
}