【问题标题】:Get the last matching key from an array of objects to check value从对象数组中获取最后一个匹配键以检查值
【发布时间】:2015-09-18 12:07:20
【问题描述】:

我的数据如下所示:

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

谢谢你=)

【问题讨论】:

  • 我不确定预期的结果是什么。请使用edit link 显示预期结果。

标签: javascript arrays mongodb mongodb-query


【解决方案1】:

您可以使用$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" } }
])

【讨论】:

  • 没有索引会很糟糕。如果我要询问“狗”,看起来使用您的方法它不会返回文档号 2,即使文档 2 的最后选择的宠物是一只狗。
  • @Drew 编辑了我的答案。但是你需要在这里使用$where
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-06
  • 2013-12-31
  • 2021-07-15
  • 1970-01-01
  • 2021-12-06
相关资源
最近更新 更多