[MongoDB] ネストした配列やハッシュをUPDATEする方法

MongoDB 2016年4月12日

MongoDBでなんやらデータをいじってると、配列をネストして持つようなことが多々あります。例えば以下。

> db.test.find()
{
  "_id": ObjectId("f70bafc4be4c41708aeae77b"),
  "test": [
    {"id": "id_1", "val": 1},
    {"id": "id_2", "val": 2},
    {"id": "id_3", "val": 3}
  ]
}

これを見ていると、だんだんid_2valを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)されません…ハッシュだとできるのですが、配列で持ちたい場合もあるため、分岐を書かないといけないかもしれませんね。もし良い方法を知っていたら教えて下さい笑

これらはとても便利なので、是非使ってみてください。

slont

金融ベンチャーでWebエンジニア

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.