记一次mongodb迁移到新数据库的流程,keystonejs数据完全转移至sailsjs的数据库中。

x
xiezixing
发布于 1 个月前

主要有几个问题需要解决:第一、原数据库中集合全是复数,所以转移至sailsjs自动生成的数据库中需要全部改成单数形式。第二、createdAt和updatedAt原来是Date类型,需要完全转换成double类型。第三、原来单对单和多对多、单对多的方式和sailsjs中的方式完全不一样,所以需要在mongo shell中完全转换。

第一步、复数变单数

> db.movies.renameCollection('movie');
{ "ok" : 1 }
> db.people.renameCollection('person');
{ "ok" : 1 }
> db.personvalues.renameCollection('personvalue');
{ "ok" : 1 }
> db.movievalues.renameCollection('movievalue');
{ "ok" : 1 }
> db.proxies.renameCollection('proxy');
{ "ok" : 1 }
> db.users.renameCollection('user');
{ "ok" : 1 }
> db.movie_actor_manies.renameCollection('movie_actor__person_asActor');
{ "ok" : 1 }
> db.movie_director_manies.renameCollection('movie_director__person_asDirector');
{ "ok" : 1 }
> db.movie_writer_manies.renameCollection('movie_writer__person_asWriter');
{ "ok" : 1 }

第二步、createdAt和updatedAt转换成double格式。

> db.movie.updateMany({updatedAt_utc: {$exists: true}}, [{$addFields: { createdAt: { $toDouble: "$updatedAt_utc"}}}])
{ "acknowledged" : true, "matchedCount" : 108128, "modifiedCount" : 108128 }
> db.movie.updateMany({updatedAt_utc: {$exists: true}}, [{$addFields: { updatedAt: { $toDouble: "$updatedAt_utc"}}}])
{ "acknowledged" : true, "matchedCount" : 108128, "modifiedCount" : 108128 }
> db.movie.updateMany({dateReleased_utc: {$exists: true}}, [{$addFields: { dateReleased: { $dateToString: {format: "%Y-%m-%d", date: "$dateReleased_utc"}}}}])
{ "acknowledged" : true, "matchedCount" : 108128, "modifiedCount" : 108128 }
> db.movievalue.updateMany({updatedAt_utc: {$exists: true}}, [{$addFields: { createdAt: { $toDouble: "$updatedAt_utc"}}}])
{ "acknowledged" : true, "matchedCount" : 197415, "modifiedCount" : 197415 }
> db.movievalue.updateMany({updatedAt_utc: {$exists: true}}, [{$addFields: { updatedAt: { $toDouble: "$updatedAt_utc"}}}])
{ "acknowledged" : true, "matchedCount" : 197415, "modifiedCount" : 197415 }
> db.person.updateMany({updatedAt_utc: {$exists: true}}, [{$addFields: { updatedAt: { $toDouble: "$updatedAt_utc"}}}])
{ "acknowledged" : true, "matchedCount" : 233602, "modifiedCount" : 233602 }
> db.person.updateMany({updatedAt_utc: {$exists: true}}, [{$addFields: { createdAt: { $toDouble: "$updatedAt_utc"}}}])
{ "acknowledged" : true, "matchedCount" : 233602, "modifiedCount" : 233602 }
> db.personvalue.updateMany({updatedAt_utc: {$exists: true}}, [{$addFields: { createdAt: { $toDouble: "$updatedAt_utc"}}}])
{ "acknowledged" : true, "matchedCount" : 466558, "modifiedCount" : 466558 }
> db.personvalue.updateMany({updatedAt_utc: {$exists: true}}, [{$addFields: { updatedAt: { $toDouble: "$updatedAt_utc"}}}])
{ "acknowledged" : true, "matchedCount" : 466558, "modifiedCount" : 466558 }
> db.proxy.updateMany({updatedAt_utc: {$exists: true}}, [{$addFields: { updatedAt: { $toDouble: "$updatedAt_utc"}}}])
{ "acknowledged" : true, "matchedCount" : 4, "modifiedCount" : 4 }
> db.proxy.updateMany({updatedAt_utc: {$exists: true}}, [{$addFields: { createdAt: { $toDouble: "$updatedAt_utc"}}}])
{ "acknowledged" : true, "matchedCount" : 4, "modifiedCount" : 4 }
> db.user.updateMany({updatedAt_utc: {$exists: true}}, [{$addFields: { createdAt: { $toDouble: "$updatedAt_utc"}}}])
{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }
> db.user.updateMany({updatedAt_utc: {$exists: true}}, [{$addFields: { updatedAt: { $toDouble: "$updatedAt_utc"}}}])
{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }

这里有一个很有用的方法,将原来集合中的Date数据通过$dateToString aggregation方法转换成指定格式的字符串,并且储存到新的字段中:

