基本
庫的基本操作
-
創(chuàng)建庫
# 創(chuàng)建并且切換到demo use demo; # 展示當(dāng)前所在庫位置 db; # 查看所有數(shù)據(jù)庫 show dbs;注意: 我們使用use 創(chuàng)建demo庫時,再用 show dbs時,發(fā)現(xiàn)沒有剛剛創(chuàng)建的demo庫,這是因為剛創(chuàng)建的庫只有在插入數(shù)據(jù)后才能顯示出來。
-
刪除數(shù)據(jù)庫
# 切換到demo庫 use demo; # 刪除當(dāng)前的所在庫 db.dropDatabase();
增刪改查
-
條件查詢find
# 為了方便查詢先插入一定數(shù)量的數(shù)據(jù) for(var i=0; i<100; i++) db.book.insert({"num": i, "name": "ss"+i}) # 查詢 num為 99 的那條數(shù)據(jù) db.book.find({num: 99}); # 查詢 num 為99 并且只返回name字段(_id 是總是會返回的,所以這里會返回_id和num兩個字段的) db.book.find({num: 99}, {"name": true}); -
條件查詢 findOne
有時候我們?yōu)榱瞬樵償?shù)據(jù)是否存在,沒必要查詢出所有的數(shù)據(jù),此時我們可以使用findOne 可以節(jié)省游標(biāo)不必要的開銷。
# 查詢 num 是否存在小于3的集合、 db.book.findOne({"num": {$lt: 3}}); -
分頁 limit
其實(shí)mongo里的分頁可以借助 limit 來實(shí)現(xiàn)的。可以先以某個屬性字段進(jìn)程排序,然后用limit來進(jìn)行限制條數(shù),達(dá)到分頁的目的
# 倒序獲取50 - 40 的數(shù)據(jù) db.book.find({num: {$lt: 0}}).sort({num: -1}).limit(10); -
修改 update
# num 為99 ,修改 name 為 hhh99 db.book.update({"num": 99}, {$set: {"name": "hhh99"}}); # 批量修改多個(一般的首先想到的是下面這樣寫, 其實(shí)是錯誤的),只會修改第一條數(shù)據(jù) db.book.update({"num": {$lt: 10}}, {$set: {"name": "hhh"}}); # 上面的寫法是錯誤的,那么正確的寫法是 db.book.update({"num": {$lt: 10}}, {$set: {"name": "hhh"}}, {"multi": true}); # output > db.book.update({"num": {$lt: 10}}, {$set: {"name": "hhh"}}); WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.book.update({"num": {$lt: 10}}, {$set: {"name": "hhh"}}, {"multi": true}); WriteResult({ "nMatched" : 10, "nUpserted" : 0, "nModified" : 9 })注意: 批量修改的話,一定不要忘記
{"multi": true} -
刪除 remove
# 刪除 num 大于等于 95 的集合 db.book.remove({"num": {$gte: 95}});
高級查詢
-
$gt(大于), $lt(小于), $gte(大于等于), $lte(小于等于), $ne(不等于)# 查詢num 大于等于 45 小于65 的所有,并且顯示name字段 db.book.find({"num": {$gte: 45, $lt: 65}}, {"name": true}); -
$all匹配所有
這個屬性跟sql里的in有點(diǎn)類似,但是又不完全一樣使用# 先在上面的集合中添加幾個數(shù)據(jù)字段數(shù)據(jù) db.book.update({num: 0}, {$set: {"age": [5, 6, 7]}}); db.book.update({num: 1}, {$set: {"age": [6, 7, 8]}}); db.book.update({num: 2}, {$set: {"age": [7, 8, 9]}}); db.book.update({num: 3}, {$set: {"age": [8, 9, 10]}}); db.book.update({num: 4}, {$set: {"age": [9, 10, 11]}}); db.book.update({num: 5}, {$set: {"age": [10, 11, 12]}}); # 查詢 age 有7和8 的集合 db.book.find({age: {$all: [7, 8]}}); # ouput > db.book.find({age: {$all: [7, 8]}}); { "_id" : ObjectId("5a0fd6ffab65c141825ab036"), "num" : 1, "name" : "hhh", "age" : [ 6, 7, 8 ] } { "_id" : ObjectId("5a0fd6ffab65c141825ab037"), "num" : 2, "name" : "hhh", "age" : [ 7, 8, 9 ] }從上面我們可以看出,這里輸出的只是7和8都同時存在的,而不是7或者8存在的集合。in 的用法則是或者的關(guān)系。
-
$exist判斷字段是否存在在關(guān)系型數(shù)據(jù)庫里也有這樣關(guān)鍵字,但是mongo里的exist卻意義完全不一樣,這里只是判斷文檔里的某個字段是否存在。
# 查詢存在age字段的集合 db.book.find({"age": {$exists: true}}); # output > db.book.find({"age": {$exists: true}}); { "_id" : ObjectId("5a0fd6ffab65c141825ab035"), "num" : 0, "name" : "hhh", "age" : [ 5, 6, 7 ] } { "_id" : ObjectId("5a0fd6ffab65c141825ab036"), "num" : 1, "name" : "hhh", "age" : [ 6, 7, 8 ] } { "_id" : ObjectId("5a0fd6ffab65c141825ab037"), "num" : 2, "name" : "hhh", "age" : [ 7, 8, 9 ] } { "_id" : ObjectId("5a0fd6ffab65c141825ab038"), "num" : 3, "name" : "hhh", "age" : [ 8, 9, 10 ] } { "_id" : ObjectId("5a0fd6ffab65c141825ab039"), "num" : 4, "name" : "hhh", "age" : [ 9, 10, 11 ] } { "_id" : ObjectId("5a0fd6ffab65c141825ab03a"), "num" : 5, "name" : "hhh", "age" : [ 10, 11, 12 ] } -
如何查詢值為null?
# 添加一個值為 null 的字段 db.book.update({"num": 0}, {$set: {"size": null}}); # 查詢 size 為 null 的數(shù)據(jù) db.book.find({"size": null}); #ouput > db.book.find({"size": null}); { "_id" : ObjectId("5a0fd6ffab65c141825ab035"), "num" : 0, "name" : "hhh", "age" : [ 5, 6, 7 ], "size" : null } { "_id" : ObjectId("5a0fd6ffab65c141825ab036"), "num" : 1, "name" : "hhh", "age" : [ 6, 7, 8 ] } { "_id" : ObjectId("5a0fd6ffab65c141825ab037"), "num" : 2, "name" : "hhh", "age" : [ 7, 8, 9 ] } ... 可以看出不僅查詢出 size 為 null, 還查出來size 不存在的值。所以,null 不僅能查詢他自身,還能查詢不存在的字段。 # 所以上面還需要再加上一個條件 size 屬性存在 db.book.find({"size": null, "size": {$exists: true}}); 或者 db.book.find({"size": {$in: [null], $exists: true}}); -
$in和$nin的用法上面提過
$all的用法,必須要求所給出的值一定要存在。這里的$in跟之前學(xué)過關(guān)系型數(shù)據(jù)庫的in是很相似的。# 查詢num為 7, 9, 10這三項的數(shù)據(jù) db.book.find({num: {$in: [7, 8, 9]}}); # output > db.book.find({num: {$in: [7, 8, 9]}}); { "_id" : ObjectId("5a0fd6ffab65c141825ab03c"), "num" : 7, "name" : "hhh" } { "_id" : ObjectId("5a0fd6ffab65c141825ab03d"), "num" : 8, "name" : "hhh" } { "_id" : ObjectId("5a0fd6ffab65c141825ab03e"), "num" : 9, "name" : "hhh" }$nin的用法則剛好和$in的相反。 -
正則表達(dá)式
關(guān)系型數(shù)據(jù)庫里有l(wèi)ike做到模糊查詢,這里mongo可以用正則表達(dá)式進(jìn)行更加強(qiáng)大的模糊查詢。
# 查詢 name 為 hhh開頭的 db.book.find({name: /^hhh.*/}); # 查詢 name 非 hhh開頭的 db.book.find({name: {$not: /^hh.*/}}); -
$not和$ne區(qū)別$not一般會與 正則表達(dá)式配合使用。$ne一般用于一個確切的值進(jìn)行相反查詢。 -
count根據(jù)條件統(tǒng)計數(shù)量。
db.book.count({num: {$gte: 90}}); -
skip 重置記錄起點(diǎn)
也就是跳過前面第幾條數(shù)據(jù)然后向后查詢。
# 以10 為頁數(shù) 進(jìn)行分頁查詢 db.book.find().skip(0).limit(10); db.book.find().skip(10).limit(10); db.book.find().skip(20).limit(10); ... -
sort 排序
# 升序 db.find.find().sort({num: 1}); # 降序 db.find.find().sort({num: -1});
索引
-
概述
在關(guān)系型數(shù)據(jù)庫里,也有索引這樣的概念,這里意思是一樣的,都是為了提高查詢效率,為一些字段添加索引。
-
_id 默認(rèn)主鍵索引
當(dāng)一個文檔創(chuàng)建時,默認(rèn)的主鍵 _id 就自帶了一個索引。
Note
In sharded clusters, if you do not use the _id field as the shard key, then your application must ensure the uniqueness of the values in the _id field to prevent errors. This is most-often done by using a standard auto-generated ObjectId.
上面引用官網(wǎng)的_id 補(bǔ)充說明, _id 可以刪除的,但是在分布式的mongo中,默認(rèn)生成的_id 是可以快速定位到一個節(jié)點(diǎn)上查找數(shù)據(jù)的,也就是最好不要改寫_id 的生成規(guī)則,而是采用默認(rèn)的標(biāo)準(zhǔn)即可。
-
創(chuàng)建index
關(guān)于createIndex 的接口,可以參考:https://docs.mongodb.com/manual/reference/method/db.collection.dropIndex/
# 為 book 創(chuàng)建 num字段的索引 db.book.createIndex({num: 1}, {name: "num_index"});補(bǔ)充: 上面我們的創(chuàng)建索引時,字段后面的值是一個數(shù)字1 ,這里的含義是我們根據(jù)該字段的值創(chuàng)建一個升序的索引;如果為-1的話,這里就創(chuàng)建的是降序的索引。 我們還可以創(chuàng)建 "position.age" 這樣的多層級的索引。
-
查看索引
db.book.getIndexes(); # output > db.book.getIndexes(); [ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "demo.book" }, { "v" : 2, "key" : { "num" : 1 }, "name" : "num_index", "ns" : "demo.book" } ] -
刪除index
db.book.dropIndex("num_index");