只获取子元素

Getting only Sub Elements

如果我有以下文件

{
    "_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" }
    ]
}

如何获取名称 = '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
}

尽管位置运算符 ($) 会为您提供参与者数组中的第一个匹配元素。如果您需要姓名为 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()

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

来自docs,

The field being limited must appear in the query document

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

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

但它会 return 您只是第一个与查询文档中的条件匹配的参与者。

来自docs,

Use $ in the projection document of the find() method or the findOne() method when you only need one particular array element in selected documents.

o/p:

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