如何解决MongoDb:将模型字段从字符串数组修改为引用另一个模型的 id 数组的最佳方法是什么? 第 1 步:第 2 步:第 3 步:只需执行查询第 4 步:只需执行查询第 5 步:
interests: {
type: [String],},
我的应用已经运行了一段时间。所以这意味着对于多个文档,这个字段已经填充了一个字符串数组。
为了实现某些目标,我需要创建一个带有字段 Interest
的模型 name
,然后在 Profile
中像这样引用它:
interests: [{
type: Schema.Types.ObjectId,ref: "interests",}],
字段 name
应包含 string
中现有的 Profile.interests
兴趣。
这是我认为我将遵循的方法:
- 创建
Interest
模型。 - 用现有的
name
字符串填充Profile.interests
字段。
一种。执行此操作时,将Profile.interests
替换为新创建的_ids
文档的Interest
。
湾确保Interest.name
是唯一的。
C。删除空格。 - 后端使用应用中的
interests
时,请使用populate
填充它们。
这感觉不像是一个安全的操作。所以我想听听你对此的看法。有没有更好的方法?我应该避免这样做吗?
谢谢。
解决方法
第 1 步:
- 创建兴趣模型,
- 根据兴趣架构指定所需的字段并为特定字段设置属性
- 根据您的要求在选项中指定集合名称
- 创建一个模型并在模型中指定您想要的名称
const InterestsSchema = new mongoose.Schema(
{ name: { type: String } },{ collection: "interests" }
);
const Interests = mongoose.model("Interests",InterestsSchema);
- 不要删除
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" }
])
您有示例输入:
[
{
"_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
的新字段兴趣,有执行查询的序列,
- 当
_id
(新字段)字段不存在时,查找配置文件查询和项目仅必填字段interests
和interest
,并使用{{1}迭代循环}} - trim
forEach
字符串遍历地图 - 通过创建的
interests
集合中的interests
字段查找_id
引用name
- 更新查询以添加在配置文件集合中有
interests
的interest
字段
_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
警告:
- 在生产服务器中执行之前,在本地/开发服务器中测试此步骤。
- 在执行查询之前备份您的数据库集合。
- 预测字段和架构名称,您可以将其替换为原始名称。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。