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 に関する仕様は以下
- 作者:徳彦, 小笠原
- メディア: 単行本