Javascript 匹配、更新并返回数组中的最后一个子文档
我想匹配数组中的子文档并更新最后一个元素。此查询仅更新changeId为0的文档,尽管我在数组中得到了id为2的文档Javascript 匹配、更新并返回数组中的最后一个子文档,javascript,mongodb,Javascript,Mongodb,我想匹配数组中的子文档并更新最后一个元素。此查询仅更新changeId为0的文档,尽管我在数组中得到了id为2的文档 const oldDocument = await schemas.Collection.findOneAndUpdate( { "_id": new ObjectId(_id), "manualChanges.id":
const oldDocument = await schemas.Collection.findOneAndUpdate(
{
"_id": new ObjectId(_id),
"manualChanges.id": update.id,
"manualChanges.discarded": false
},
{
$set: {
"manualChanges.$.discarded": true
}
},
{
sort: {'manualChanges.changeId': -1},
projection: {"manualChanges.$": 1}
}
);
console.log(oldDocument);
之后,我想返回一个更新过的文档,很遗憾,它也只能在没有排序的情况下工作。来自文档:
位置$operator充当与查询文档匹配的第一个元素的占位符,并且
位置运算符始终与数组中的第一个文档匹配,因此我假设您尝试向下排序。然而,尽管您认为这种方法可以工作,但它不会像游标操作符那样工作,这意味着它只在匹配文档时生效。在即将推出的4.4版本计划引入自定义函数之前,实际上不可能在Mongo中对嵌套数组进行排序
那你能做什么呢?如果您使用的是他们推出的Mongo 4.2+版本,它允许我们在更新中使用聚合表达式,从而为我们提供了更强大的功能,下面是使用它可以完成的示例:
db.test.updateOne(
{
"_id": new ObjectId(_id),
},
[
{
$set: {
filtered: {
$filter: {
input: "$manualChanges",
as: "change",
cond: {$ne: ["$$change.discarded", true]}
}
}
}
},
{
$set: {
last_id: {
$max: "$filtered.id",
}
}
},
{
$set: {
manualChanges: {
$map: {
input: "$manualChanges",
as: "change",
in: {
$mergeObjects: [
"$$change",
{
discarded: {$cond: [{$eq: ["$$change.id", "$last_id"]}, true, "$$change.discarded"]}
}
]
}
}
}
}
},
{
$unset: ["last_id", "filtered"]
}
])
如果您使用的是较低版本的Mongo,那么您必须将其分为两个查询,首先查找子文档id
,然后才能对其进行更新。db.yourcollection.find({yoursubdocumentinarray:“63109”},{elementtoupdate:{$elemMatch:{update:this}}})。最后一部分对我来说不是完全清楚的回报。