首页 > 解决方案 > 如何在mongodb中编辑多个嵌入文档

问题描述

我想查找与以下查询匹配的对象,然后将 events 属性设置为空数组(如果匹配)。目前我使用的查询只会更新每个文档中的第一个嵌入对象,但我需要它来检查每个文档中的每个嵌入对象。这是查询,有谁知道我怎样才能做到这一点?

const date_check = moment().subtract(10, 'minutes').format('X')

await Accumulator.updateMany(
    { 'data.lastUpdate': { $lt: date_check } },
    { 
        $set: {
            'data.$.events': []
        }
    }
)

文件看起来像这样...

{
    bookmaker: 'Bet365',
    sport: 'Football',
    data: [
        {
            lastUpdate: '2372273273',
            events: [
                ... // some event objects
            ]
        },
        {
            lastUpdate: '2372234421',
            events: [
                ... // some event objects
            ]
        },
        {
            lastUpdate: '2375343461',
            events: [
                ... // some event objects
            ]
        }
    ]
}

标签: mongodbmongodb-query

解决方案


我认为最好将架构更改lastUpdate为性能数字,并避免错误,检查$toInt,您可以使用类似于第二个查询的代码来完成。

询问

  • 数组过滤器方式
  • 用 date_check 替换“2372273273”
  • 过滤以保留文档
  • 使用 arrayFilters 仅对通过过滤器的成员文档进行更改

测试代码在这里

db.collection.update({
  "data.lastUpdate": {
    "$lt": "2372273273"
  }
},
{
  $set: {
    "data.$[data].events": []
  }
},
{
  "arrayFilters": [
    {
      "data.lastUpdate": {
        "$lt": "2372273273"
      }
    }
  ]
})

询问

  • 替代管道更新方式$map
  • 将“2372273273”替换为date_check
  • 过滤以查找文档
  • 仅更新过滤器为真的成员

管道更新需要 MongoDB >= 4.2

测试代码在这里

db.collection.update({
  "data.lastUpdate": {
    "$lt": "2372273273"
  }
},
[
  {
    "$set": {
      "data": {
        "$map": {
          "input": "$data",
          "in": {
            "$cond": [
              {
                "$lt": [
                  "$$this.lastUpdate",
                  "2372273273"
                ]
              },
              {
                "$mergeObjects": [
                  "$$this",
                  {
                    "events": []
                  }
                ]
              },
              "$$this"
            ]
          }
        }
      }
    }
  }
])

推荐阅读