はじめに
MongoDBはNoSQLデータベースの一つで、JSONライクな形式でデータを扱います。この記事では、MongoDBでデータを取得する際の基本的なクエリの書き方を解説します。
この記事で学べること
- MongoDBのクエリの基本構文
- 比較演算子や論理演算子を使った検索方法
- 配列データの扱い方
- よく使う便利なクエリ
MongoDBのクエリの特徴
SQLとの違い
リレーショナルデータベース(RDB)のSQLとは異なり、MongoDBではJSONライクな形式でクエリを記述します。
SQLではSELECTやWHEREといったキーワードを使いますが、MongoDBではfind()メソッドとJSONオブジェクトを使って条件を指定します。
JSONライクな記法
MongoDBのクエリは、JavaScriptのオブジェクト記法に似た形式で記述します。これにより、プログラミング言語との親和性が高くなっています。
基本的なfind()メソッド
MongoDBでデータを取得する際の基本となるのがfind()メソッドです。
全件取得
コレクション内のすべてのドキュメントを取得する場合は、引数を指定せずにfind()を実行します。
db.users.find()
特定の条件で検索
条件を指定してデータを絞り込む場合は、第一引数にクエリ条件をオブジェクト形式で渡します。
// 年齢が25歳のユーザーを検索
db.users.find({ age: 25 })
// 名前が"田中"のユーザーを検索
db.users.find({ name: "田中" })
// 複数の条件を指定(AND条件)
db.users.find({ age: 25, city: "東京" })
プロジェクション(フィールド指定)
取得するフィールドを限定したい場合は、第二引数でプロジェクションを指定します。1は取得、0は除外を意味します。
// nameとageだけを取得(_idは自動的に含まれる)
db.users.find({}, { name: 1, age: 1 })
// _idを除外してnameとageだけを取得
db.users.find({}, { name: 1, age: 1, _id: 0 })
// emailを除外して他のフィールドをすべて取得
db.users.find({}, { email: 0 })
比較演算子を使ったクエリ
MongoDBでは、数値や日付の比較に演算子を使用します。演算子は$から始まる記法で表現します。
$gt, $gte(より大きい)
-
$gt: greater than、指定した値より大きい -
$gte: greater than or equal、指定した値以上
// 年齢が30歳より大きいユーザー
db.users.find({ age: { $gt: 30 } })
// 年齢が30歳以上のユーザー
db.users.find({ age: { $gte: 30 } })
$lt, $lte(より小さい)
-
$lt: less than、指定した値より小さい -
$lte: less than or equal、指定した値以下
// 年齢が20歳未満のユーザー
db.users.find({ age: { $lt: 20 } })
// 年齢が20歳以下のユーザー
db.users.find({ age: { $lte: 20 } })
範囲指定
複数の比較演算子を組み合わせて範囲を指定することもできます。
// 年齢が20歳以上30歳以下のユーザー
db.users.find({ age: { $gte: 20, $lte: 30 } })
$eq, $ne(等しい、等しくない)
-
$eq: equal、指定した値と等しい -
$ne: not equal、指定した値と等しくない
// 年齢が25歳のユーザー({ age: 25 }と同じ)
db.users.find({ age: { $eq: 25 } })
// 年齢が25歳でないユーザー
db.users.find({ age: { $ne: 25 } })
// ステータスが"active"でないユーザー
db.users.find({ status: { $ne: "active" } })
論理演算子を使ったクエリ
複数の条件を組み合わせる場合に論理演算子を使用します。
$and(AND条件)
すべての条件を満たすドキュメントを取得します。通常は暗黙的にAND条件になりますが、同じフィールドに複数の条件を指定する場合は明示的に$andを使用します。
// 年齢が25歳で、かつ都市が東京のユーザー(暗黙的なAND)
db.users.find({ age: 25, city: "東京" })
// 年齢が20歳以上で、かつ30歳以下のユーザー(明示的なAND)
db.users.find({
$and: [
{ age: { $gte: 20 } },
{ age: { $lte: 30 } }
]
})
$or(OR条件)
いずれかの条件を満たすドキュメントを取得します。
// 年齢が20歳以下、または40歳以上のユーザー
db.users.find({
$or: [
{ age: { $lte: 20 } },
{ age: { $gte: 40 } }
]
})
// 都市が東京または大阪のユーザー
db.users.find({
$or: [
{ city: "東京" },
{ city: "大阪" }
]
})
$not, $nor
-
$not: 条件に一致しないドキュメントを取得 -
$nor: すべての条件に一致しないドキュメントを取得
// 年齢が30歳以上でないユーザー
db.users.find({ age: { $not: { $gte: 30 } } })
// 都市が東京でも大阪でもないユーザー
db.users.find({
$nor: [
{ city: "東京" },
{ city: "大阪" }
]
})
ANDとORの組み合わせ
// 年齢が25歳で、かつ都市が東京または大阪のユーザー
db.users.find({
age: 25,
$or: [
{ city: "東京" },
{ city: "大阪" }
]
})
配列を扱うクエリ
MongoDBでは、配列型のフィールドに対しても柔軟にクエリを実行できます。
$in, $nin(含まれる、含まれない)
-
$in: 指定した値のいずれかに一致 -
$nin: 指定した値のいずれにも一致しない
// 都市が東京、大阪、名古屋のいずれかのユーザー
db.users.find({ city: { $in: ["東京", "大阪", "名古屋"] } })
// 年齢が20、25、30のいずれでもないユーザー
db.users.find({ age: { $nin: [20, 25, 30] } })
// タグ配列に"JavaScript"が含まれるドキュメント
db.articles.find({ tags: { $in: ["JavaScript"] } })
$all(すべて含む)
配列フィールドが指定したすべての要素を含むドキュメントを取得します。
// タグ配列に"JavaScript"と"MongoDB"の両方が含まれる記事
db.articles.find({ tags: { $all: ["JavaScript", "MongoDB"] } })
その他の便利なクエリ
$exists(フィールドの存在確認)
特定のフィールドが存在するか、または存在しないドキュメントを取得します。
// emailフィールドが存在するユーザー
db.users.find({ email: { $exists: true } })
// phoneフィールドが存在しないユーザー
db.users.find({ phone: { $exists: false } })
この演算子は、スキーマが柔軟なMongoDBで特に便利です。ドキュメントによってフィールドの有無が異なる場合に活用できますね。
$regex(正規表現)
文字列フィールドに対して正規表現でパターンマッチングを行います。
// 名前が"田"で始まるユーザー
db.users.find({ name: { $regex: /^田/ } })
// メールアドレスが"gmail.com"で終わるユーザー
db.users.find({ email: { $regex: /gmail\.com$/ } })
// 名前に"太郎"を含むユーザー(大文字小文字を区別しない)
db.users.find({ name: { $regex: /太郎/i } })
$type(データ型の確認)
フィールドのデータ型で絞り込みます。
// ageフィールドが数値型のドキュメント
db.users.find({ age: { $type: "number" } })
// nameフィールドが文字列型のドキュメント
db.users.find({ name: { $type: "string" } })
findOne()との使い分け
find()はカーソルを返し複数のドキュメントを取得しますが、findOne()は条件に一致する最初のドキュメント一つだけを返します。
// 複数のドキュメントを取得(カーソルを返す)
db.users.find({ city: "東京" })
// 最初の一つだけを取得(ドキュメントオブジェクトを直接返す)
db.users.findOne({ city: "東京" })
使い分けのポイント
- find()を使う場合: 複数の結果が必要な時、一覧を取得したい時
- findOne()を使う場合: 一意のIDで検索する時、最初の一件だけで十分な時
// ユーザーIDで特定のユーザーを取得(一件のみ)
db.users.findOne({ _id: ObjectId("507f1f77bcf86cd799439011") })
// 特定の都市に住むユーザーの一覧(複数件)
db.users.find({ city: "東京" })
まとめ
MongoDBの基本的なクエリについて解説しました。主なポイントは以下の通りです。
-
find()メソッドでデータを取得し、条件をJSONオブジェクト形式で指定する - 比較演算子で数値や日付の範囲検索ができる
- 論理演算子で複雑な条件を組み合わせられる
- 配列データに対しても柔軟なクエリが可能
-
$existsや$regexなどの便利な演算子を活用できる
これらの基本的なクエリを組み合わせることで、多様なデータ検索が実現できます。実際のアプリケーション開発では、これらのクエリを適切に使い分けて効率的にデータを取得しましょう。