从对象数组中获取最后一个匹配键以检查值

时间:2015-09-18 12:07:21

标签: javascript arrays mongodb mongodb-query

我的数据如下:

[
 {
  _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个事件。

谢谢=)

1 个答案:

答案 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" } }
])