mongodbを2.4から3.2にアップグレードする作業を行っている。3.2にするとテストが大量に失敗するようになったのだが、その原因の一つがこれ。
2.4
> db.Test.update({_id: "nyan"}, {$set: {hoge: {b: {x: 1}}}}, {upsert: true}); > db.Test.findAndModify({query: {_id: "nyan"}, update: {$set: {'hoge.a': {x: 1}}}, new: true}); { "_id" : "nyan", "hoge" : { "a" : { "x" : 1 }, "b" : { "x" : 1 } } }
3.2
mongos> db.Test.update({_id: "nyan"}, {$set: {hoge: {b: {x: 1}}}}, {upsert: true}); WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) mongos> db.Test.findAndModify({query: {_id: "nyan"}, update: {$set: {'hoge.a': {x: 1}}}, new: true}); { "_id" : "nyan", "hoge" : { "b" : { "x" : 1 }, "a" : { "x" : 1 } } }
2.4はsetした順番に関わらずa→bとなるが、3.2はsetした順番に並んでいる。アプリケーションコードでオブジェクトを配列に変換しており、その配列要素の順番が変わったためテストが失敗するようになった。
mongo的にもJS的にもプロパティの順番は仕様で決まっていないので順番に依存すべきではない。今回はアプリ側では配列要素の位置が入れ替わっても問題なく、テストコードだけが順番に依存していたのでテストを直すだけにした。