Mongo查询具有前N的子文档

时间:2014-07-15 22:30:26

标签: mongodb pipeline aggregation-framework top-n subdocument

我在MongoDB的用户集合中获得了以下数据:

{
        "_id" : ObjectId("53807beee4b0d2b25747df7e"),
        "allowedAppIds" : [ 
            {
                "appId" : "534c8d2ce4b024b1f08e16e6",
                "createdDate" : ISODate("2014-06-21T20:22:11.945Z"),
            }, 
            {
                "appId" : "53585d97e4b0769f79d1e140",
                "createdDate" : ISODate("2014-06-21T21:03:56.045Z"),
            }, 
            {
                "appId" : "53490f2ae4b024b1f08e0c39",
                "createdDate" : ISODate("2014-06-26T22:36:21.855Z"),
            }, 
            {
                "appId" : "537e3ad7e4b0a8e6dd5cf20b",
                "createdDate" : ISODate("2014-06-28T19:44:43.805Z"),
            }
        ],
        "createdDate" : ISODate("2014-05-24T11:01:02.835Z"),
    }, 
    {
        "_id" : ObjectId("53aca073e4b00bff4ee85f6d"),
        "allowedAppIds" : [ 
            {
                "appId" : "536927eee4b005b056353a8a",
                "createdDate" : ISODate("2014-06-26T22:36:57.681Z"),
            }
        ],
        "createdDate" : ISODate("2014-06-26T22:36:35.767Z"),
    }, 
    {
        "_id" : ObjectId("53aca12fe4b00bff4ee85fd8"),
        "allowedAppIds" : [ 
            {
                "appId" : "537e3ad7e4b0a8e6dd5cf20b",
                "createdDate" : ISODate("2014-06-27T06:33:32.728Z"),
            }
        ],
        "createdDate" : ISODate("2014-06-26T22:39:43.726Z"),
    }, 
    {
        "_id" : ObjectId("53ac9f86e4b078bf3022fe16"),
        "allowedAppIds" : [ 
            {
                "appId" : "537e3ad7e4b0a8e6dd5cf20b",
                "createdDate" : ISODate("2014-06-26T22:32:49.655Z"),
            }, 
            {
                "appId" : "534c8d2ce4b024b1f08e16e6",
                "createdDate" : ISODate("2014-06-26T22:42:38.011Z"),
            }
        ],
        "createdDate" : ISODate("2014-06-26T22:32:38.806Z"),
    } 

我试图计算整个系列的第一个appIds。因此,对于每个用户,我需要获得他们的第一个allowedAppId,该appId的组,并获得整个集合的计数。

对于上面的数据,我试图得到这个:

appId:  534c8d2ce4b024b1f08e16e6 count: 1
appId:  536927eee4b005b056353a8a count: 1
appId:  537e3ad7e4b0a8e6dd5cf20b count: 2

一旦我开始工作,我将尝试在allowedAppIds.createdDate中创建日期周围的日期参数,以便按日期进一步过滤。

我对Mongo还不太新,所以如果这是基本的我道歉。我在google等上看过很多例子,但是我们还没有能够找到任何会使用聚合管道从我的子文档中获得前1个记录的东西。

通过在我的管道中执行此操作,我确实已经足够了解实际上已经允许AppIds(并非所有用户文档都具有allowedAppId子文档)的记录:

db.user.aggregate({$match:{"allowedAppIds.0": {$exists: true}}})

但是我仍然无法从第一个appId获取与之关联的createdDate。

1 个答案:

答案 0 :(得分:0)

您可以通过展开allowedAppIds字段然后分组两次来完成此操作:

db.test.aggregate([
    // Duplicate the docs, one per allowedAppIds element
    {$unwind: '$allowedAppIds'},
    // Group them back by _id, but just take the first element from each _id set
    {$group: {_id: '$_id', appId: {$first: '$allowedAppIds.appId'}}},
    // Now group by appId and count
    {$group: {_id: '$appId', count: {$sum: 1}}}
])

输出:

{
    "result" : [ 
        {
            "_id" : "534c8d2ce4b024b1f08e16e6",
            "count" : 1
        }, 
        {
            "_id" : "536927eee4b005b056353a8a",
            "count" : 1
        }, 
        {
            "_id" : "537e3ad7e4b0a8e6dd5cf20b",
            "count" : 2
        }
    ],
    "ok" : 1
}