MongoDB-仅检索匹配的子文档和根文档

MongoDB-仅检索匹配的子文档和根文档,mongodb,Mongodb,编辑: 问题已解决,请参见下文 我有以下文件: db.clients.insert({ _id: ObjectId("524d720d8d3ea014a52e95bb"), company: "Example", logins: [ { "name": "John Smith", "username": "test", "password": "eF9wnBEys0OzL5vmR/OH

编辑: 问题已解决,请参见下文

我有以下文件:

db.clients.insert({
    _id: ObjectId("524d720d8d3ea014a52e95bb"),
    company: "Example",
    logins: [
        {
            "name": "John Smith",
            "username": "test",
            "password": "eF9wnBEys0OzL5vmR/OHGCaekHiw/Miy+XvbDdayxeo=",
            "email": "a@a.com",
            "last": null,
            "roles": ["CONFIG"]
        },
        {
            "name": "Guest",
            "username": "guest",
            "password": "K/gYODb7XPo0erySvL276DyPi4+stPPK4jM3pJ8aaVg=",
            "email": "a@a.com",
            "last": null,
            "roles": []
        }
    ]
});
现在,我想用这个文档对我的客户进行身份验证。但是,我不想检索每个子登录,我只想要一个匹配的

这就是我使用聚合的原因:

db.clients.aggregate(
    {
        "$project": {
            "login": "$logins",
            "_id": 0
        }
    },
    {
        "$unwind": "$login"
    },
    {
        "$group": {
            "_id": "$login.username",
            "login": {
                "$first": "$login"
            }
        }
    },
    {
        "$match": {
            "login.username": "test",
            "login.password": "eF9wnBEys0OzL5vmR/OHGCaekHiw/Miy+XvbDdayxeo=",
        }
    }
);
这很好,给了我:

{
        "result" : [
                {
                        "_id" : "test",
                        "login" : {
                                "name" : "John Smith",
                                "username" : "test",
                                "password" : "eF9wnBEys0OzL5vmR/OHGCaekHiw/Miy+XvbDdayxeo=",
                                "email" : "a@a.com",
                                "last" : null,
                                "roles" : [
                                        "CONFIG"
                                ]
                        }
                }
        ],
        "ok" : 1
}
但现在,棘手的部分是,我还想检索根文档字段。例如
\u id
公司

但不管我怎么努力,我都做不到。你有解决办法吗?:)


编辑:

好吧,事实上这并不难。对不起

db.clients.aggregate(
    {
        "$project": {
            "login": "$logins",
            "_id": "$_id",
            "company": "$company"
        }
    },
    {
        "$unwind": "$login"
    },
    {
        "$group": {
            "_id": "$login.username",
            "login": {
                "$first": "$login"
            },
            "clientId": {
                "$first": "$_id"
            },
            "company": {
                "$first": "$company"
            },
        }
    },
    {
        "$match": {
            "login.username": "test",
            "login.password": "eF9wnBEys0OzL5vmR/OHGCaekHiw/Miy+XvbDdayxeo=",
        }
    }
);
略短一点的变体:

db.clients.aggregate(
  {$match:{"logins.username":"test"}},
  {$unwind:"$logins"},
  {$match:{"logins.username":"test","logins.password":"eF9wnBEys0OzL5vmR/OHGCaekHiw/Miy+XvbDdayxeo="}}
)
输出为:

{
        "result" : [
                {
                        "_id" : ObjectId("524d720d8d3ea014a52e95bb"),
                        "company" : "Example",
                        "logins" : {
                                "name" : "John Smith",
                                "username" : "test",
                                "password" : "eF9wnBEys0OzL5vmR/OHGCaekHiw/Miy+XvbDdayxeo=",
                                "email" : "a@a.com",
                                "last" : null,
                                "roles" : [
                                        "CONFIG"
                                ]
                        }
                }
        ],
        "ok" : 1
}

您也可以使用
查找
和位置投影操作符来执行此操作:

db.clients.find({
“logins.username”:“测试”,
“登录密码”:“eF9wnBEys0OzL5vmR/OHGCaekHiw/Miy+XvbDdayxeo=”,
}, {
“登录。$”:1,
“公司”:1
})
投影中的
$
包含查询中匹配的
登录
数组元素的索引

输出:

{
“_id”:ObjectId(“524d720d8d3ea014a52e95bb”),
“公司”:“示例”,
“登录”:[
{
“姓名”:“约翰·史密斯”,
“用户名”:“测试”,
“密码”:“eF9wnBEys0OzL5vmR/OHGCaekHiw/Miy+XvbDdayxeo=”,
“电子邮件”:a@a.com",
“last”:空,
“角色”:[
“配置”
]
}
]
}

所以请对您自己的问题发表一个答案,没关系。我是stackoverflow的新手,所以我的声誉很低。我不能在8小时前回答我自己的问题:)我想你需要在
{$match:{“logins.username:“test”}}
之前先
解开
。不,你不需要解开。因为,这样做一个数组检查级别?数组的所有元素都会被检查。是否可以只返回子文档中选定的字段?ie仅
登录
名称
?我尝试了
登录。$.name
但它返回了整个子文档。@user1063287我本以为可以。最好发布一个新的问题和细节。