MongoDBを使うシステムが、最近多いと思います。
2.6系(安定版)の最新2.6.7ですが、Date型のインポート処理にバグがありそうです。
「1970/01/01」以前の Date型 を mongoexport すると、負の "$numberLong" として出力されるのですが、それを mongoimport すると、それ以降のフィールドが欠落してしまうのです。
例えば、ユーザマスタに「誕生日」フィールドがあると、45歳以上の人は「1970/01/01」以前の値が入っているわけで、マスタデータを移行したりでもすると、その人のフィールドがガッツリ無くなってしまいます。でも若手は大丈夫だから「どうせ部長の使い方がおかしいんでしょwww」といういつもの「偉い人に限って障害が発生する」パターンが展開されます。
大急ぎで調べた所、以下が判明しました。
2.6形式
"1965-11-17T00:00:00Z" → "$date : { $numberLong": "-130118400000" }
"2014-04-24T00:00:00Z" → "$date": "2014-04-24T09:00:00.000+0900"
2.4形式
"1965-11-17T00:00:00Z" → "$date : -130118400000
"2014-04-24T00:00:00Z" → "$date": 1398297600000
2.4系では "$numberLong" を使わないフォーマットです。また、2.6系は2.4系のエクスポートファイルであれば、正常に読み込むことができるようです。
そこで、2.6系で出力したjsonを安全に読めるように変換するコンバータを作成しました。(node.js版)
(エクスポートしたjsonを標準入力で受け取り、標準出力に吐き出す)
var fs = require('fs'),
readline = require('readline'),
rs = process.stdin,
rl = readline.createInterface({'input': rs, 'output': {}});
var re1 = new RegExp(/({ "[$]date" : { "[$]numberLong" : "-[0-9]+" } })/g);
var re2 = new RegExp(/({ "[$]numberLong" : "(-[0-9]+)" })/);
rl.on('line', function (line) {
line = line.replace(re1, function (term) {
term = term.replace(re2, function (a, b, num) {
return num;
});
return term;
});
console.log(line);
});
rl.resume();
使い方
$ node convert.js < エクスポート.json > 変換後エクスポート.json
これで、上司に怒られずに済みますね。