【问题标题】:how to get data in mongoose where last element in array?如何在 mongoose 中获取数组中最后一个元素的数据?
【发布时间】:2019-01-03 00:23:47
【问题描述】:

如何在 mongoose 中获取数组中最后一个元素的数据? 我的数据是这样的:

[
    {
        "_id" : ObjectId("5b56eb3deb869312d85a8e69"),
        "transactionStatus" : [ 
            {
                "status" : "pending",
                "createdAt" : ISODate("2018-07-24T09:02:53.347Z")
            }, 
            {
                "status" : "process",
                "createdAt" : ISODate("2018-07-24T09:02:53.347Z")
            }
        ]
    },
    {
        "_id" : ObjectId("5b56eb3deb869312d8589765"),
        "transactionStatus" : [ 
            {
                "status" : "pending",
                "createdAt" : ISODate("2018-07-24T09:02:53.347Z")
            },
            {
                "status" : "process",
                "createdAt" : ISODate("2018-07-24T09:03:30.347Z")
            },
            {
                "status" : "done",
                "createdAt" : ISODate("2018-07-24T09:04:22.347Z")
            }
        ]
    }
]

而且,我想在最后一个对象transactionStatus.status = process 上方获取数据,所以结果应该是:

{
    "_id" : ObjectId("5b56eb3deb869312d85a8e69"),
    "transactionStatus" : [ 
        {
            "status" : "pending",
            "createdAt" : ISODate("2018-07-24T09:02:53.347Z")
        }, 
        {
            "status" : "process",
            "createdAt" : ISODate("2018-07-24T09:02:53.347Z")
        }
    ]
}

如何用猫鼬做到这一点?

【问题讨论】:

标签: node.js mongodb mongoose


【解决方案1】:

您可以在 match 中使用 $expr (MongoDB 3.6+)。使用$let$arrayElemAt 传递-1 作为第二个参数,您可以获得最后一个元素作为临时变量,然后您可以比较这些值:

db.col.aggregate([
    {
        $match: {
            $expr: {
                $let: {
                    vars: { last: { $arrayElemAt: [ "$transactionStatus", -1 ] } },
                    in: { $eq: [ "$$last.status", "process" ] } 
                }
            }
        }
    }
])

对于较低版本的 MongoDB,使用 $addFields$match 可以获得相同的结果。您可以添加 $project 然后删除该临时字段:

db.col.aggregate([
    {
        $addFields: {
            last: { $arrayElemAt: [ "$transactionStatus", -1 ] }
        }
    },
    {
        $match: { "last.status": "process" }
    },
    {
        $project: { last: 0 }
    }
])

【讨论】:

  • 感谢您的回答,$addFields 效果很好:)
  • 这将花费大量时间来记录数千条记录。使用我的解决方案和 find() 方法,您的性能将得到提高
  • 您正在重新排序transactionStatus,这远远超出了此问题的范围,并且没有任何信息表明您可以这样做。我认为这里的顺序很重要
  • 我说的是效率,当存在数千个文档时,它会比 find() 方法花费很多时间
【解决方案2】:

//总是使用 $position 运算符更新位置 0 的新状态

db.update({
    "_id": ObjectId("5b56eb3deb869312d85a8e69")
},
    {
        "$push": {
            "transactionStatus": {
                "$each": [
                    {
                        "status": "process",
                        "createdAt": ISODate("2018-07-24T09:02:53.347Z")
                    }
                ],
                "$position": 0
            }
        }
    }
)

//检查第一个元素的查询status is process

db.find(
    {
        "transactionStatus.0.status": "process"
    }
)

参考$position$each

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-04
    • 2020-07-03
    • 2012-01-28
    • 2012-09-27
    • 1970-01-01
    • 2022-06-28
    • 1970-01-01
    相关资源
    最近更新 更多