【问题标题】:arrayFilters in mongodbMongoDB中的arrayFilters
【发布时间】:2018-12-21 19:41:15
【问题描述】:

我有以下架构。

{
   posts: [
          {
             _id: '5ayuunbdsyuuuyut778'
             replies: [{
                 _id: "67hfudj7e9whduu888",
                 text: "something"
             }]
          }
      ]
}

我想更新特定回复的文本。 我正在使用猫鼬。

我已经写了如下查询

Post.findOneAndUpdate(
   {'posts.replies._id': _id}, 
   {$set: {'posts.$[post].replies.$[reply].text': "something1"}},
   { arrayFilters: [{'post._id': postId}, { 'reply._id': _id }]}
 )

此查询未更新文档。

我错过了什么吗?我是否需要使用 ObjectId 投射 id

【问题讨论】:

  • 您是否遇到任何错误?因为上面的查询对我有用......可能你的postId_id 不正确......我试过这个User.findOneAndUpdate( {'posts.replies._id': "67hfudj7e9whduu888"}, {$set: {'posts.$[post].replies.$[reply].text': "something12"}}, { arrayFilters: [{'post._id': "5ayuunbdsyuuuyut778"}, { 'reply._id': "67hfudj7e9whduu888" }]} )
  • 你在 mongo 上使用哪个版本?
  • @Anthony Winslet。我没有收到任何错误。当我使用 {new:true} 时,我得到的文档没有更新
  • 他们是否在数据库中更新?以及您如何使用multi: true
  • 我没用过multi: true。我需要吗?

标签: mongodb mongoose mongodb-query


【解决方案1】:

您需要使用new: true 来获取更新后的值并将 id 转换为 mongoose objectId 以使其工作

Post.findOneAndUpdate(
   { 'posts.replies._id': _id }, 
   { $set: { 'posts.$[post].replies.$[reply].text': "something1" } },
   { arrayFilters: [{ 'post._id': postId }, { 'reply._id': _id }], new: true }
)

【讨论】:

  • 数据库本身没有更新。
  • 我观察到的是,它在 mongo shell(3.6) 中的更新。但不是通过猫鼬(5.2)。
  • 在你的 mongo shell db.adminCommand( { setFeatureCompatibilityVersion: "3.6" } ) 中输入这个命令然后再试一次
  • 现在我确定您的 id 可能不正确...将 id 硬编码并尝试
  • 嘿,谢谢您的帮助。我忘记在猫鼬中投射对象 ID。
【解决方案2】:

由于arrayFilters是与mongodb相关的东西,所以你需要在mongoose中用ObjectId转换id

Post.findOneAndUpdate(
   { 'posts.replies._id': _id }, 
   { $set: { 'posts.$[post].replies.$[reply].text': "something1" } },
   { arrayFilters: [{ 'post._id': postId }, { 'reply._id': _id }]}
)

必须改为

Post.findOneAndUpdate(
   { 'posts.replies._id': _id }, 
   { $set: { 'posts.$[post].replies.$[reply].text': "something1" } },
   { arrayFilters: [{ 'post._id': ObjectId(postId) }, { 'reply._id': ObjectId(_id)}]}
)

【讨论】:

    【解决方案3】:

    arrayFilters 不接受字符串化的对象 ID,与 mongoose 中的典型过滤器(它会自动为您转换对象 ID)相反,当将对象 ID 作为过滤器传递给 arrayFilters 时,您必须手动转换对象 ID。

    Post.findOneAndUpdate(
       { 'posts.replies._id': _id }, 
       { $set: { 'posts.$[post].replies.$[reply].text': "something1" } },
       { arrayFilters: [{ 'post._id':new ObjectId(postId) }, { 'reply._id': new ObjectId(_id) }], new: true }
    
    

    这会起作用,查看 cmets here 了解更多详情

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-24
      • 1970-01-01
      • 2018-04-23
      • 1970-01-01
      • 1970-01-01
      • 2020-07-09
      相关资源
      最近更新 更多