[MongoDB] ネストした配列やハッシュをUPDATEする方法
MongoDBでなんやらデータをいじってると、配列をネストして持つようなことが多々あります。例えば以下。
> db.test.find()
{
"_id": ObjectId("f70bafc4be4c41708aeae77b"),
"test": [
{"id": "id_1", "val": 1},
{"id": "id_2", "val": 2},
{"id": "id_3", "val": 3}
]
}
これを見ていると、だんだんid_2
のval
をupdateしたくなってくるでしょう…?
そんな時は以下のように指定してupdateできます。
> db.test.update({"_id": ObjectId("f70bafc4be4c41708aeae77b")}, {$set: {"test.1.val": 10}})
{
"_id": ObjectId("f70bafc4be4c41708aeae77b"),
"test": [
{"id": "id_1", "val": 1},
{"id": "id_2", "val": 10},
{"id": "id_3", "val": 3}
]
}
test.1.val
という風に、key.index.key
で指定できます。
そしてさらに汎用的に、以下のようにもできます。
> db.test.update({"_id": ObjectId("f70bafc4be4c41708aeae77b"), "test.id": "id_3"}, {$inc: {"test.$.val": 1}})
{
"_id": ObjectId("f70bafc4be4c41708aeae77b"),
"test": [
{"id": "id_1", "val": 1},
{"id": "id_2", "val": 10},
{"id": "id_3", "val": 4}
]
}
updateの検索クエリ部分で、対象のidを持つオブジェクトまで絞り込み、test.$.val
という風に、$
マークを使用することで、絞り込んだオブジェクトのインデックスを指定せずに、インクリメントすることができました。
もちろん、ハッシュキーも指定できていることがわかりますね。
ただしこの方法だと、インクリメント対象がオブジェクトの配列の場合に、自動的に配列にappend(insert)されません…ハッシュだとできるのですが、配列で持ちたい場合もあるため、分岐を書かないといけないかもしれませんね。もし良い方法を知っていたら教えて下さい笑
これらはとても便利なので、是非使ってみてください。