Mongodb 如何使用$arrayFilters更新Mongoose中的数组变量值
通过使用ArrayFilter,我需要使用数组中的动态值更新集合 也就是说,我需要根据ArrayFilter中提供的数组,使用$inc中的数组值进行更新 示例文档Mongodb 如何使用$arrayFilters更新Mongoose中的数组变量值,mongodb,mongoose,aggregation-framework,Mongodb,Mongoose,Aggregation Framework,通过使用ArrayFilter,我需要使用数组中的动态值更新集合 也就是说,我需要根据ArrayFilter中提供的数组,使用$inc中的数组值进行更新 示例文档 { _id:'shopId', products:[ _id:'productId', buys:[ { _id:'abc', quantity:0 }, { _id:'def', quantity:2 } ] ] }
{
_id:'shopId',
products:[
_id:'productId',
buys:[
{
_id:'abc',
quantity:0
},
{
_id:'def',
quantity:2
}
]
]
}
{
_id:'shopId',
products:[
_id:'productId',
buys:[
{
_id:'abc',
quantity:1 //got incremented by 1
},
{
_id:'def',
quantity:5 //got incremented by 3
}
]
]
}
预期结果
{
_id:'shopId',
products:[
_id:'productId',
buys:[
{
_id:'abc',
quantity:0
},
{
_id:'def',
quantity:2
}
]
]
}
{
_id:'shopId',
products:[
_id:'productId',
buys:[
{
_id:'abc',
quantity:1 //got incremented by 1
},
{
_id:'def',
quantity:5 //got incremented by 3
}
]
]
}
考虑下面的查询,了解我尝试过的内容
Shop.findOneAndUpdate(
{ "_id": ObjectId(shopId)},
{ $inc: { "products.$[p].buys.$[n].quantity": { $each: [1,3] } }},
{ arrayFilters: [{ "p._id": ObjectId('productId') }, { "n._id": {$in: ["abc", "def"]} }]
)
我需要将n._id:'abc'增加1,n._id:'def'增加3,并将其放入一个数组中(在$inc中的每个$中)
现在,这不起作用,并给出了一个错误。我试着用[1,3]中的$in替换$each:[1,3],但仍然不起作用
如何执行此操作?从MongoDB v4.2开始,不可能在一次操作中使用
阵列过滤器执行此操作
我建议单独更新
//解决方案在node.js中实现,因为您已经标记了mongoose
//准备要在多个更新中使用的条件数据结构
const updateCondition={“abc”:1,“def”:3}
const updates=Object.entries(updateCondition.map)([key,value])=>
Shop.findOneAndUpdate(
{u id:ObjectId(shopId)},
{$inc:{“products.$[p].buys.$[n].quantity:value},//值将在[1,3]中迭代
{arrayFilters:[{“p.\u id”:ObjectId(productId)},{“n.\u id”:key}}]//key将通过[“abc”,“def”进行迭代
).exec()
)
等待承诺。所有(更新)。然后([resultA,resultB])=>{
//结果是“abc”更新的结果
//resultB是“def”更新的结果
}).catch(错误=>{
//处理错误
})
如果您提供一个示例文档和预期结果,将有助于更好地理解。@thammada我已更新了我的问题,将示例文档和预期结果包括在内。我认为应该作为两个单独的操作运行,您是否需要单独运行它们?@thammada是的,我不希望它们分开。。我只需要一次手术就可以了。由于可以使用相同的值进行更新,我需要一种方法在该数组中使用不同的值进行更新,即[1,3]
您所说的“因为可以使用相同的值进行更新”是什么意思?我仍然认为可以将它们分为两个操作,一个匹配“abc”
,另一个匹配“def”
。如果你想在同一个操作中使用$map
更新管道,我认为上面的代码要复杂得多,我如何使用.exec()。然后(()=>.catch(()=>)
?我已经更新了代码,你也可以单独处理。然后()在.exec()。然后()
工作得很好