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

MongoDBでサブコレクションからドキュメントを取得するには?$in演算子の使い方を解説

MongoDBで配列内のサブドキュメント(サブコレクション)を条件にドキュメントを取得したい場合、$in 演算子を使用するのが効果的です。単純な $and の組み合わせでは、同じ配列要素内での複数条件の一致を正しく判定できないケースがあるため、$elemMatch$in を組み合わせる方法が推奨されます。

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

まず、ドキュメントを含むコレクションを作成しましょう。以下の例では、demo83 コレクションに、人物ごとの名前と科目リストを持つ「Details」配列を格納しています。

> db.demo83.insertOne(
... {
...    "Details":[
...       {
...          "Name":"Chris",
...          "Subject":[
...             "MySQL",
...             "MongoDB"
...          ]
...       },
...       {
...          "Name":"David",
...          "Subject":[
...             "Java",
...             "C"
...          ]
...       }
...    ]
... }
... );
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e2bfd2271bf0181ecc422a3")
}
> db.demo83.insertOne(
... {
...    "Details":[
...       {
...          "Name":"Bob",
...          "Subject":[
...             "C++",
...             "Python"
...          ]
...       },
...       {
...          "Name":"John",
...          "Subject":[
...             "Spring",
...             "Hibernate"
...          ]
...       }
...    ]
... }
... );
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e2bfd4571bf0181ecc422a4")
}

登録済みドキュメントの確認

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

> db.demo83.find();

このクエリを実行すると、次のような出力が得られます。

{
   "_id" : ObjectId("5e2bfd2271bf0181ecc422a3"), "Details" : [
      { "Name" : "Chris", "Subject" : [ "MySQL", "MongoDB" ] },
      { "Name" : "David", "Subject" : [ "Java", "C" ] }
   ]
}
{
   "_id" : ObjectId("5e2bfd4571bf0181ecc422a4"), "Details" : [
      { "Name" : "Bob", "Subject" : [ "C++", "Python" ] },
      { "Name" : "John", "Subject" : [ "Spring", "Hibernate" ] }
   ]
}

$elemMatch と $in を使ったドキュメントの検索

ここで、「Name が Chris であり、かつ Subject 配列の中に MongoDB が含まれている」という条件でドキュメントを取得してみましょう。このような場合、$elemMatch を使用して同一の配列要素内で複数の条件を評価し、Subject の値の一致判定には $in を使用します。

> db.demo83.find({ "Details" : { "$elemMatch" : {"Name" :"Chris" , "Subject":{"$in":["MongoDB"]}}}});

実行結果は次のとおりです。Name が「Chris」で、Subject に「MongoDB」を含むドキュメントだけが正確に取得できています。

{
   "_id" : ObjectId("5e2bfd2271bf0181ecc422a3"), "Details" : [
      { "Name" : "Chris", "Subject" : [ "MySQL", "MongoDB" ] },
      { "Name" : "David", "Subject" : [ "Java", "C" ] }
   ] 
}

ポイントまとめ

  • 配列内のサブドキュメントに対して複数条件を指定する場合は $elemMatch を使うことで、同一要素内での条件一致を保証できます。
  • フィールド値が配列のいずれかに一致するかを調べたい場合は $in 演算子が便利です。
  • $and を単純に使うと、異なる配列要素にまたがって条件がマッチしてしまうことがあるため注意が必要です。
  1. MongoDBの$regex演算子で大文字と小文字を区別しない検索を行う方法(iオプション)

    MongoDBで大文字と小文字を区別せずに文字列検索を行いたい場合は、$regex演算子に「i」(case insensitive:大文字と小文字を区別しない)オプションを指定します。この記事では、実際にコレクションを作成し、「mongodb」という文字列を表記の違いにかかわらずすべて取得する方法を、サンプルコード付きで解説します。ドキュメントを含むコレクションの作成まず、insertOne()メソッドを使って、異なる表記(MySQL、MongoDB、mongodb、MONGODB)のドキュメントを持つコレクションを作成しましょう。> db.demo759.insertOne({Subj

  2. MongoDBの無駄なスペースを削減する戦略:フィールド名の短縮とネームストアによるトークン化

    Appboyは、モバイルアプリ向けの世界有数のマーケティングオートメーションプラットフォームです。当社では毎月数十億規模のデータポイントを収集しており、顧客のモバイルアプリ上でのユーザーの行動を追跡し、その行動や属性情報に基づいて、メール、プッシュ通知、アプリ内メッセージによるターゲティングを可能にしています。データベース基盤の大部分はMongoDBが支えており、ObjectRocket上で複数のクラスタにまたがる数十のシャードを運用しています。短いフィールド名による基本戦略MongoDBにおける一般的なパフォーマンス最適化手法の一つが、ドキュメント内で短いフィールド名を使うことです。つまり、