MongoDB の基本的なクエリ10個

MongoDB のクエリーのサンプルデータ

ここでは MongoDB でのクエリーの入門編として、基本的な条件指定方法等を、 実際に動かしながら学びましょう。

ここで使用するテストデータは、次のリンクでダウンロードしてください。

テストデータのダウンロード

MongoDB Compass などのデータのインポート機能を利用して、ファイル malls.json をコレクション malls として、 states.json をコレクション states として取り込んでください。

MongoDB Compass を使ったデータのインポート方法

ここでは MongoDB Compass を使って、テストデータを取り込む方法を簡単に説明します。

MongoDB Compass で MongoDB に接続したら、適当な名前のデータベースを作成します。ここでは shoppingdb とします。最初のコレクション名は malls とします。

ADD DATA ボタンから Import File を選択します。

ダウンロードしたファイルから malls.json を選択し、 Input File Type は JSON を選び、 IMPORT ボタンをクリックします。

これで malls.json が取り込まれたはずです。もうひとつの states.json も、 states という名前のコレクションとして取り込んでください。

MongoDB の基本的なクエリ

MongoDB での基本的なクエリを、実際に実行しながらみてみましょう。 上のサンプルデータを取り込むと、下記のクエリが実行できます。

MongoDB での「等しい」条件

あるコレクション内のドキュメントで、特定のプロパティの値が指定した値に等しいドキュメントを抽出するには、次のようにします。

例えば、 numberOfStores というプロパティが 「300と等しい」という条件を満たすドキュメントを抽出するには、 $eq という演算子を用いて次のようにかけます。

db.getCollection('malls').find({
  numberOfStores: {
    $eq: 300
  },
})

演算子を使わないで次のように書いても同じです。

db.getCollection('malls').find({
  numberOfStores: 300,
})

MongoDB での「大きい」「小さい」条件: $gt$lt

あるコレクション内のドキュメントで、特定のプロパティの値が指定した値より大きい、または小さいドキュメントを抽出するには、次のようにします。

例えば、 numberOfStores というプロパティが 「200 より大きい」という条件を満たすドキュメントを抽出するには、 $gt (greater than) という演算子を用いて次のようにかけます。

db.getCollection('malls').find({
  numberOfStores: {
    $gt: 200
  },
})

さらに「200より大きく、かつ、300 より小さい」という条件にするならば、「より小さい」(less than) を表す演算子 $lt を組み合わせて、次のようにできます。

db.getCollection('malls').find({
  numberOfStores: {
    $gt: 200,
    $lt: 300
  },
})

「200 より小さい」ではなく、「300 と同じかまたは小さい」とするには、演算子 $lte (less than or equal) が使えます。

db.getCollection('malls').find({
  numberOfStores: {
    $gt: 200,
    $lte: 300
  },
})

同様に「同じかまたは大きい」(greater than or equal) $gte です。

MongoDB のクエリーでの否定の条件指定

抽出条件の否定は $not 演算子を使います。

「『200より大きい』を『満たさない』」ドキュメントを抽出するには、次のようにします。

db.getCollection('malls').find({
  numberOfStores: {
    $not: {
      $gt: 200,
    },
  },
})

MongoDB のクエリーでの複数の条件指定

ここでは複数の条件を指定する方法をみてみましょう。

条件1 かつ 条件2: $and

「『100より大きい』かつ『200より小さい』」というように、二つの条件を足す場合は、条件を並べて記載します。

db.getCollection('malls').find({
  numberOfStores: {
    $gt: 100,
    $lt: 200,
  },
})

同じことを $and 演算子を用いると、次のように書けます。

db.getCollection('malls').find({
  $and: [
    {
      numberOfStores: {
        $gt: 100,
      },
    },
    {
      numberOfStores: {
        $lt: 200,
      },
    },
  ],
})

条件1 または 条件2 : $or

複数の条件の、いずれか一つを満たす、という場合は演算子 $or を使います。

「100より小さい」または「300より大きい」という場合は、次のように書きます。

db.getCollection('malls').find({
  $or: [
    {
      numberOfStores: {
        $lt: 100,
      },
    },
    {
      numberOfStores: {
        $gt: 300,
      },
    },
  ],
})

MongoDB で配列内の値で抽出

MongoDB のドキュメントでは、プロパティに配列型のデータを持つことができます。

配列内にどれか1つでも含むものを抽出

