我是MongoDB的新手,所以这可能是一个基本问题(希望如此)。我目前有1000万条记录,在mongodb集合中加载了410个字段,如下所示:
{
"_id" : ObjectId("........"),
"AddressID" : 123455,
"IndividualId" : 1,
"personfirstname" : "FirstName",
"personmiddleinitial" : "M",
"personlastname" : "LastName",
"etc": "....."
}
我需要将所有这些数据包装到嵌入式文档中,如下所示:
{
"_id" : ObjectId("........"),
"data" : {
"AddressID" : 123455,
"IndividualId" : 1,
"personfirstname" : "FirstName",
"personmiddleinitial" : "M",
"personlastname" : "LastName",
"etc": "....."
}
我不一定需要就地更新这些数据,但这样会很好。如果我需要以某种方式指定新格式导出此数据,然后重新导入新的,更新的数据,这很好。通过MongoDB shell执行此操作将是理想的选择。
答案 0 :(得分:0)
您可以使用以下
在shell中执行此操作db.test.find().forEach(function(doc){
doc = { _id: doc._id, data: doc };
delete doc.data._id;
db.test.save(doc);
});
例如,如果我们插入以下文件:
> db.test.insertMany([
... {
... _id: ObjectId("5a91af8908e17c5997e03b7e"),
... field1: false,
... field2: 0,
... field3: "No"
... },
... {
... _id: ObjectId("5a91afbc08e17c5997e03b7f"),
... field1: true,
... field2: 1,
... field3: "Yes"
... }])
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5a91af8908e17c5997e03b7e"),
ObjectId("5a91afbc08e17c5997e03b7f")
]
}
然后运行:
db.test.find().forEach(function(doc){
doc = { _id: doc._id, data: doc };
delete doc.data._id;
db.test.save(doc);
});
我们的文件现在看起来像这样:
> db.test.find().pretty()
{
"_id" : ObjectId("5a91af8908e17c5997e03b7e"),
"data" : {
"field1" : false,
"field2" : 0,
"field3" : "No"
}
}
{
"_id" : ObjectId("5a91afbc08e17c5997e03b7f"),
"data" : {
"field1" : true,
"field2" : 1,
"field3" : "Yes"
}
}
答案 1 :(得分:0)
正如chridam在评论中所建议的那样,您可以执行以下聚合管道:
db.collectionName.aggregate([
{ $project: { _id: "$_id", data: "$$ROOT" } },
{ $out: "newCollectionName" }
]);
这样,您在根级别和_id
对象中都有data
字段。因此,您可以执行大量更新以取消设置第二个:
db.newCollectionName.updateMany(
{},
{ $unset: { "data._id": "" } }
);
最后,您可以删除第一个集合并重命名第二个集合以恢复更新集合上的原始名称:
db.collectionName.drop();
db.newCollectionName.rename("collectionName");
这种方法在数据库中完全有效,避免取出任何1000万个文档。