【问题标题】:MongoDB: add object to subarray if not existsMongoDB:如果不存在则将对象添加到子数组
【发布时间】:2021-08-30 21:03:20
【问题描述】:

我在这里搜索了很多问题和网络上的其他文章,但它们似乎都描述了与我手头的不同的案例。

我有User 架构:

{
    username: { type: String },
    lessons: [
        {
            lesson: { type: String },
            result: { type: String }
        }
    ]
}

我想将新元素添加到lessons 或跳过,如果已经有一个具有相同值的元素,因此我使用addToSet:

const dbUser = await User.findOne({ username })
dbUser.lessons.addToSet({ lesson, result: JSON.stringify(result) })
await dbUser.save()

但是它使似乎重复的内容:

// first run
[
  {
    _id: 60c80418f2bcfe5fb8f501c1,
    lesson: '60c79d81cf1f57221c05fdac',
    result: '{"correct":2,"total":2}'
  }
]

// second run
[
  {
    _id: 60c80418f2bcfe5fb8f501c1,
    lesson: '60c79d81cf1f57221c05fdac',
    result: '{"correct":2,"total":2}'
  },
  {
    _id: 60c80470f2bcfe5fb8f501c2,
    lesson: '60c79d81cf1f57221c05fdac',
    result: '{"correct":2,"total":2}'
  }
]

此时我看到它添加了_id,因此将它们视为不同的条目(虽然它们是相同的)。

我的错误是什么,我应该怎么做才能解决它?我可以更改 lessons 结构或更改查询 - 任何更容易实现的。

【问题讨论】:

  • 您可以在更新(保存)之前在查询中检查课程和结果值(以及您已经过滤的用户名)。
  • @prasad_ 所以你的建议只是if (await User.findOne({ username }, { lesson })) 条件(让我们忽略result)?
  • 类似这样的:mongoose “Find” with multiple conditions。例如,课程条件可以编码为"lessons.lesson": "math"。

标签: node.js mongodb mongoose mongodb-query


【解决方案1】:

您可以创建子文档避免_id。只需将_id: false 添加到您的子文档声明中即可。

const userSchema = new Schema({
  username: { type: String },
  lessons: [
    {
      _id: false,
      lesson: { type: String },
      result: { type: String }
    }
  ]
});

这将阻止在您的子文档中创建 _id 字段,您可以向 lesson 添加一个新元素,或者像您一样使用 addToSet 运算符跳过它。

【讨论】:

  • 现在可以使用了。如果没有_id,它最终会正确比较它们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-01
  • 1970-01-01
  • 2014-05-15
  • 1970-01-01
  • 2017-05-10
  • 1970-01-01
  • 2019-01-18
相关资源
最近更新 更多