配列のプロパティに、指定した値のうち、どれかひとつでも持つドキュメントを抽出するには、 $in 演算子が使えます。

例えば、配列型のプロパティ stores の中に、 Forever 21UniqloH&M のいずれかを含むドキュメントを抽出するには、次のようにします。

db.getCollection('malls').find({
  stores: {
    $in: [ 'Forever 21', 'Uniqlo', 'H&M' ]
  },
})

配列内に全て含むものを抽出

配列のプロパティに、指定した値を全て持つドキュメントを抽出するには、 $all 演算子が使えます。

例えば、配列型のプロパティ stores の中に、 Forever 21UniqloH&M の全てを含むドキュメントを抽出するには次のようにします。

db.getCollection('malls').find({
  stores: {
    $all: [ 'Forever 21', 'Uniqlo', 'H&M' ]
  },
})

配列内にどの値も含まないものを抽出

配列のプロパティに、指定した値を全て持たないドキュメントを抽出するには、 $nin 演算子が使えます。

例えば、配列型のプロパティ stores の中に、 H&MBanana Republic のいずれも含まない (ひとつでも含んでいれば抽出しない) ドキュメントを抽出するには、次のようにします。

db.getCollection('malls').find({
  stores: { $nin: [ 'H&M', 'Banana Republic' ] }
})

MongoDB のドキュメント中に特定のプロパティの有無で抽出

MongoDB のコレクションに含まれるドキュメントでは、たとえ同じコレクションに含まれていても、それぞれのドキュメントがもつプロパティが同じとは限ります。(一般に異なります。)

例えば、phone というプロパティを持つドキュメントを抽出するには次のようにします。

db.getCollection('malls').find({
  phone: { $exists: true }
})

MongoDB での正規表現によるクエリ

文字列の条件に関しては、ケースセンシティブが基本です。大文字小文字を区別しない、などは、特に正規表現等で条件を指定する必要があります。

例えば、 name プロパティに south と言う文字を、大文字小文字区別せずにもつドキュメントを抽出する場合には、次のように指定します。

db.getCollection('malls').find({
  name: /south/i,
})

MongoDB でクエリの結果でドキュメントの一部のみ返す方法

MongoDB のクエリの結果としてドキュメント (のリスト) を返す場合、特定のプロパティのみを返すことができます。

find() で結果を返すとき、二つ目の引数として、返すプロパティの値を 1 とすることで、そのプロパティが結果に含まれます。第二引数を全く指定しなければドキュメント全体が返ります。

例えば、クエリの結果 nameaddress.state だけを返す場合は次のようにします。

db.getCollection('malls').find(
  { name: /south/i },
  {
    name: 1,
    address: {
      state: 1,
    },
  }
)

MongoDB でクエリの結果をソートする方法

MongoDB のクエリでドキュメントを返すときにソートするには、 find() 関数の戻り値となるカーソルに対して sort() 関数を呼びます。 このときにソートするプロパティを 1 とすると昇順にソートされます。

例えば、 numberOfStores プロパティで昇順にソートするには、次のようにします。

db.getCollection('malls')
  .find(
    { name: /south/i },
    {
      name: 1,
      numberOfStores: 1,
    }
  )
  .sort({ numberOfStores: 1 })

MongoDB で他のコレクションのデータをクエリの結果の取り込む方法

RDBMS で JOIN を使って他のテーブルのレコードを参照するように、MongoDB でも他のコレクションのデータを引くにはどうすれば良いでしょうか。

あるフィールドをキーとして、他のコレクションのドキュメントを取り込むには $lookup を使用してフィールド間の対応付けを記述します。

例えば、 malls コレクション内のドキュメントの address.state にあるコードと、 states コレクション内のドキュメントの code プロパティを対応付け、 states コレクションの name プロパティを取り込むには、次のようにします。

db.getCollection('malls').aggregate([
  {
    $lookup: {
      from: 'states',
      localField: 'address.state',
      foreignField: 'code',
      as: 'usState',
    },
  },
  {
    $unwind: '$usState',
  },
  {
    $project: {
      name: 1,
      addr: '$usState.name',
    },
  },
])

いかがだったでしょうか。実際にクエリーを実行してみることで、MongoDB でのクエリーにも慣れてきたのではないでしょうか。以上で、MongoDB での基本的なクエリーの記述方法の説明を終わります。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Node.js 入門