使用$ elemMatch时如何限制/检索MongoDB文档的内部字段

时间:2015-11-26 02:06:51

标签: mongodb mongoose

我在名为notification的集合中有文档,如下所示。

{
"_id" : ObjectId("56438985e68a78f46b1fd9cc"),
"modulename" : "Admin Control Panel",
"modulecode" : "acp",
"eventnames" : [ 
    {
        "name" : "New user account added",
        "code" : 100,
        "_id" : ObjectId("5655fb5d710557d8f7895d94"),
        "emails" : [ 
            "email1@abc.com"
        ]
    }, 
    {
        "name" : "User permissions changes",
        "code" : 200,
        "_id" : ObjectId("5655fb5d710557d8f7895d93"),
        "emails" : [ 
            "email1@abc.com", 
            "email2@abc.com", 
            "email3@abc.com"
        ]
    }
]
}

我想从emails数组中仅检索对象的eventnames属性,匹配为code 100。

我尝试$elemMatch过滤文档并得到如下结果。

查询:

db.getCollection('notifications').find({modulecode: 'acp'},{eventnames: { $elemMatch: {code:100}}})

结果:

{
"_id" : ObjectId("56438985e68a78f46b1fd9cc"),
"eventnames" : [ 
    {
        "name" : "New user account added",
        "code" : 100,
        "_id" : ObjectId("5655fb5d710557d8f7895d94"),
        "emails" : [ 
            "email1@abc.com"
        ]
    }
]
}

我接近我想要的但只想获得emails如下

"emails" : [ 
            "email1@abc.com"
        ]

1 个答案:

答案 0 :(得分:1)

您可以通过在投影中指定其他字词来仅包含emails数组的eventnames字段并省略_id来执行此操作:

db.getCollection('notifications').find({modulecode: 'acp'}, {
    eventnames: { $elemMatch: {code:100}}, 
    'eventnames.emails': 1,
    _id: 0
})

结果:

{
    "eventnames" : [ 
        {
            "emails" : [ 
                "email1@abc.com"
            ]
        }
    ]
}

请注意,您仍然拥有父eventnames字段,但这是必需的,因为您无法使用find更改文档的整体形状。如果你真的想因某种原因摆脱它,你需要使用aggregate