[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をフォローして頂けますと幸いです ^ ^。
最後までご覧頂きましてありがとうございました!