我的数据如下所示:
[
{
_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 个事件。
谢谢=)
最佳答案
那么你可以使用$where
运算符(operator)。但请记住,它会执行 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" } }
])
关于javascript - 从对象数组中获取最后一个匹配的键来检查值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32651664/