我在数据库中有一个看起来像的对象:
{
'name': 'foo',
'table':
[
{
'date' : ISODate("2000-01-13T23:00:00Z")
},
{
'date' : ISODate("2000-01-14T23:00:00Z")
},
{
'date' : ISODate("2000-01-15T23:00:00Z")
},
{
'date' : ISODate("2000-01-16T23:00:00Z")
},
{
'date' : ISODate("2000-01-17T23:00:00Z")
}
]
}
我希望查询以下结果:
{
'name': 'foo',
'table':
[
{
'date' : ISODate("2000-01-15T23:00:00Z")
},
{
'date' : ISODate("2000-01-16T23:00:00Z")
}
]
}
所以我正在寻找一种方法来提取两个不同日期之间的孩子。
到目前为止,我已尝试过以下内容:
db.stock.find({'table.date' : {$gte : '2000-01-15', $lt : '2000-01-17'}});
db.stock.find({'table.date' : {$gte : new Date('2000-01-15'), $lt : new Date('2000-01-17')}});
db.stock.find({'table.date' : {$gte : '2000-01-15T23:00:00Z', $lt : '2000-01-17T23:00:00Z'}});
db.stock.find({'table.date' : {$gte : ISODate('2000-01-15T23:00:00Z'), $lt : ISODate('2000-01-17T23:00:00Z')}});
db.stock.find({'table.date' : {$gte : new Date('2000-01-15T23:00:00Z'), $lt : new Date('2000-01-17T23:00:00Z')}});
这可能吗?如果是这样,怎么解决?
答案 0 :(得分:1)
.find()
无法自行“过滤”数组的返回元素。您可以使用匹配条件的positional $
运算符仅“投射”一个匹配元素(请参阅文档)。
这里的原因是这里的查询不匹配数组元素,而是文档 “包含”匹配的数组元件。
但要将元素“过滤”为您想要的元素,您需要使用aggregate:
db.stock.aggregate([
// Matching first is a good idea to filter the documents that contain
// the matching elements
{ "$match": {
"table.date": {
"$gte": new Date("2000-01-15"),
"$lt": new Date("2000-01-17")
}
}},
// Unwind the array, this "de-normalizes"
{ "$unwind": "$table" },
// Now use the match to actually "filter" results in the array
{ "$match": {
"table.date": {
"$gte": new Date("2000-01-15"),
"$lt": new Date("2000-01-17")
}
}},
// Group the results back by a "key", probably the document
{ "$group": {
"_id": "$_id",
"table": { "$push": "$table" }
}}
])
另外值得注意的是,您需要将日期用作实际日期类型而非“字符串”。在其他语言实现中也是如此,其中本机日期类型将作为BSON日期发送到MongoDB服务器,在那里可以在内部进行比较。
有关使用此类查询返回原始文档表单的详细信息,请参阅here。