Mongodb数组中的搜索日期
我有很多这样的文件:Mongodb数组中的搜索日期,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有很多这样的文件: { "_id" : ObjectId("54a94200aa76d3db6cd51977"), "URL" : "http://...", "Statistics" : [ { "Date" : ISODate("2010-05-18T18:07:29.000+0000"), "Clicks" : NumberInt(250), },
{
"_id" : ObjectId("54a94200aa76d3db6cd51977"),
"URL" : "http://...",
"Statistics" : [
{
"Date" : ISODate("2010-05-18T18:07:29.000+0000"),
"Clicks" : NumberInt(250),
},
{
"Date" : ISODate("2010-05-21T12:06:41.000+0000"),
"Clicks" : NumberInt(165),
},
{
"Date" : ISODate("2010-05-30T08:37:50.000+0000"),
"Clicks" : NumberInt(263),
}
]
}
我的查询如下所示:
db.clicks.aggregate([
{ $match : 'Statistics.Date' : { $gte: new Date("2010-05-18T00:00:00.000Z"), $lte: new Date("2010-05-18T23:59:59.999Z") } },
{ $unwind' => '$Statistics' },
{ $group : { _id : { year : { $year : '$Statistics.Date' }, month : { $month : '$Statistics.Date' }, day : { $dayOfMonth : '$Statistics.Date' } }, Clicks : { $sum : '$Statistics.Clicks' } },
{ $sort : { _id : 1 } }
])
{
"_id" : [
{
"year" : 2010,
"month" : 5,
"day" : 18
}
],
"Clicks" : 250
},
{
"_id" : [
{
"year" : 2010,
"month" : 4,
"day" : 21
}
],
"Clicks" : 165
},
{
"_id" : [
{
"year" : 2010,
"month" : 5,
"day" : 30
}
],
"Clicks" : 263
}
当我试图总结某个特定日期的点击次数时,它会给出所有日期,而不是一个。我做错了什么?提前谢谢
编辑1:
由于该集合中有超过80.000个文档,我无法在$match之前进行$diswind。另外,这也不是一个好主意,因为这会使查询速度比需要的慢。
其中包含大量的文档和数据,这就是我必须使用$sum的原因。我上面制作的文档只是一个示例,只有结构与我的项目中的相同
上面的查询返回了smth,如下所示:
db.clicks.aggregate([
{ $match : 'Statistics.Date' : { $gte: new Date("2010-05-18T00:00:00.000Z"), $lte: new Date("2010-05-18T23:59:59.999Z") } },
{ $unwind' => '$Statistics' },
{ $group : { _id : { year : { $year : '$Statistics.Date' }, month : { $month : '$Statistics.Date' }, day : { $dayOfMonth : '$Statistics.Date' } }, Clicks : { $sum : '$Statistics.Clicks' } },
{ $sort : { _id : 1 } }
])
{
"_id" : [
{
"year" : 2010,
"month" : 5,
"day" : 18
}
],
"Clicks" : 250
},
{
"_id" : [
{
"year" : 2010,
"month" : 4,
"day" : 21
}
],
"Clicks" : 165
},
{
"_id" : [
{
"year" : 2010,
"month" : 5,
"day" : 30
}
],
"Clicks" : 263
}
如果我不使用$group,我还必须使用$limit,因为查询将超过16MB,否则:
db.clicks.aggregate([
{ $match : 'Statistics.Date' : { $gte: new Date("2010-05-18T00:00:00.000Z"), $lte: new Date("2010-05-18T23:59:59.999Z") } },
{ $unwind' : '$Statistics' },
{ $limit : 1 }
])
这一结果:
{
"_id" : ObjectId("54a94200aa76d3db6cd51977"),
"URL" : "http://...",
"Statistics" : {
"Date" : {
"sec" : 1274166878,
"usec" : 0
},
"Clicks" : 250
}
}
由于性能原因,我不得不使用$group,不使用它不是一个选项
正如我在PHP中所做的那样,我提到的文档、查询和结果中可能存在一些错误。希望这不会是个问题。我还没有弄清楚是什么导致了我的问题。有人能帮我吗
编辑2:
由于这似乎是一个无法解决的性能问题,我正在将所有数据从“Statistics”数组迁移到自己的集合中。谢谢您的帮助。您需要在$REWUND前后运行$match两次:
db.clicks.aggregate[
{$match:{'Statistics.Date':{
$gte:new ISODate2010-05-18T00:00:00.000Z,
$lte:new ISODate2010-05-18T23:59:59.999Z},
{$unwind:'$Statistics'},
{$match:{'Statistics.Date':{
$gte:new ISODate2010-05-18T00:00:00.000Z,
$lte:new ISODate2010-05-18T23:59:59.999Z},
{$组:{
_id:{year:{$year:'$Statistics.Date'},
月份:{$month:'$Statistics.Date'},
日期:{$dayOfMonth:'$Statistics.Date'},
单击:{$sum:'$Statistics.Clicks'}},
{$sort:{{u id:1}}
]
第一个$match用于选择日期范围内至少有一个统计元素的文档。第二个用于过滤那些不在正确日期范围内的文档的其他统计元素。事情可能已经解决了,但为寻求此问题帮助的人发布答案
{ $match : 'Statistics.Date' : { $gte: new Date("2010-05-18T00:00:00.000Z"),
enter code here$lte: new Date("2010-05-18T23:59:59.999Z") } }
此匹配将筛选主文档。您需要的是过滤统计数组中的文档。
现在,按$match筛选的文档将包含完整的统计数组。过滤后的展开可能有统计信息的子文档,其同级DocumentDocumentDocument(位于同一数组中)已通过$match条件
注:简单查找投影:
db.col_name.find{},{Statistics.$:1}也将筛选数组,但
聚合中的$project无助于筛选文档数组
您好,您可以查询与该日期匹配的项目并查看结果吗?尝试先展开,然后匹配可能会解决您的问题,或者在现有查询中展开后添加相同的匹配。事实上@yogesh是对的,您必须先展开数据,然后再匹配,因为如果不展开,它将匹配整个静态行,我无法由于性能原因,请先执行$REWIND。收藏中有超过8万份像我提到的那样的文件。大多数时候,它只是以一个错误结束,就像直到30秒才有答案一样。当我只对一件物品设定$limit时,它也会给出所有的日期。当我没有在查询中添加$group时,这种行为就停止了。也许你应该在aggreagtionOk中添加allowDiskUse,我没有提到这一点,但我也已经尝试过了。这最终导致了MongoCorSortimeoutException。即使$limit设置为1,您是否尝试过使用更长的光标超时?不,因为它必须很快,因为数据将用于图形。我想,没有用户希望等待请求的数据的时间超过1分钟。然后,如果尚未添加统计数据索引,则需要添加统计数据索引。日期。若要进一步提高性能,可能需要更改架构以将数据从统计数据数组移到单独的集合中。但这超出了这个问题的范围。