MongoDB
 Computer >> コンピューター >  >> プログラミング >> MongoDB

MongoDBで条件に一致するサブドキュメントを抽出して返すクエリの書き方

MongoDBでは、ドキュメント内の配列に格納されたサブドキュメント(ネストされたオブジェクト)の中から、特定の条件に一致する要素だけを取り出したいケースがよくあります。本記事では、集計パイプライン(aggregate)と $filter 演算子を組み合わせて、条件付きのサブドキュメントを検索・取得する方法を解説します。

1. サンプルコレクションの作成

まずは、ユーザー情報を持つコレクションを作成しましょう。insertOne() メソッドを使ってドキュメントを挿入します。

> db.demo345.insertOne({
...    "UserName" : "Robert",
...    "UserDetails" : [
...       {
...          "isMarried" : false,
...          "CountryName" : "US"
...       },
...       {
...          "isMarried" : true,
...          "CountryName" : "UK"
...       },
...       {
...          "isMarried" : false,
...          "CountryName" : "AUS"
...       }
...    ]
... })
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e5404fdf8647eb59e5620ac")
}

この例では、「Robert」というユーザーの UserDetails 配列の中に、結婚状況(isMarried)と国名(CountryName)を持つ3つのサブドキュメントが格納されています。

2. 登録されたドキュメントの確認

find() メソッドを使うと、コレクション内のすべてのドキュメントを表示できます。

> db.demo345.find();

実行結果は以下のとおりです。

{
   "_id" : ObjectId("5e5404fdf8647eb59e5620ac"),
   "UserName" : "Robert",
   "UserDetails" : [
      { "isMarried" : false, "CountryName" : "US" },
      { "isMarried" : true, "CountryName" : "UK" },
      { "isMarried" : false, "CountryName" : "AUS" }
   ]
}

3. 条件に一致するサブドキュメントのみを返すクエリ

ここからが本題です。配列内のサブドキュメントを絞り込むには、aggregate() で次の2つのステージを使用します。

  • $match: まず「UserName が Robert」であるドキュメントに絞り込みます。
  • $addFields + $filter: UserDetails フィールドを、isMarriedtrue の要素だけにフィルタリングした結果で上書きします。
> db.demo345.aggregate([
...    {
...       $match: { UserName: "Robert" }
...    },
...    {
...       $addFields: {
...          UserDetails: {
...             $filter: {
...                input: "$UserDetails",
...                cond: {
...                   $eq: [ "$$this.isMarried", true ]
...                }
...             }
...          }
...       }
...    }
... ])

ポイント解説

  • $filterinput には、処理対象となる配列フィールド($UserDetails)を指定します。
  • cond には各要素を評価する条件式を記述し、$$this で現在処理中の要素を参照できます。
  • $eq: [ "$$this.isMarried", true ] により、「結婚済み(isMarried が true)」のサブドキュメントだけが残ります。

実行結果

{
   "_id" : ObjectId("5e5404fdf8647eb59e5620ac"),
   "UserName" : "Robert",
   "UserDetails" : [
      { "isMarried" : true, "CountryName" : "UK" }
   ]
}

このように、元の配列から isMarriedtrue のサブドキュメント(UKのデータ)だけが抽出されて返されていることがわかります。

まとめ

MongoDBで配列内のサブドキュメントを条件付きで取得したい場合は、$match で親ドキュメントを絞り込み、$filter を使って配列要素をフィルタリングするのが定番のアプローチです。単純な find() では配列全体が返されてしまうため、必要な要素だけを取り出したいときにこのテクニックが役立ちます。条件式を変更すれば、「特定の国名に一致するもの」など、さまざまな要件に柔軟に対応できます。

  1. 特定のFirstNameとLastNameを持つドキュメントを検索するMongoDBクエリの書き方

    はじめにMongoDBで特定のFirstNameとLastNameを持つドキュメントを検索するには、$and演算子と$in演算子を組み合わせて使用します。この記事では、実際のコード例を通して、find()メソッドでこの条件を実装する方法を解説します。サンプルコレクションの作成まず、insertOne()メソッドを使ってドキュメントを含むコレクションを作成しましょう。> db.demo692.insertOne({FirstName:"Chris","LastName":"Brown"}); { "acknowl

  2. MongoDBでドキュメントとサブドキュメントを表示・更新する方法(実例付き)

    MongoDBでは、ドキュメントの中にサブドキュメント(ネストされた配列やオブジェクト)を持たせることができます。この記事では、ドキュメントとサブドキュメントを含むコレクションの作成、find()メソッドによる表示、update()メソッドによる更新までを具体例とともに解説します。ドキュメントとサブドキュメントの基本構文ドキュメントとサブドキュメントを挿入する際の基本的な構文は以下のとおりです。db.yourCollectionName.insertOne(     {