【发布时间】:2015-08-09 05:28:27
【问题描述】:
我有一个 MongoDB 集合,其结构(简化)如下:
[
{
"name" : "name1",
"instances" : [
{
"value" : 1,
"score" : 2,
"date" : ISODate("2015-03-04T00:00:00.000Z")
},
{
"value" : 2,
"score" : 5,
"date" : ISODate("2015-04-01T00:00:00.000Z")
},
{
"value" : 2.5,
"score" : 9,
"date" : ISODate("2015-03-05T00:00:00.000Z")
}
]
},
{
"name" : "name2",
"instances" : [
{
"value" : 6,
"score" : 3,
"date" : ISODate("2015-03-05T00:00:00.000Z")
},
{
"value" : 1,
"score" : 6,
"date" : ISODate("2015-03-04T00:00:00.000Z")
},
{
"value" : 3.7,
"score" : 5.2,
"date" : ISODate("2015-02-04T00:00:00.000Z")
}
]
},
{
"name" : "name3",
"instances" : [
{
"value" : 6,
"score" : 3,
"date" : ISODate("2015-03-05T00:00:00.000Z")
},
{
"value" : 1,
"score" : 6,
"date" : ISODate("2015-03-04T00:00:00.000Z")
},
{
"value" : 3.7,
"score" : 5.2,
"date" : ISODate("2015-02-04T00:00:00.000Z")
}
]
}
]
目前我有一个aggregate 查询,它在给定日期之前从每个文档中提取一个实例:
db.myCollection.aggregate([
{$unwind: "$instances"},
{$sort: {'instances.date': -1}},
{$match: {'instances.date': {$lte: <givenDate>}}},
{$project: {name: 1, _id: 0, date: "$instances.date", value: "$instances.value", score: "$instances.score"}},
{$group: {_id: "$name", name: {$first: "$name"}, date: {$first: "$date"},
value: {$first: "$value"}, score: {$first: "$score"}}}
])
这个查询工作得很好,对于给定的日期,将返回每个文档中最新的(即,恰好或之前的)实例。
当给定日期早于最早实例时,我的问题就开始了。例如,如果我给定的日期是 2015-03-02,我将不会从 name1 获得任何实例。在这种情况下,我想检索文档中可用的最早实例。
显然,我可以将此任务拆分为两个不同的查询并合并结果,但如果可能,我希望在单个数据库查询中实现此目标。
有什么想法吗?
【问题讨论】:
-
在那种情况下,你为什么需要指定
date? -
不确定我是否理解这个问题。我从用户选择中获取日期,我需要获取截至该日期的最新值。如果有些项目的日期太早,我想拿到最早的。
-
我的意思如下。如果您有这种情况,则指定的
date没有意义。换句话说,无论您是否指定date,每个文档的结果都将是$first日期。我错过了什么吗? -
在上面的示例 DB 中,如果
date是 2015-03-04,那么结果集将包含来自name1的第一个实例,来自name2的第二个实例,以及第二个来自name3。如果date是 2015-03-02,则结果集将仅包含 2 个项目(来自name2和name3的第三个实例)。在这种情况下,我将希望从name1中添加最早(在这种情况下是第一个)实例到该结果集中 -
好的,我想现在我明白了。因此,您希望日期较早且 最接近您指定的日期。但是,如果文档没有这样的日期,请包括最早的日期(离现在最远的日期)?
标签: mongodb mongodb-query