三日坊主の繰り返し

大体のことを3日で飽きる人のぼやきです。広く浅く色々手を出していこうと思います。気持ちだけは若くいたい。

mongo でネストされた配列から特定の要素を検索する方法

以下のようなデータがあったとして

{ 
  "_id" : ObjectId("5f6a3919a761753bb5e73c68"),
  "author" : "aaa",
  "question" : "test1",
  "answers" : [ 
    { 
      "voters" : [ "ccc" ],
      "_id" : ObjectId("5f6a3919a761753bb5e73c69"),
      "title" : "a" 
    }, 
    { 
      "voters" : [ "bbb" ],
      "_id" : ObjectId("5f6a3919a761753bb5e73c6a"),
      "title" : "b" 
    }, 
    { 
      "voters" : [ "aaa" ],
      "_id" : ObjectId("5f6a3919a761753bb5e73c6b"),
      "title" : "c" 
    }
  ]
}

voters の中に aaa が含まれる箇所だけを取り出したい場合

find を利用

$elemMatch を使うことで配列の中の要素を検索することが可能、全ての内容が返ってくる。

answers のどの要素に対してaaa が含まれるかを特定する必要がない場合はこれで問題ない

> db.questions.find({"_id": ObjectId("5f6a3919a761753bb5e73c68"), "answers.voters":{$elemMatch: {$eq: "aaa"}}})
{ "_id" : ObjectId("5f6a3919a761753bb5e73c68"), "images" : [ ], "member" : [ ], "author" : "aaa", "question" : "test1", "answers" : [ { "voters" : [ "ccc" ], "_id" : ObjectId("5f6a3919a761753bb5e73c69"), "title" : "a" }, { "voters" : [ "bbb" ], "_id" : ObjectId("5f6a3919a761753bb5e73c6a"), "title" : "b" }, { "voters" : [ "aaa" ], "_id" : ObjectId("5f6a3919a761753bb5e73c6b"), "title" : "c" } ], "expire" : "", "publish" : 1, "create" : "2020-09-23 02:49:13", "update" : "2020-09-23 02:49:13", "delflag" : 0, "__v" : 0 }

aggregate を利用

aaa を含むものだけを返すことができる。

> db.questions.aggregate([{$match: {"_id": ObjectId("5f6a3919a761753bb5e73c68")}}, {$unwind: "$answers"}, {$unwind: "$answers.voters"}, {$match: {"answers.voters": "aaa"}}])
{ "_id" : ObjectId("5f6a3919a761753bb5e73c68"), "images" : [ ], "member" : [ ], "author" : "aaa", "question" : "test1", "answers" : { "voters" : "aaa", "_id" : ObjectId("5f6a3919a761753bb5e73c6b"), "title" : "c" }, "expire" : "", "publish" : 1, "create" : "2020-09-23 02:49:13", "update" : "2020-09-23 02:49:13", "delflag" : 0, "__v" : 0 }

$unwind を2回実行する場合は、1つ上の要素名を含めて指定する必要があった。

({$unwind: "$answers"}, {$unwind: "$answers.voters"} のところ)

aggregate に関する仕様は以下

docs.mongodb.com