db.movie.updateMany({dateReleased_utc: {$exists: true}}, [{$addFields: { dateReleased: { $dateToString: {format: "%Y-%m-%d", date: "$dateReleased_utc"}}}}])
// 这里就是把原来Date格式的dateReleased_utc转换成YYYY-mm-dd格式的字符串并且创建一个新的字段dateReleased,将格式化后的字符串储存到dateReleased中。

第三步、修正单对单、单对多、多对多关系字段

db.movie_actor__person_asActor.updateMany( {}, { $rename: { "Movie_left_id": "movie_actor", "Person_right_id": "person_asActor" } } )
db.movie_director__person_asDirector.updateMany( {}, { $rename: { "Movie_left_id": "movie_director", "Person_right_id": "person_asDirector" } } )
db.movie_writer__person_asWriter.updateMany( {}, { $rename: { "Movie_left_id": "movie_writer", "Person_right_id": "person_asWriter" } } )

原来单对多是创建了一个单独的表,但是在新数据库结构中是储存在movievalue的movie字段中,所以需要读取出来单独的表,然后创建一个movie字段到movievalue中,并且赋值:

> var manies = db.movie_data_manies.find()
> manies.forEach(function(many) { db.movievalue.update({_id: many.MovieValue_right_id}, [{$addFields: {movie: many.Movie_left_id}}])})

第四步、建立必要的索引

> db.movie.createIndex({type:1, createdAt:-1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 1,
	"numIndexesAfter" : 2,
	"ok" : 1
}
> db.movie.createIndex({type:1, updatedAt:-1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 2,
	"numIndexesAfter" : 3,
	"ok" : 1
}
> db.movie.createIndex({originalName: 1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 3,
	"numIndexesAfter" : 4,
	"ok" : 1
}
> db.movie.createIndex({alias: 1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 4,
	"numIndexesAfter" : 5,
	"ok" : 1
}
> db.movie.createIndex({doubanId: 1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 5,
	"numIndexesAfter" : 6,
	"ok" : 1
}
> db.movie_actor__person_asActor.getIndexes()
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" } ]
> db.movie_actor__person_asActor.createIndex({movie_actor:1,person_asActor:1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 1,
	"numIndexesAfter" : 2,
	"ok" : 1
}
> db.movie_director__person_asDirector.createIndex({movie_director:1,person_asDirector:1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 1,
	"numIndexesAfter" : 2,
	"ok" : 1
}
> db.movie_writer__person_asWriter.createIndex({movie_writer:1,person_asWriter:1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 1,
	"numIndexesAfter" : 2,
	"ok" : 1
}
> db.movievalue.createIndex({lang:1, createdAt:-1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 1,
	"numIndexesAfter" : 2,
	"ok" : 1
}
> db.movievalue.createIndex({lang:1, updatedAt:-1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 2,
	"numIndexesAfter" : 3,
	"ok" : 1
}
> db.movievalue.createIndex({name:1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 3,
	"numIndexesAfter" : 4,
	"ok" : 1
}
> db.movievalue.createIndex({movie:1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 4,
	"numIndexesAfter" : 5,
	"ok" : 1
}
> db.personvalue.createIndex({name:1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 1,
	"numIndexesAfter" : 2,
	"ok" : 1
}
> db.personvalue.createIndex({lang:1,createdAt:-1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 2,
	"numIndexesAfter" : 3,
	"ok" : 1
}
> db.personvalue.createIndex({lang:1,updatedAt:-1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 3,
	"numIndexesAfter" : 4,
	"ok" : 1
}
> db.personvalue.createIndex({role: 1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 4,
	"numIndexesAfter" : 5,
	"ok" : 1
}
> db.personvalue.createIndex({person: 1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 5,
	"numIndexesAfter" : 6,
	"ok" : 1
}
> db.user.createIndex({emailProofToken:1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 3,
	"numIndexesAfter" : 4,
	"ok" : 1
}
> db.user.createIndex({passwordResetToken:1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 4,
	"numIndexesAfter" : 5,
	"ok" : 1
}
> db.person.createIndex({createdAt:-1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 1,
	"numIndexesAfter" : 2,
	"ok" : 1
}
> db.person.createIndex({updatedAt:-1})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 2,
	"numIndexesAfter" : 3,
	"ok" : 1
}

第五步、删除多余的字段

> db.movie.updateMany({updatedAt_utc: {$exists: true}}, { $unset: { updatedAt_utc: "", updatedAt_offset: "", createdAt_utc: "",createdAt_offset:"", dateReleased_offset: "",dateReleased_utc: "", __v: ""} })
{ "acknowledged" : true, "matchedCount" : 108128, "modifiedCount" : 108128 }
// 后面其他集合的删除方式差不多,粘贴复制即可

相关文章推荐
评论区
暂未开放
相关文章推荐