我正在尝试从我的文档中获取一定数量的历史数据,类似于SQL的Between子句。我搜索了类似的问题,并设法找到这个查询,但它只返回数组的第一个元素,所以这还不够:
db.docs.find({ _id: "eraj4983tj3" }, {history: { $elemMatch : {time: {$gt: new ISODate("2016-03-21T20:53:33.662Z") , $lt: new ISODate("2016-03-21T20:54:20.313Z") } } } });
我的文件如下:
{
"_id": "eraj4983tj3",
"descr": "somestuff",
"history": [
{
"time": ISODate("2016-03-21T20:52:31.389Z"),
"value": 103.91
},
{
"time": ISODate("2016-03-21T20:53:33.663Z"),
"value": 106.91
},
{
"time": ISODate("2016-03-21T20:53:45.179Z"),
"value": 104.91
},
{
"time": ISODate("2016-03-21T20:54:20.313Z"),
"value": 105.11
},
{
"time": ISODate("2016-03-21T20:54:53.649Z"),
"value": 105.41
},
{
"time": ISODate("2016-03-21T20:55:12.998Z"),
"value": 115.91
}
]
}
我的查询结果应该返回:
{
"_id": "eraj4983tj3",
"history": [
{
"time": ISODate("2016-03-21T20:53:45.179Z"),
"value": 104.91
},
{
"time": ISODate("2016-03-21T20:54:20.313Z"),
"value": 105.11
},
{
"time": ISODate("2016-03-21T20:54:53.649Z"),
"value": 105.41
}
]
}
如何编写查询以实现此结果?
答案 0 :(得分:3)
使用简单查询无法实现您的目标。但是,您可以使用聚合:
db.yourColl.aggregate([
{ $match:{ _id:"eraj4983tj3" } },
{ $unwind: "$history" },
{ $match:{ "history.time":{
$gt: new ISODate("2016-03-21T20:53:33.662Z") ,
$lt: new ISODate("2016-03-21T20:54:20.313Z")
}}},
{ $group:{ _id:"$_id", history:{ $push:"$history" }}}
])
它为您提供
的(正确)结果{
"_id" : "eraj4983tj3",
"history" : [
{ "time" : ISODate("2016-03-21T20:53:33.663Z"), "value" : 106.91 },
{ "time" : ISODate("2016-03-21T20:53:45.179Z"), "value" : 104.91 }
]
}
现在,让我们来看看各个阶段:
{ $match:{ _id:"eraj4983tj3" } }
:找到正确的文档 { $unwind: "$history" }
为每个数组项创建一个新文档,并将其发送到管道。
这个阶段的输出如下:
{ "_id" : "eraj4983tj3", "descr" : "somestuff", "history" : { "time" : ISODate("2016-03-21T20:52:31.389Z"), "value" : 103.91 } }
{ "_id" : "eraj4983tj3", "descr" : "somestuff", "history" : { "time" : ISODate("2016-03-21T20:53:33.663Z"), "value" : 106.91 } }
{ "_id" : "eraj4983tj3", "descr" : "somestuff", "history" : { "time" : ISODate("2016-03-21T20:53:45.179Z"), "value" : 104.91 } }
{ "_id" : "eraj4983tj3", "descr" : "somestuff", "history" : { "time" : ISODate("2016-03-21T20:54:20.313Z"), "value" : 105.11 } }
{ "_id" : "eraj4983tj3", "descr" : "somestuff", "history" : { "time" : ISODate("2016-03-21T20:54:53.649Z"), "value" : 105.41 } }
{ "_id" : "eraj4983tj3", "descr" : "somestuff", "history" : { "time" : ISODate("2016-03-21T20:55:12.998Z"), "value" : 115.91 } }
{ $match:{ "history.time":{ $gt: new ISODate("2016-03-21T20:53:33.662Z"), $lt: new ISODate("2016-03-21T20:54:20.313Z")}}}
我们再次匹配,以查找与我们的日期范围匹配的上一级的历史记录项。这个阶段的输出如下:
{ "_id" : "eraj4983tj3", "descr" : "somestuff", "history" : { "time" : ISODate("2016-03-21T20:53:33.663Z"), "value" : 106.91 } }
{ "_id" : "eraj4983tj3", "descr" : "somestuff", "history" : { "time" : ISODate("2016-03-21T20:53:45.179Z"), "value" : 104.91 } }
{ $group:{ _id:"$_id", history:{ $push:"$history" }}}
我们按_id
分组(这里没有新内容),对于上一阶段输出的每个文档,我们 {{3在新创建的分组文档中,history
(对象)到数组history
的值。
答案 1 :(得分:1)
位置操作符$
和elemMatch
只返回一个子文档。