用于从嵌套数组集合中检索的mongoDB查询

时间:2016-06-15 13:28:29

标签: mongodb mongodb-query aggregation-framework

{
    "_id" : ObjectId("576155a6cd87b68f7e6e42c9"),
    "First_Name" : "ok",
    "Last_Name" : "jaao",
    "Email" : "xyz@gmail.com",
    "Sessions" : [
        {
            "Last_Login" : "Wed, Jun 14, 2016 6:48 PM",
            "Class" : "fb",
            "ID" : "123"
        },
        {
            "Last_Login" : "Wed, Jun 15, 2016 6:48 PM",
            "ID" : "111",
            "Class" : "fb"
        }
    ],
    "Count" : 2
},
{
    "_id" : ObjectId("576155ccf6d8979e7e77df27"),
    "First_Name" : "abc",
    "Last_Name" : "xyz",
    "Email" : "xyz@gmail.com",
    "Sessions" : [
        {
            "Last_Login" : "Wed, Jun 15, 2016 6:49 PM",
            "Class" : "fb",
            "ID" : "123"
        }
    ],
    "Count" : 1
}

这是我的json结构。我想要一个mongoDB查询,它检索今天已登录的每个用户,即Last_Login今天的日期。

我希望输出为:

{
    "_id" : ObjectId("576155a6cd87b68f7e6e42c9"),
    "First_Name" : "ok",
    "Last_Name" : "jaao",
    "Email" : "xyz@gmail.com",
    "Sessions" : [
        {
            "Last_Login" : "Wed, Jun 15, 2016 6:48 PM",
            "ID" : "111",
            "Class" : "fb"
        }
    ],
    "Count" : 2
},
{
    "_id" : ObjectId("576155ccf6d8979e7e77df27"),
    "First_Name" : "abc",
    "Last_Name" : "xyz",
    "Email" : "xyz@gmail.com",
    "Sessions" : [
        {
            "Last_Login" : "Wed, Jun 15, 2016 6:49 PM",
            "Class" : "fb",
            "ID" : "123"
        }
    ],
    "Count" : 1
}

1 个答案:

答案 0 :(得分:1)

您需要$elemMatchaggregate

db.users.aggregate([
    {
        $unwind: "$Sessions"
    },
    {
        $match: {
            "Sessions.Last_Login": {
                $gte: ISODate("2016-06-16T00:00:00.0Z"),
                $lt: ISODate("2016-06-17T00:00:00.0Z")
            }
        }
    },
    {
        $group: {
            _id: {
                _id: "$_id",
                First_Name: "$First_Name",
                Last_Name: "$Last_Name"
            },
            Sessions: {
                $push: "$Sessions"
            }
        }
    },
    {
        $project: {
            _id: "$_id._id",
            First_Name: "$_id.First_Name",
            Last_Name: "$_id.Last_Name",
            Sessions: "$Sessions"
        }
    }
])

因此查询将执行以下步骤:

  1. $unwind所有Sessions元素
  2. 日期范围内的
  3. $match个文档
  4. $group合并文件_idFirst_NameLast_Name
  5. $project文档看起来像原始格式
  6. 我省略了一些字段,但您可以轻松地将其添加到$group$project步骤中。当然,您需要更改日期范围。

    我关注这个查询在大集合中的表现。如果你使用我提供的第一个查询并在你的代码中过滤你想要的会话,也许会更好。

    修改

    正如@chridam所说,只有当您将Last_Login更改为ISODate()时,此查询才有效。

    编辑2:

    更新查询以使用aggregate并匹配日期范围内仅提取Sessions的请求。

    这是旧版本:

    db.users.filter({
        'Sessions': {
            '$elemMatch': {
                'Last_Login': {
                    '$gte': ISODate("2016-06-16T00:00:00.0Z"),
                    '$lt': ISODate("2016-06-17T00:00:00.0Z")
                }
            }
        }
    })