微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

MongoDb:将模型字段从字符串数组修改为引用另一个模型的 id 数组的最佳方法是什么? 第 1 步:第 2 步:第 3 步:只需执行查询第 4 步:只需执行查询第 5 步:

如何解决MongoDb:将模型字段从字符串数组修改为引用另一个模型的 id 数组的最佳方法是什么? 第 1 步:第 2 步:第 3 步:只需执行查询第 4 步:只需执行查询第 5 步:

我有一个 Profile 模型,其中包含此字段:

  interests: {
    type: [String],},

我的应用已经运行了一段时间。所以这意味着对于多个文档,这个字段已经填充了一个字符串数组。

为了实现某些目标,我需要创建一个带有字段 Interest 的模型 name,然后在 Profile 中像这样引用它:

  interests: [{
    type: Schema.Types.ObjectId,ref: "interests",}],

字段 name 应包含 string 中现有的 Profile.interests 兴趣。 这是我认为我将遵循的方法

  1. 创建 Interest 模型。
  2. 用现有的 name 字符串填充 Profile.interests 字段。
    一种。执行此操作时,将 Profile.interests 替换为新创建的 _ids 文档的 Interest
    湾确保 Interest.name 是唯一的。
    C。删除空格。
  3. 后端使用应用中的 interests 时,请使用 populate 填充它们。

这感觉不像是一个安全的操作。所以我想听听你对此的看法。有没有更好的方法?我应该避免这样做吗?
谢谢。

解决方法

第 1 步:

  1. 创建兴趣模型,
  • 根据兴趣架构指定所需的字段并为特定字段设置属性
  • 根据您的要求在选项中指定集合名称
  • 创建一个模型并在模型中指定您想要的名称
const InterestsSchema = new mongoose.Schema(
    { name: { type: String } },{ collection: "interests" }
);
const Interests = mongoose.model("Interests",InterestsSchema);
  1. 不要删除 interests 字段,而是添加新字段 interest您可以选择所需的字段),为了安全起见,只要您觉得当前更新工作正常,您就可以将其删除,更新配置文件架构,
  • 根据您的要求更新 interest 字段,现在新添加的字段为 interest
  interests: {
    type: [String]
  },interest: [{
    type: Schema.Types.ObjectId,ref: "interests"
  }],

第 2 步:

在后端使用应用中的 interests 时,使用 interest 并填充它们。


第 3 步:(只需执行查询)

为兴趣创建一个集合并存储来自个人资料集合的所有唯一兴趣字符串,因此编写聚合查询以选择唯一字符串并存储在兴趣集合中,您可以在指定后在 mongo shell 或您正在使用的任何编辑器中执行此查询您的原始个人资料集合名称,

  • $project 仅显示兴趣字段,因为我们将对其进行解构
  • $unwind 解构 interests 数组
  • $group 按兴趣并选择唯一字段,并从 interests 字符串中修剪空白
  • $project 显示 name 字段,如果您想添加所需的字段
  • $out 将创建一个新集合 interests 并使用新生成的 interests 字段写入所有 _id
db.getCollection('profile').aggregate([
  { $project: { interests: 1 } },{ $unwind: "$interests" },{ $group: { _id: { $trim: { input: "$interests" } } } },{ $project: { _id: 0,name: "$_id" } },{ $out: "interests" }
])

Playground

您有示例输入:

[
  {
    "_id": 1,"interests": ["sports","sing","read"]
  },{
    "_id": 2,"interests": ["tracking","travel"]
  }
]

执行上述查询后,interests/新集合中的输出/结果将类似于:

[
    {
      "_id": ObjectId("5a934e000102030405000000"),"name": "travel"
    },{
      "_id": ObjectId("5a934e000102030405000001"),"name": "sports"
    },{
      "_id": ObjectId("5a934e000102030405000002"),"name": "read"
    },{
      "_id": ObjectId("5a934e000102030405000003"),"name": "tracking"
    },{
      "_id": ObjectId("5a934e000102030405000004"),"name": "sing"
    }
  ]


第 4 步:(只需执行查询)

在配置文件集合中添加来自 _id 集合的引用 interests 的新字段兴趣,有执行查询的序列,

  1. _id新字段)字段不存在时,查找配置文件查询和项目仅必填字段interestsinterest,并使用{{1}迭代循环}}
  2. trim forEach 字符串遍历地图
  3. 通过创建的 interests 集合中的 interests 字段查找 _id 引用 name
  4. 更新查询以添加在配置文件集合中有 interestsinterest 字段
_id

您有示例输入:

db.getCollection('profile').find(
  { interest: { $exists: false } },{ _id: 1,interests: 1 }).forEach(function(profileDoc) {

    // TRIM INTEREST STRING
    var interests = profileDoc.interests.map(function(i){
        return i.trim();
    });

    // FIND INTERESTS IDs
    var interest = [];
    db.getCollection('interests').find(
      { name: { $in: interests } },{ _id: 1 }).forEach(function(interestDoc){
        interest.push(interestDoc._id);
    });

    // UPDATE IDS IN PROFILE DOC
    db.getCollection('profile').updateOne(
        { _id: profileDoc._id },{ $set: { interest: interest } }
    );

});

执行上述查询后,您的个人资料集合中的结果将类似于:

[
  {
    "_id": 1,"travel"]
  }
]


第 5 步:

现在您已经完成了所有步骤并且您已经新添加了 [ { "_id": 1,"read"],"interest": [ ObjectId("5a934e000102030405000001"),ObjectId("5a934e000102030405000002"),ObjectId("5a934e000102030405000004") ] },{ "_id": 2,"travel"],"interest": [ ObjectId("5a934e000102030405000000"),ObjectId("5a934e000102030405000003") ] } ] 字段 并且旧字段 interest 字段仍处于安全模式,只要确保一切正常,您就可以删除旧的 interests 字段,

  • 从所有配置文件中删除旧字段 interests 字段
interests

Playground


警告:

  • 在生产服务器中执行之前,在本地/开发服务器中测试此步骤。
  • 在执行查询之前备份您的数据库集合。
  • 预测字段和架构名称,您可以将其替换为原始名称。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。