【问题标题】:Update created a conflict on multiple arrayFilters更新在多个 arrayFilters 上创建了冲突
【发布时间】:2020-09-11 06:32:42
【问题描述】:

我正在尝试以类似的方式增加两个不同的数组。在不增加 elementC 的情况下,一切正常。如果我添加 elementC 并在其上使用 arrayFilter,则会收到错误消息:更新在 tasks.priority 处创建了冲突。我认为这与迭代同一个对象有关,但为什么以及如何解决这个问题?我的代码:

        const project = await Project.updateOne(
        {_id: req.params.project_id},
        {
            $set: {'tasks.$[elementA].priority': req.body.new_state.priority, 'tasks.$[elementA].state': req.body.new_state.state},
            $inc: {'tasks.$[elementB].priority': 1, 'tasks.$[elementC].priority': 2},
        },
        {
            arrayFilters: [
                {'elementA._id': req.params.task_id},
                {'elementB.state': req.body.old_state.state, 'elementB.priority': {$gt: req.body.old_state.priority}},
                {'elementC.state': req.body.new_state.state, 'elementC.priority': {$gt: req.body.new_state.priority}}
            ]
        }
    );
    res.json(project);

架构:

const task_schema = new mongoose.Schema({
description: {
    type: String
},
state: {
    type: String
},
priority: {
    type: Number
}
const project_schema = new mongoose.Schema({
name: {
    type: String
},
description: {
    type: String
},
non_public: {
    type: Boolean
},
tasks: [task_schema]

例子:

{ "_id" : ObjectId("5ec274b50877c671ccf9b6c7"), 
"name" : "first project", 
"description" : "lorem ipsum",
"non_public" : true, 
"tasks" : [ { "_id" : ObjectId("5ec27674e0db347307902ba9"), 
                "description" : "Lorem", 
                "state" : "TODO", 
                "priority" : 0 }, 
            { "_id" : ObjectId("5ec27686e0db347307902baa"), 
                "description" : "Ipsum", 
                "state" : "TODO", 
                "priority" : 1 }, 
            { "_id" : ObjectId("5ec27686e0db347307902baa"), 
                "description" : "Dolor", 
                "state" : "TODO", 
                "priority" : 2 }, 
            { "_id" : ObjectId("5ec293db751ae07a8520a703"), 
                "description" : "Sit", 
                "state" : "DOING", 
                "priority" : 0 }, 
            { "_id" : ObjectId("5ec29591ad84927c7788116d"), 
                "description" : "Amet",
                "state" : "DONE",
                "priority" : 0 },
]}

【问题讨论】:

  • 您能提供一些示例文件吗?您的预期输出是什么?
  • 我有一个任务数组,每个任务都有一个优先级和一个状态。当我将任务从一个状态移动到另一个状态时。在它被删除的列表中,我需要通过减少它之后的所有其他任务来更新列表。在它被添加到的列表中,我需要增加它之后的所有任务。因此,我需要根据它们所处的状态对它们进行两次过滤,从而遍历同一个数组。
  • 提供req.params.task_idreq.body.old_state.statereq.body.old_state.priorityreq.body.new_state.statereq.body.new_state.priority各自的值。
  • old_state.state 和 new_state.state 是“TODO”、“DOING”或“DONE”。 old_state.priority 和 new_state.priority 是一个整数。 old_state.priority 是它曾经在列表中的位置,new_state.priority 是它所在的新位置

标签: arrays node.js mongodb mongoose mongodb-query


【解决方案1】:

发生这种情况是因为您试图在同一个数组字段上应用两个不同的过滤器并对其进行更新。因此,Mongo 引擎对应用哪个过滤器感到困惑。

提示:您的arayFilters 必须是互斥的。

【讨论】:

  • 那么我可以在一个查询中执行此操作吗?因为我不确定如何使我的 arrayfilter 互斥。
  • 您能否提供您的示例数据(不是架构)以及相应的输出,如果可能的话,我们可以解决这个问题吗?
  • 样本数据是什么意思?我在您的其他评论下方添加了一个解释(但我不确定它是否清楚)
  • 样本数据输入意味着您的集合中很少有文档保持原样或减少,无论哪种方式您感觉更好。
  • 我认为,通过_id 过滤数组是最好的。
猜你喜欢
  • 2019-09-19
  • 2020-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-01
  • 2020-07-09
  • 1970-01-01
  • 2017-03-22
相关资源
最近更新 更多