Mongodb获取子文档并按日期过滤

时间:2015-05-11 09:59:01

标签: mongodb

我有一个包含以下文件的集合。

{
    "id":1,
    "url":"mysite.com",
    "views":
     [
       {"ip":"1.1.1.1","date":ISODate("2015-03-13T13:34:40.0Z")},
       {"ip":"2.2.2.2","date":ISODate("2015-03-13T13:34:40.0Z")},
       {"ip":"1.1.1.1","date":ISODate("2015-02-13T13:34:40.0Z")},
       {"ip":"1.1.1.1","date":ISODate("2015-02-13T13:34:40.0Z")}
     ]
},
{
    "id":2,
    "url":"mysite2.com",
    "views":
     [
       {"ip":"1.1.1.1","date":ISODate("2015-01-13T13:34:40.0Z")},
       {"ip":"2.2.2.2","date":ISODate("2015-01-13T13:34:40.0Z")},
       {"ip":"1.1.1.1","date":ISODate("2015-02-13T13:34:40.0Z")},
       {"ip":"1.1.1.1","date":ISODate("2015-02-13T13:34:40.0Z")}
     ]
}

如何获取id = 1date(Y-m) = 2015-02的文档?

2 个答案:

答案 0 :(得分:0)

您可以使用aggregation pipeline operators。以下内容将返回views数组中符合条件的所有子文档。

$match使用给定的id过滤选择的文档 $unwind views数组。在您的第一个$project阶段,使用$year运算符返回日期年份和$month日期的月份。接下来,使用monthyear$match过滤您的文档。 _id {} {}} {} {{}} {{}} {} {{}}

$project

<强>结果

db.collection.aggregate(
    [
        {'$match': {'id': 1}}, 
        {'$unwind': '$views'}, 
        {'$project': {
            'id': 1,
            'year': {'$year': '$views.date'}, 
            'month': {'$month': '$views.date'}, 
            'url': 1, 'views': 1
            }
        }, 
        {'$match': {'year': 2015, 'month': 2}},
        {'$group': {
                       '_id': '$id', 
                       'url': {'$first': 'url'}, 
                       'views': {'$push': '$views'}
                   }
        },
        {'$project': {'id': '$_id', 'views': 1, 'url': 1, '_id': 0}}
    ]
)

答案 1 :(得分:0)

要获取满足上述条件的特定{ "url" : "url", "views" : [ { "ip" : "1.1.1.1", "date" : ISODate("2015-02-13T13:34:40Z") }, { "ip" : "1.1.1.1", "date" : ISODate("2015-02-13T13:34:40Z") } ], "id" : 1 } 数组元素(子文档),请使用$group投影运算符,如下所示:

"views"

返回:

var start = new Date(2015, 0, 31, 23, 59, 59),
    end = new Date(2015, 2, 1);
db.test.find(
{
    id: 1, 
    "views.date": { "$gt": start, "$lt": end}
}, 
{
    "id": 1,
    "views": { 
        "$elemMatch": { 
            "date": { "$gt": start, "$lt": end} 
        } 
    }
});

如果您只想返回整个文档,请使用不带$elemMatch投影的日期范围查询,如下所示:

/* 0 */
{
    "_id" : ObjectId("555089bf9cd8fa39c7971e33"),
    "id" : 1,
    "views" : [ 
        {
            "ip" : "1.1.1.1",
            "date" : ISODate("2015-02-13T13:34:40.000Z")
        }
    ]
}

上面的查询将返回符合上述条件的整个文档,包括as = ll子文档:

var start = new Date(2015, 0, 31, 23, 59, 59),
    end = new Date(2015, 2, 1);
db.test.find({id: 1, "views.date": { "$gt": start, "$lt": end}})