我的数据如下:
[
{
_id:1
events: [
{selectedPet: 'cat', time: '2015-09-18T12:00:00.000Z'},
{selectedPet: 'dog', time: '2015-09-18T12:00:01.000Z'},
{colourHat: 'green', time: '2015-09-18T12:00:01.200Z'},
{selectedPet: 'bird', time: '2015-09-18T12:00:02.000Z'},
]
},
{
_id:2
events: [
{selectedPet: 'bird', time: '2015-09-18T12:00:00.000Z'},
{selectedPet: 'cat', time: '2015-09-18T12:00:01.000Z'},
{selectedPet: 'dog', time: '2015-09-18T12:00:02.000Z'},
{favouriteAnimal: 'bird', time: '2015-09-18T12:00:04.000Z'},
]
}
]
如何查询最后选择的宠物(数组中的最后一个,或按时间顺序排列 - 数组是按时间顺序排列的)?
这样做的:
db.getCollection('events').find({
'events.selectedPet': 'bird'
});
将返回两个文件,但选择最后一个选择宠物是鸟的文件的预期输出将是:
[
{
_id:1
events: [
{selectedPet: 'cat', time: '2015-09-18T12:00:00.000Z'},
{selectedPet: 'dog', time: '2015-09-18T12:00:01.000Z'},
{colourHat: 'green', time: '2015-09-18T12:00:01.200Z'},
{selectedPet: 'bird', time: '2015-09-18T12:00:02.000Z'},
]
}
]
这是示例数据。我的真实数据集是成千上万的文档,每个文档包含大约500个事件。
谢谢=)
答案 0 :(得分:0)
您可以使用$where
运算符。但请记住,它会进行JavaScript评估并cannot take advantage of indexes。
db.collection.find({ "$where": function() {
for (var i = this.events.length - 1; i >= 0; i--) {
if (this.events[i]["selectedPet"]) {
return this.events[i]["selectedPet"] === "bird";
}
}}
})
从即将发布的版本中,您可以使用聚合和$slice
运算符。
db.collection.aggregate([
{
"$project": {
"e": { "$slice": [
{ "$setDifference": [
{ "$map": {
"input": "$events",
"as": "ev",
"in": { "$ifNull": ["$$ev.selectedPet", false]}
}},
[false]]
},
-1
]},
"events": 1
}},
{ "$match": { "e": "bird" } }
])