如何在同一个 mongodb 更新中执行两个不同的数组过滤器?



在应用程序 im 构建中,我想在同一查询中执行两个更新。我想找到具有匹配task_id的子文档并更新其优先级。在同一调用中,我想递增优先级高于 3 的所有子文档。是否可以在同一查询中组合这两者?

const project = await Project.updateOne(
// first search
{ _id: req.params.project_id },
{ $set: {'tasks.$[element].priority': req.body.priority, 'tasks.$[element].state': req.body.state }},
{ arrayFilters: [{ 'element._id': req.params.task_id }] }

// second search
{ _id: req.params.project_id },
{ $inc: {'tasks.$[element].priority': 1 }},
{ arrayFilters: [{ 'element.priority': { $gt: 3 } }] }
);

您必须为arrayFilters使用不同的标识符。 您的标识符是element. 您的代码必须如下所示:

const project = await Project.updateOne(
// first search
{_id: req.params.project_id},
{
$set: {'tasks.$[elementA].priority': req.body.priority, 'tasks.$[elementA].state': req.body.state},
$inc: {'tasks.$[elementB].priority': 1}
},
{
arrayFilters: [
{'elementA._id': req.params.task_id},
{'elementB.priority': {$gt: 3}}
]
},
)

注意:标识符必须以小写字母开头,并且仅包含字母数字字符(来自MongoDB官方网站,链接(

您可以使用两个arrayFilters同时执行此操作。请考虑以下事项:

当前收藏:

{
"_id" : 1,
"array1" : [
{
"k1" : 1,
"v1" : 100
},
{
"k1" : 2,
"v1" : 15
},
{
"k1" : 1,
"v1" : 100
}
],
"array2" : [
{
"k2" : 1,
"v2" : 10
},
{
"k2" : 2,
"v2" : 1000
},
{
"k2" : 1,
"v2" : 20
}
]
}

查询:

db.collection.update(
{ _id: 1 },
{ $set:
{
'array1.$[elem1].v1': 100,
'array2.$[elem2].v2': 1000
}
},
{ arrayFilters: 
[
{'elem1.k1':1},
{'elem2.k2': 2}
],
multi: true
}
)

如您所见,我在arrayFilters选项的帮助下创建了两个过滤的位置运算符(elem1elem2(。我可以使用它来执行更新。

结果:

{
"_id" : 1,
"array1" : [
{
"k1" : 1,
"v1" : 100
},
{
"k1" : 2,
"v1" : 15
},
{
"k1" : 1,
"v1" : 100
}
],
"array2" : [
{
"k2" : 1,
"v2" : 10
},
{
"k2" : 2,
"v2" : 1000
},
{
"k2" : 1,
"v2" : 20
}
]
}

您可以在上面更新的集合中看到,array1中的k1字段具有值1,它的v1字段已更新为 100,array2中的k2字段具有值2,它的v2字段已更新为 100。

因此,在您的情况下,您需要执行以下操作:

updateOne(
{ _id: req.params.project_id},
{
$set: {
'tasks.$[elem1].priority': req.body.priority,
'tasks.$[elem1].state': req.body.state
},
$inc: {
'tasks.$[elem2].priority': 1
}
},
{
arrayFilters: [
{ 'elem1._id': req.params.task_id },
{ 'elem2.priority':
{ $gt: 3 }
}
]
}
)

我希望它对您有所帮助。

最新更新