MongoDBを操作してみる
背景
今更ながらMongoDBを再学習中です。
今回は、コマンドラインからMongoDBを操作してみます。
操作
データの追加と参照
ドキュメントusers
に{username:"hashito"}
を追加してみます。
test> db.users.insert({username:"hashito"})
DeprecationWarning: Collection.insert() is deprecated. Use insertOne, insertMany, or bulkWrite.
{
acknowledged: true,
insertedIds: { '0': ObjectId("63509ddb39e7cde9bce5f310") }
}
MongoDBではアクセスした瞬間にドキュメントが生成されるようです。
基本的な方法で、データを参照してみます。
また、insert
は非推奨になっていることがわかります。
insertOne
かinsertMany
、bulkWrite
の利用を推奨されています。
こちらの記載通り1件追加の場合はinsertOne
を利用し、複数個の場合はinsertMany
かbulkWrite
を利用すれば問題ないものと思われます。
test> db.users.find()
[ { _id: ObjectId("63509ddb39e7cde9bce5f310"), username: 'hashito' } ]
.find()
は引数を利用することでフィルタリングなどもあるようですが、一旦は引数無しで利用します。
ドキュメントusers
の中にはデータが1つしかないことがわかります。
ドキュメントのデータ数をカウントしてみます。
db.users.count()
という関数を利用します。
test> db.users.count()
DeprecationWarning: Collection.count() is deprecated. Use countDocuments or estimatedDocumentCount.
1
count
という関数は非推奨であるためcountDocuments
かestimatedDocumentCount
を利用するように言われます。
2つを要望していますがどちらがいいという議論はあるようです…
test> db.users.countDocuments()
1
test> db.users.estimatedDocumentCount()
1
データを追加して結果を再確認してみます。
test> db.users.insert({username:"hashito2"})
{
acknowledged: true,
insertedIds: { '0': ObjectId("6350a7a139e7cde9bce5f311") }
}
test> db.users.estimatedDocumentCount()
2
test> db.users.countDocuments()
2
test> db.users.find()
[
{ _id: ObjectId("63509ddb39e7cde9bce5f310"), username: 'hashito' },
{ _id: ObjectId("6350a7a139e7cde9bce5f311"), username: 'hashito2' }
]
データのフィルタリング
.find
関数で引数を指定する事により、特定のusername
を持っているデータのみにフィルタリングする事ができます。
test> db.users.find({username:"hashito"})
[ { _id: ObjectId("63509ddb39e7cde9bce5f310"), username: 'hashito' } ]
hashito2
という名前のユーザは検索されない事がわかります。
データの更新
update
関数を利用することでデータを更新する事ができます。
test> db.users.update({username:"hashito"},{$set:{city:"tokyo"}})
DeprecationWarning: Collection.update() is deprecated. Use updateOne, updateMany, or bulkWrite.
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1,
upsertedCount: 0
}
test> db.users.find({username:"hashito"})
[
{
_id: ObjectId("63509ddb39e7cde9bce5f310"),
username: 'hashito',
city: 'tokyo'
}
]
こちらのupdate
関数も同様に非推奨ですね…(私が参考にしている本が古いため申し訳ないです。)
アップデートする対象が1件の場合はupdateOne
で複数個の場合は updateMany
bulkWrite
のいづれかを利用してください。
値の削除を行う場合もupdate
系の関数を利用します。
test> db.users.updateOne({username:"hashito"},{$unset:{city:1}})
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1,
upsertedCount: 0
}
test> db.users.find({username:"hashito"})
[ { _id: ObjectId("63509ddb39e7cde9bce5f310"), username: 'hashito' } ]
少し高度な検索
少し高度な検索を行うため、要素を追加します。
f.movies
に["a","b"]
または["x","b"]
を追加しています。
test> db.users.update({username:"hashito"},{$set:{f:{movies:["a","b"]}}})
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1,
upsertedCount: 0
}
test> db.users.update({username:"hashito2"},{$set:{f:{movies:["x","b"]}}})
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 1,
upsertedCount: 0
}
test> db.users.find()
[
{
_id: ObjectId("63509ddb39e7cde9bce5f310"),
username: 'hashito',
f: { movies: [ 'a', 'b' ] }
},
{
_id: ObjectId("6350a7a139e7cde9bce5f311"),
username: 'hashito2',
f: { movies: [ 'x', 'b' ] }
}
]
この中で、f.movies.b
のみを持っているデータを抽出します。
test> db.users.find({"f.movies":"b"})
[
{
_id: ObjectId("63509ddb39e7cde9bce5f310"),
username: 'hashito',
f: { movies: [ 'a', 'b' ] }
},
{
_id: ObjectId("6350a7a139e7cde9bce5f311"),
username: 'hashito2',
f: { movies: [ 'x', 'b' ] }
}
]
この中で、f.movies.x
のみを持っているデータを抽出します。
test> db.users.find({"f.movies":"x"})
[
{
_id: ObjectId("6350a7a139e7cde9bce5f311"),
username: 'hashito2',
f: { movies: [ 'x', 'b' ] }
}
]
データの削除
remove
関数を利用すればデータの削除をできます。
このときにfind
と同じ形式でフィルタリングする事が可能です。
test> db.users.remove({"f.movies":"x"})
DeprecationWarning: Collection.remove() is deprecated. Use deleteOne, deleteMany, findOneAndDelete, or bulkWrite.
{ acknowledged: true, deletedCount: 1 }
test> db.users.find()
[
{
_id: ObjectId("63509ddb39e7cde9bce5f310"),
username: 'hashito',
f: { movies: [ 'a', 'b' ] }
}
]
find
の結果を見れば削除が成功している事がわかります。
こちらもremove
関数は非推奨のようです…
アップデートする対象が1件の場合はdeleteOne
またはfindOneAndDelete
で複数個の場合は deleteMany
bulkWrite
のいづれかを利用してください。
また、全て削除したい場合はdrop
関数を利用します。
test> db.users.drop()
true
test> db.users.find()
大量のデータ追加
MongoDBのインターフェイスはJavascriptになっています。
そのため、下記のようなコードを実行し大量のデータを追加する事ができます。
※データは挿入に数秒かかる場合があるためご注意ください。
test> for(i=0;i<20000;i++){db.numbers.insertOne({num:i})}
{
acknowledged: true,
insertedId: ObjectId("6350b49a39e7cde9bce64131")
}
test> db.numbers.countDocuments()
20000
最終的に2万個のデータが追加できたのがわかると思います。
余談
上記の様に、1個1個保存した場合に時間がかかってしまいます。
ですので、insertMany
を使って一括でデータを保存したほうが高速に保存ができるものと思います。
下記のコードは2000個の{num:x}
を作成しています。
test> db.numbers2.insertMany(new Array(20000).fill(0).map((v,i)=>{return {num:i}}))
実行したところ、数秒で終わりました。個別に1個ずつ追加するよりやっぱり早いですね…
test> db.numbers2.find({num:19})
[ { _id: ObjectId("6350bab139e7cde9bce64145"), num: 19 } ]
test> db.numbers2.count()
20000
Discussion