slontが2016年4月12日に投稿(2016年10月1日更新)

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

slont

元金融エンジニア。メイン言語はJava, HTML, JavaScript, Python, Kotlinあたり。SECCONやCTF、NLP、機械学習に興味あり。金融日記購読4年。巷で話題の変態紳士。美女ソムリエ始めてました。 お仕事の依頼はTwitterからお願いします。

comments powered by Disqus
Back to top