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



我有一个名为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"
        ]
    }
]
}

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

我尝试了$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"
        ]

您可以通过在投影中指定附加项来实现这一点,只包括eventnames数组的emails字段并省略_id:

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

结果:

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

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

最新更新