2

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

我有以下文件:

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
}

但现在,棘手的部分是我还想检索根文档字段。比如_idcompany例如。

但无论我尝试什么,我都无法做到。你有解决方案吗?:)


编辑:

好吧,其实这并不难。对不起!

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=",
        }
    }
);
4

2 回答 2

11

您也可以使用 afind$位置投影运算符来执行此操作:

db.clients.find({
        "logins.username": "test",
        "logins.password": "eF9wnBEys0OzL5vmR/OHGCaekHiw/Miy+XvbDdayxeo=",
    }, {
        "logins.$": 1,
        "company": 1
    })

$投影中的 包含查询中匹配的数组元素的索引logins

输出:

{
  "_id": ObjectId("524d720d8d3ea014a52e95bb"),
  "company": "Example",
  "logins": [
    {
      "name": "John Smith",
      "username": "test",
      "password": "eF9wnBEys0OzL5vmR/OHGCaekHiw/Miy+XvbDdayxeo=",
      "email": "a@a.com",
      "last": null,
      "roles": [
        "CONFIG"
      ]
    }
  ]
}
于 2013-10-04T12:53:13.387 回答
1

更短的变体:

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
}
于 2013-10-04T12:32:22.110 回答