MongoDBでオブジェクトの配列を検索する方法:$elemMatch演算子の使い方を解説
MongoDBでは、ドキュメント内にネストされたオブジェクトの配列(配列の中に複数のサブドキュメントが格納された構造)を持つコレクションを扱うことがよくあります。このような配列から特定の条件に一致する要素を検索するには、$elemMatch 演算子を使用します。
$elemMatch を使うと、「同じ配列要素内で複数の条件をすべて満たす」ドキュメントを正確に絞り込むことができます。単純なドット記法での検索と異なり、複数のフィールド条件が同一の配列要素内で成立していることを保証できるのが大きな特徴です。
サンプルデータの準備
まずは、従業員情報を格納するコレクションを作成し、テスト用のドキュメントを挿入してみましょう。
> db.searchArrayDemo.insertOne({
"EmployeeFirstName": "Adam",
"EmployeeLastName": "Smith",
"EmployeeDateOfBirth": new ISODate("1992-01-31 13:45:10"),
"EmployeeSkills": ["Spring and Hibernate Framework", "Machine Learning"],
"EmployeeDetails": [
{
"EmployeePerformanceArea": "Java",
"Year": 2001
},
{
"EmployeePerformanceArea": "Python",
"Year": 2005
}
]
});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c77b3812386c62d05142a6a")
}> db.searchArrayDemo.insertOne({
"EmployeeFirstName": "Carol",
"EmployeeLastName": "Taylor",
"EmployeeDateOfBirth": new ISODate("1993-04-21 11:10:20"),
"EmployeeSkills": ["C++", "Cloud Computing"],
"EmployeeDetails": [
{
"EmployeePerformanceArea": "C++",
"Year": 1998
},
{
"EmployeePerformanceArea": "C++ Game Developer",
"Year": 2007
}
]
});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c77b58f2386c62d05142a6b")
}登録済みドキュメントの確認
find() メソッドを使って、コレクション内のすべてのドキュメントを表示します。
> db.searchArrayDemo.find().pretty();
実行結果は以下の通りです。
{
"_id" : ObjectId("5c77b3812386c62d05142a6a"),
"EmployeeFirstName" : "Adam",
"EmployeeLastName" : "Smith",
"EmployeeDateOfBirth" : ISODate("1992-01-31T13:45:10Z"),
"EmployeeSkills" : [
"Spring and Hibernate Framework",
"Machine Learning"
],
"EmployeeDetails" : [
{
"EmployeePerformanceArea" : "Java",
"Year" : 2001
},
{
"EmployeePerformanceArea" : "Python",
"Year" : 2005
}
]
}
{
"_id" : ObjectId("5c77b58f2386c62d05142a6b"),
"EmployeeFirstName" : "Carol",
"EmployeeLastName" : "Taylor",
"EmployeeDateOfBirth" : ISODate("1993-04-21T11:10:20Z"),
"EmployeeSkills" : [
"C++",
"Cloud Computing"
],
"EmployeeDetails" : [
{
"EmployeePerformanceArea" : "C++",
"Year" : 1998
},
{
"EmployeePerformanceArea" : "C++ Game Developer",
"Year" : 2007
}
]
}$elemMatchによる配列検索の実例
ケース1:条件に一致する要素が存在する場合
「EmployeePerformanceArea が C++ かつ Year が 1998」という条件を、同一の配列要素内で満たすドキュメントを検索します。
> db.searchArrayDemo.find({
EmployeeDetails: {
$elemMatch: {
EmployeePerformanceArea : "C++",
Year : 1998
}
}
}).pretty();実行結果:
{
"_id" : ObjectId("5c77b58f2386c62d05142a6b"),
"EmployeeFirstName" : "Carol",
"EmployeeLastName" : "Taylor",
"EmployeeDateOfBirth" : ISODate("1993-04-21T11:10:20Z"),
"EmployeeSkills" : [
"C++",
"Cloud Computing"
],
"EmployeeDetails" : [
{
"EmployeePerformanceArea" : "C++",
"Year" : 1998
},
{
"EmployeePerformanceArea" : "C++ Game Developer",
"Year" : 2007
}
]
}Carol のドキュメントには「C++(1998年)」という実績が含まれているため、該当ドキュメントとして返されました。
ケース2:条件に一致する要素が存在しない場合
次に、存在しない組み合わせ(EmployeePerformanceArea が「C」かつ Year が 1996)で検索してみます。
> db.searchArrayDemo.find({
EmployeeDetails: {
$elemMatch: {
EmployeePerformanceArea : "C",
Year : 1996
}
}
}).pretty();この場合、条件を満たす配列要素がどのドキュメントにも存在しないため、結果は何も返されません。エラーにはならず、単に空の結果セットが返る点に注意してください。
補足:$elemMatchを使うメリット
仮に {"EmployeeDetails.EmployeePerformanceArea": "C++", "EmployeeDetails.Year": 1998} のようにドット記法で検索した場合、「C++」と「1998」が別々の配列要素に分かれていても一致とみなされてしまいます。一方、$elemMatch を使えば両方の条件が単一の配列要素内で同時に成立することを保証できるため、ネストされた構造を扱う際には $elemMatch の利用が推奨されます。
-
MongoDBでオブジェクト内の配列に要素を追加する方法|$push演算子の使い方を解説
MongoDBでオブジェクト内の配列に要素を挿入するには?すでに作成済みのオブジェクト内にある配列に新しい要素を追加したい場合は、MongoDBの $push 演算子を使用します。$push は、指定した配列フィールドの末尾に値を追加するための更新演算子で、ネストされた構造のドキュメントにもドット記法を使うことで対応できます。まずは、サンプルとなるドキュメントを含むコレクションを作成しましょう。> db.demo449.insertOne(... {... details1: {... details2: [{... _id:new ObjectId(
-
MongoDBのオブジェクト配列からアイテムを取得する方法
MongoDBでオブジェクト配列からアイテムを取得するには?MongoDBのドキュメント内にネストされたオブジェクト配列から特定のアイテムを取り出したい場合は、aggregate()メソッドを使用します。集計パイプラインの各ステージを組み合わせることで、配列の展開・絞り込み・集約を柔軟に行えます。まずは、サンプルコレクションにドキュメントを作成してみましょう。> db.demo459.insertOne( ... { _id : 1, ... Information : [ ... { ... Name : Chris, ... _id : new O