MongoDBで配列内のネストされたフィールドをクエリする方法($elemMatchの使い方)
MongoDBで配列内のネストされた(入れ子になった)フィールドをクエリしたい場合、$elemMatch 演算子を使用します。$elemMatch を使うと、配列内の各要素に対して複数の条件を適用し、「同じ要素がすべての条件を満たす」ドキュメントだけを正確に抽出できます。
この記事では、実際にコレクションを作成し、配列内のネストされたフィールドをクエリする手順を順番に解説します。
1. サンプルコレクションの作成
まず、insertOne() メソッドを使って、ClientDetails という配列フィールドを持つドキュメントを含むコレクションを作成します。
> db.demo153.insertOne({"ClientDetails":[{"ClientName":"Chris","ClientProject":"Online Banking System"},{"ClientName":"David","ClientProject":"Online School Management"}]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e351957fdf09dd6d08539df")
}
> db.demo153.insertOne({"ClientDetails":[{"ClientName":"Carol","ClientProject":"Online Book System"},{"ClientName":"Mike","ClientProject":"Game Development"}]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e3519c9fdf09dd6d08539e0")
}これで、2件のドキュメントが登録されました。各ドキュメントには、クライアント名(ClientName)とプロジェクト名(ClientProject)を含むサブドキュメントが配列形式で格納されています。
2. 登録したドキュメントの確認
find() メソッドを使うと、コレクション内のすべてのドキュメントを表示できます。
> db.demo153.find();
実行すると、次のような出力が得られます。
{
"_id" : ObjectId("5e351957fdf09dd6d08539df"), "ClientDetails" : [
{ "ClientName" : "Chris", "ClientProject" : "Online Banking System" },
{ "ClientName" : "David", "ClientProject" : "Online School Management" }
]
}
{
"_id" : ObjectId("5e3519c9fdf09dd6d08539e0"), "ClientDetails" : [
{ "ClientName" : "Carol", "ClientProject" : "Online Book System" },
{ "ClientName" : "Mike", "ClientProject" : "Game Development" }
]
}3. 配列内のネストされたフィールドをクエリする
ここからが本題です。$elemMatch と $in を組み合わせることで、配列内のネストされたフィールドを条件付きで検索できます。以下の例では、ClientProject が「Online Banking System」である要素を含むドキュメントを取得しています。
> db.demo153.find({"ClientDetails": { "$elemMatch" : {"ClientProject": { "$in": ["Online Banking System"] } } } });実行結果は以下のとおりです。
{ "_id" : ObjectId("5e351957fdf09dd6d08539df"), "ClientDetails" : [ { "ClientName" : "Chris", "ClientProject" : "Online Banking System" }, { "ClientName" : "David", "ClientProject" : "Online School Management" } ] }このように、「Online Banking System」というプロジェクトを持つドキュメントのみが返されました。
4. 補足:ドット記法との違い
単一の条件であれば、ドット記法(例:"ClientDetails.ClientProject": "Online Banking System")でも同様の検索が可能です。しかし、複数の条件を同じ配列要素に対して適用したい場合は、$elemMatch が必須です。
例えば、「ClientName が Chris かつ ClientProject が Online Banking System である同一の要素」を検索するには、次のように記述します。
> db.demo153.find({"ClientDetails": { "$elemMatch" : {"ClientName": "Chris", "ClientProject": "Online Banking System"} } });ドット記法で条件を分けて書くと、異なる配列要素にまたがってマッチしてしまう可能性があるため、注意が必要です。
まとめ
- 配列内のネストされたフィールドを検索するには
$elemMatchを使用する $inと組み合わせれば、複数の候補値での検索も可能- 同一要素に対して複数条件を指定する場合は、必ず
$elemMatchを使う
-
【MongoDB】idがドキュメント内の配列フィールドの値と一致する場合に除外するクエリの書き方
MongoDBでは、ドキュメントの id フィールドの値が、同一ドキュメント内の配列型フィールド(例: subjectid)に含まれている場合に、そのドキュメントを検索結果から除外したいケースがあります。このような条件を実現するには、 $expr 演算子と組み合わせて $not および $in を使用します。本記事では、サンプルコレクションの作成からクエリの実行、出力結果の確認までを順を追って解説します。 サンプルコレクションの作成 まずは、動作確認用のドキュメントを含むコレクションを作成します。ここでは、 id フィールドと、文字列の配列を持つ subjectid フィールドを備えた2件のド
-
MongoDBのaggregate()で3階層にネストされた埋め込みドキュメントの配列をフィルタリングする方法
MongoDBでネストされた配列をフィルタリングする基本アプローチMongoDBで3階層にネストされた埋め込みドキュメントの配列をフィルタリングするには、aggregate()メソッドを使用します。集計パイプラインの中で$unwindによって配列を展開し、$matchで条件に一致するドキュメントを絞り込むのが基本的な流れです。この記事では、実際のコード例を通じて具体的な手順を解説します。1. サンプルコレクションの作成まずは動作確認用のコレクションを作成し、ドキュメントを挿入してみましょう。> db.demo736.insertOne( ... { ... _id: