首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MongoDB -用子文档更新/替换数组字段以嵌入其内容

MongoDB -用子文档更新/替换数组字段以嵌入其内容
EN

Stack Overflow用户
提问于 2021-10-12 13:08:45
回答 1查看 658关注 0票数 1

描述

在重新处理数据构造之后,我希望从不同的集合中嵌入一个文档(或其中的一部分)。请注意event.tags[]。目前,只有他们的字符串_ids (作为普通字符串,没有ObjectId!)存储,但我想迁移他们的内容,如{tags.name, tags._id}。我想用tag-documents的内容更新/替换原始的-documents。

数据

集合“事件”

代码语言:javascript
复制
db.events.insertMany([{
    "_id" : ObjectId("5f6c5b0594911c0b7231643d"),
    "title" : "Test Event",
    "tags" : [ 
        "5fd8cef2368c625a9d7516cb"
    ]
},
{
    "_id" : ObjectId("5fb3896afc13ae2ed1000000"),
    "title" : "Test Event 2",
    "tags" : [ 
        "5fd8cef2368c625a9d7516cb", 
        "5fd8cfb04a4a6063ab4ca4bf", 
        "5fd8cfb04a4a6063ab4ca4c0"
    ]
}
]);

集合“标签”

代码语言:javascript
复制
db.tags.insertMany([{
    "_id" : ObjectId("5fd8cef2368c625a9d7516cb"),
    "name" : "Foo",
    "createdAt" : ISODate("2020-12-15T14:57:54.096Z")
},
{
    "_id" : ObjectId("5fd8cfb04a4a6063ab4ca4bf"),
    "name" : "Bar",
    "createdBy" : "embo@team-con.de",
    "createdAt" : ISODate("2020-12-16T14:57:54.096Z")
},
{
    "_id" : ObjectId("5fd8cfb04a4a6063ab4ca4c0"),
    "name" : "Foobar",
    "createdAt" : ISODate("2020-12-17T14:57:54.096Z")
}
]);

预期结果

我希望实现嵌入一些/所有的集合“标记”字段,这些字段与"events.tags“<-> "tags._id”匹配,作为嵌入/嵌套文档的数组。这将是迁移脚本的一部分,通过mongoDB API >4.0通过node.js运行。

目标:我希望将Strings数组(参见集合事件)替换为不同集合的特定信息(请参阅集合标记),并将其保存回集合事件(迁移过程)。因此,我假设,我必须从tag集合中获取/查找一些东西,并需要一种机制将字符串(events.tagsx)替换为复杂对象({tags._id,tags.name})。

代码语言:javascript
复制
{
    "_id" : ObjectId("5f6c5b0594911c0b7231643d"),
    "title" : "Test Event",
    "tags" : [{
        "_id" : ObjectId("5fd8cef2368c625a9d7516cb"),
        "name" : "Foo",
        "createdAt" : ISODate("2020-12-15T14:57:54.096Z")
    }]
},
{
    "_id" : ObjectId("5fb3896afc13ae2ed1000000"),
    "title" : "Test Event 2",
    "tags" : [{
        "_id" : ObjectId("5fd8cef2368c625a9d7516cb"),
        "name" : "Foo"
    },
    {
        "_id" : ObjectId("5fd8cfb04a4a6063ab4ca4bf"),
        "name" : "Bar"
    },
    {
        "_id" : ObjectId("5fd8cfb04a4a6063ab4ca4c0"),
        "name" : "Foobar"
    }]
}

婴儿步

我尝试使用聚合管道,并在最后一步通过匹配和查找它们的内容到replaceWith开始。我不太熟悉通过聚合管道来解决这个问题。

代码语言:javascript
复制
db.getCollection('events').aggregate([
    { $match: { tags: { "$exists" : true } } },
    {
       $lookup:
         {
           from: "tags",
           localField: "tags",
           foreignField: "_id",
           as: "taags"
         }
    },
    ])
EN

回答 1

Stack Overflow用户

发布于 2021-10-12 13:24:38

您可以使用objectId操作符将标记的id从string转换为$toObjectId,在$lookup阶段之前,

  • $addFields添加新字段和更新/格式化现有字段
  • $map迭代tags数组的循环
  • $toObjectId将字符串objectId转换为objectId类型
  • tags阶段的as属性中放置名称$lookup
代码语言:javascript
复制
  // $match stage here
  {
    $addFields: {
      tags: {
        $map: {
          input: "$tags",
          in: { $toObjectId: "$$this" }
        }
      }
    }
  },
  {
    $lookup: {
      from: "tags",
      localField: "tags",
      foreignField: "_id",
      as: "tags"
    }
  }

游乐场

  • 使用聚合查询,您不能更新当前事件集合,但可以使用$out阶段生成新集合,MongoDB 4.4支持
  • 把这个阶段放在最后阶段
代码语言:javascript
复制
  { $out: "updated_events" }

第二个选择是准备一个脚本来完成手动处理,

  1. 从事件集合中查找所有记录
  2. 循环事件集合的结果。
  3. 内部循环通过在标记集合中传递标记in来执行查找查询
  4. 通过替换来自3)步骤的结果,内部循环更新事件集合
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69541145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档