[Mongo] findメソッドのいろいろな使い方(MySQLと比較)
こんにちは、@yoheiMuneです。
以前にフロントエンドエンジニアにオススメなデータベース、MongoDBに入門とフロントエンドエンジニアにもできるMongoDBを使ったログ分析のブログを書いたのち、MongoDBを引き続き使っていますが、findの使い方を調べることが多く、今回はそれらをブログに残しておきたいと思います。
SQL to MongoDB Mapping Chart — MongoDB Manual
はじめてのMongoDB | Slideshare
最後になりますが本ブログでは、フロントエンドのネタを中心に情報を発信しています。気になった方はぜひ、RSSやTwitterをフォローして頂けますと幸いです ^ ^。
最後までご覧頂きましてありがとうございました!
以前にフロントエンドエンジニアにオススメなデータベース、MongoDBに入門とフロントエンドエンジニアにもできるMongoDBを使ったログ分析のブログを書いたのち、MongoDBを引き続き使っていますが、findの使い方を調べることが多く、今回はそれらをブログに残しておきたいと思います。
目次
Mongoの検索メソッドは多機能
Mongoのfind、findOne、count、distinctは検索を行うことができるメソッドたちです。使うときそれぞれのユースケースに合わせた使い分けをしていく必要があり、それぞれのメソッドの機能をある程度知っている必要があります。今回はSQLのselect文をMongoで実現するにはという切り口で、Mongoの検索機能を学んでみたいと思います。今回利用するデータ
今回は以下のようなUserデータを使って説明してみたいと思います。
db.users.insert({user_id: "abc001", age: 45, status: "A"})
db.users.insert({user_id: "bcd001", age: 50, status: "A"})
db.users.insert({user_id: "cde001", age: 20, status: "A"})
db.users.insert({ age: 10, status: "A"})
db.users.insert({user_id: "def001", age: 30, status: "B"})
検索メソッドのいろいろな使い方
それではいろいろな使い方をみてみたいと思います。全件検索する
// SQL SELECT * FROM users
// Mongo db.users.find()
// 実行結果
{ "_id" : ObjectId("556d5643aa73f980c884bf4f"), "user_id" : "abc001", "age" : 45, "status" : "A" }
{ "_id" : ObjectId("556d56b4aa73f980c884bf50"), "user_id" : "bcd001", "age" : 50, "status" : "A" }
{ "_id" : ObjectId("556d56b4aa73f980c884bf51"), "user_id" : "cde001", "age" : 20, "status" : "A" }
{ "_id" : ObjectId("556d56b5aa73f980c884bf53"), "user_id" : "def001", "age" : 30, "status" : "B" }
{ "_id" : ObjectId("556d6562aa73f980c884bf54"), "age" : 10, "status" : "A" }
検索フィールドを指定する
// SQL SELECT id, user_id, status FROM users
// Mongo
db.users.find(
{},
{user_id: 1, status: 1}
)
// 実行結果(ageは含まれない)
{ "_id" : ObjectId("556d5643aa73f980c884bf4f"), "user_id" : "abc001", "status" : "A" }
{ "_id" : ObjectId("556d56b4aa73f980c884bf50"), "user_id" : "bcd001", "status" : "A" }
{ "_id" : ObjectId("556d56b4aa73f980c884bf51"), "user_id" : "cde001", "status" : "A" }
{ "_id" : ObjectId("556d56b5aa73f980c884bf53"), "user_id" : "def001", "status" : "B" }
{ "_id" : ObjectId("556d6562aa73f980c884bf54"), "status" : "A" }
検索フィールドを指定する(_idを除く)
// SQL SELECT user_id, status FROM users
// Mongo
db.users.find(
{},
{user_id: 1, status: 1, _id: 0}
)
// 実行結果(_idが含まれない)
{ "user_id" : "abc001", "status" : "A" }
{ "user_id" : "bcd001", "status" : "A" }
{ "user_id" : "cde001", "status" : "A" }
{ "user_id" : "def001", "status" : "B" }
{ "status" : "A" }
検索条件を指定する(等価比較)
// SQL SELECT * FROM users WHERE status = "A"
// Mongo
db.users.find(
{status: "A"}
)
// 実行結果(status=Aのデータのみ)
{ "_id" : ObjectId("556d5643aa73f980c884bf4f"), "user_id" : "abc001", "age" : 45, "status" : "A" }
{ "_id" : ObjectId("556d56b4aa73f980c884bf50"), "user_id" : "bcd001", "age" : 50, "status" : "A" }
{ "_id" : ObjectId("556d56b4aa73f980c884bf51"), "user_id" : "cde001", "age" : 20, "status" : "A" }
{ "_id" : ObjectId("556d6562aa73f980c884bf54"), "age" : 10, "status" : "A" }
検索条件を指定する(非等価比較)
// SQL SELECT * FROM users WHERE status != "A"
// Mongo
db.users.find(
{status: { $ne: "A" }}
)
// 実行結果(status!=Aのデータのみ)
{ "_id" : ObjectId("556d56b5aa73f980c884bf53"), "user_id" : "def001", "age" : 30, "status" : "B" }
検索条件を複数指定する
// SQL SELECT * FROM users WHERE status = "A" AND age = 50
// Mongo
db.users.find(
{status: "A", age: 50}
)
// 実行結果(status=A AND age=50 のデータのみ)
{ "_id" : ObjectId("556d56b4aa73f980c884bf50"), "user_id" : "bcd001", "age" : 50, "status" : "A" }
OR条件を指定する
// SQL SELECT * FROM users WHERE status = "A" OR age = 50
// Mongo
db.users.find(
{$or: [{status: "A"} , {age: 50}]}
)
// 実行結果(status="A" OR age=50 のデータ)
{ "_id" : ObjectId("556d5643aa73f980c884bf4f"), "user_id" : "abc001", "age" : 45, "status" : "A" }
{ "_id" : ObjectId("556d56b4aa73f980c884bf50"), "user_id" : "bcd001", "age" : 50, "status" : "A" }
{ "_id" : ObjectId("556d56b4aa73f980c884bf51"), "user_id" : "cde001", "age" : 20, "status" : "A" }
{ "_id" : ObjectId("556d6562aa73f980c884bf54"), "age" : 10, "status" : "A" }
大小比較を指定する(>演算子)
// SQL SELECT * FROM users WHERE age > 25
// Mongo
db.users.find(
{age: {$gt: 25}}
)
// 実行結果(age>25 のデータ)
{ "_id" : ObjectId("556d5643aa73f980c884bf4f"), "user_id" : "abc001", "age" : 45, "status" : "A" }
{ "_id" : ObjectId("556d56b4aa73f980c884bf50"), "user_id" : "bcd001", "age" : 50, "status" : "A" }
{ "_id" : ObjectId("556d56b5aa73f980c884bf53"), "user_id" : "def001", "age" : 30, "status" : "B" }
大小比較を指定する(>=演算子)
// SQL SELECT * FROM users WHERE age >= 25
// Mongo
db.users.find(
{age: {$gte: 25}}
)
// 実行結果(age>=25 のデータ)
{ "_id" : ObjectId("556d5643aa73f980c884bf4f"), "user_id" : "abc001", "age" : 45, "status" : "A" }
{ "_id" : ObjectId("556d56b4aa73f980c884bf50"), "user_id" : "bcd001", "age" : 50, "status" : "A" }
{ "_id" : ObjectId("556d56b5aa73f980c884bf53"), "user_id" : "def001", "age" : 30, "status" : "B" }
大小比較を指定する(<演算子)
// SQL SELECT * FROM users WHERE age < 25
// Mongo
db.users.find(
{age: {$lt: 25}}
)
// 実行結果(age<25 のデータ)
{ "_id" : ObjectId("556d56b4aa73f980c884bf51"), "user_id" : "cde001", "age" : 20, "status" : "A" }
{ "_id" : ObjectId("556d6562aa73f980c884bf54"), "age" : 10, "status" : "A" }
大小比較を指定する(<=演算子)
// SQL SELECT * FROM users WHERE age <= 25
// Mongo
db.users.find(
{age: {$lte: 25}}
)
// 実行結果(age<=25 のデータ)
{ "_id" : ObjectId("556d56b4aa73f980c884bf51"), "user_id" : "cde001", "age" : 20, "status" : "A" }
{ "_id" : ObjectId("556d6562aa73f980c884bf54"), "age" : 10, "status" : "A" }
LIKE検索を行う(前方後方一致)
// SQL SELECT * FROM users WHERE user_id like "%bc%"
// Mongo
db.users.find(
{user_id: /bc/}
)
// 実行結果(user_id like "%bc%" のデータ)
{ "_id" : ObjectId("556d5643aa73f980c884bf4f"), "user_id" : "abc001", "age" : 45, "status" : "A" }
{ "_id" : ObjectId("556d56b4aa73f980c884bf50"), "user_id" : "bcd001", "age" : 50, "status" : "A" }
LIKE検索を行う(後方一致)
// SQL SELECT * FROM users WHERE user_id like "bc%"
// Mongo
db.users.find(
{user_id: /^bc/}
)
// 実行結果(user_id like "bc%" のデータ)
{ "_id" : ObjectId("556d56b4aa73f980c884bf50"), "user_id" : "bcd001", "age" : 50, "status" : "A" }
IN句で検索する
// SQL SELECT * FROM users WHERE age IN (20, 45)
// Mongo
db.users.find(
{age: {$in: [20, 45]}}
)
// 実行結果(user_id like "bc%" のデータ)
{ "_id" : ObjectId("556d5643aa73f980c884bf4f"), "user_id" : "abc001", "age" : 45, "status" : "A" }
{ "_id" : ObjectId("556d56b4aa73f980c884bf51"), "user_id" : "cde001", "age" : 20, "status" : "A" }
DISTINCTを指定する
// SQL SELECT DISTINCT status FROM users
// Mongo
db.users.distinct("status")
// 実行結果 [ "A", "B" ]
DISTINCT結果の件数を取得する
// SQL SELECT COUNT(DISTINCT status) FROM users
// Mongo
db.users.distinct("status").length
// 実行結果 2
ソートを指定する(昇順)
// SQL SELECT * FROM users ORDER BY user_id ASC
// Mongo
db.users.find({}).sort(
{user_id: 1}
)
// 実行結果(ORDER BY user_id ASC のデータ)
{ "_id" : ObjectId("556d6562aa73f980c884bf54"), "age" : 10, "status" : "A" }
{ "_id" : ObjectId("556d5643aa73f980c884bf4f"), "user_id" : "abc001", "age" : 45, "status" : "A" }
{ "_id" : ObjectId("556d56b4aa73f980c884bf50"), "user_id" : "bcd001", "age" : 50, "status" : "A" }
{ "_id" : ObjectId("556d56b4aa73f980c884bf51"), "user_id" : "cde001", "age" : 20, "status" : "A" }
{ "_id" : ObjectId("556d56b5aa73f980c884bf53"), "user_id" : "def001", "age" : 30, "status" : "B" }
ソートを指定する(降順)
// SQL SELECT * FROM users ORDER BY user_id DESC
// Mongo
db.users.find({}).sort(
{user_id: -1}
)
// 実行結果(ORDER BY user_id DESC のデータ)
{ "_id" : ObjectId("556d56b5aa73f980c884bf53"), "user_id" : "def001", "age" : 30, "status" : "B" }
{ "_id" : ObjectId("556d56b4aa73f980c884bf51"), "user_id" : "cde001", "age" : 20, "status" : "A" }
{ "_id" : ObjectId("556d56b4aa73f980c884bf50"), "user_id" : "bcd001", "age" : 50, "status" : "A" }
{ "_id" : ObjectId("556d5643aa73f980c884bf4f"), "user_id" : "abc001", "age" : 45, "status" : "A" }
{ "_id" : ObjectId("556d6562aa73f980c884bf54"), "age" : 10, "status" : "A" }
件数を数える
// SQL SELECT COUNT(*) FROM users
// Mongo db.users.count() // または db.users.find().count()
// 実行結果 5
件数を数える(フィールド指定)
// SQL SELECT COUNT(user_id) FROM users
// Mongo
db.users.count({user_id: {$exists: true}})
// または
db.users.find({user_id: {$exists: true}}).count()
// 実行結果 4
LIMIT句を指定する
// SQL SELECT * FROM users LIMIT 1
// Mongo db.users.findOne() // または db.users.find().limit(1)
// 実行結果
{ "_id" : ObjectId("556d5643aa73f980c884bf4f"), "user_id" : "abc001", "age" : 45, "status" : "A" }
LIMIT句でOFFSETを指定する
// SQL SELECT * FROM users LIMIT 2 SKIP 1
// Mongo db.users.find().limit(2).skip(1)
// 実行結果
{ "_id" : ObjectId("556d56b4aa73f980c884bf50"), "user_id" : "bcd001", "age" : 50, "status" : "A" }
{ "_id" : ObjectId("556d56b4aa73f980c884bf51"), "user_id" : "cde001", "age" : 20, "status" : "A" }
実行計画を確認する
// SQL EXPLAIN SELECT * FROM users WHERE status = "A"
// Mongo
db.users.find({status: "A"}).explain()
// 実行結果
{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 4,
"nscannedObjects" : 5,
"nscanned" : 5,
"nscannedObjectsAllPlans" : 5,
"nscannedAllPlans" : 5,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"server" : "MyUser.local:27017",
"filterSet" : false
}
参考資料
今回の記事を書くために以下を参考にしました。ありがとうございます。SQL to MongoDB Mapping Chart — MongoDB Manual
はじめてのMongoDB | Slideshare
最後に
Mongoのfindは本当にいろいろな検索ができて便利ですね。ただこれらの情報がWeb上では少し断片的になっているなぁと思い、今後の自分のためにもまとめてみました。どなたかの何かの役に立てば幸いです。最後になりますが本ブログでは、フロントエンドのネタを中心に情報を発信しています。気になった方はぜひ、RSSやTwitterをフォローして頂けますと幸いです ^ ^。
最後までご覧頂きましてありがとうございました!

