MongoDB安裝和入門
MongoDB是一個文檔資料庫,提供好的性能,領先的非關係型資料庫。採用BSON存儲文檔數據。2007年10月,MongoDB由
優勢:
-
面向文檔的存儲:以 JSON 格式的文檔保存數據。
-
任何屬性都可以建立索引。
-
複製以及高可擴展性。
-
自動分片。
-
豐富的查詢功能。
-
快速的即時更新。
-
來自 MongoDB 的專業支援。
選擇版本、系統環境、包 。以下將以tgz包 為例
上傳完成後解壓
tar zxvf mongodb-linux-x86_64-rhel70-4.2.8.tgz
移動到/usr/local/mongodb目錄(非必須)
mv mongodb-linux-x86_64-rhel70-4.2.8/ /usr/local/mongodb
創建專門的負責的用戶並賦予許可權(非必須)
cd /usr/local/mongodb groupadd mongodb useradd -s /sbin/nologin -g mongodb -M mongodb mkdir data log run chown -R mongodb:mongodb data log run
在/usr/local/mongodb 裡面創建一個配置文件 mongodb.conf
vim mongodb.conf 並寫入下面的資訊:
bind_ip=0.0.0.0 port=27017 dbpath=/usr/local/mongodb/data/ logpath=/usr/local/mongodb/log/mongodb.log pidfilepath =/usr/local/mongodb/run/mongodb.pid logappend=true fork=true maxConns=500 noauth = true # 配置解釋: # fork=true 運行在後台 # logappend=true 如果為 true,當 mongod/mongos 重啟後,將在現有日誌的尾部繼續添加日誌。否則,將會備份當前日誌文件,然後創建一個新的日誌文件;默認為 false。 # noauth = true 不需要驗證用戶密碼 # maxConns=500 最大同時連接數 默認2000
以上是MongoDB的安裝與啟動的準備工作,可直接啟動 啟動命令:
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/mongodb.conf
配置環境變數
vim /etc/profile
在/etc/profile文件末尾添加一行:
export PATH=/usr/local/mongodb/bin:$PATH
讓其生效:
source /etc/profile
查看當前mongodb的版本:
mongod --version
mongo
查看MongoDB自帶的原始資料庫
show dbs
local:這個數據永遠不會被複制,可以用來存儲限於本地單台伺服器的任意集合
config:當mongo用於分片設置時,config資料庫在內部使用。用於保存分片的相關資訊
use test
刪除資料庫:db.dropDatabase()
db.dropDatabase()
用於刪除已經持久化的資料庫,剛創建在記憶體中的資料庫刪除無效
相當於恢復到剛創建test資料庫且並沒有持久化到磁碟的狀態
創建一個集合:db.createCollection(“集合名稱”)
db.createCollection("西遊記")
查看所有的集合show tables 或者 show collections
show tables
show collections
刪除集合:db.集合名稱.drop()
db.西遊記.drop()
db.xyj.insert({name:"豬八戒",age:28,gender:"男"})
這裡會自動創建xyj這個集合
查詢數據
db.xyj.find()
可以看到,我們沒有指定id,MongoDB自動給我們生成了一條id,我們也可以指定id,如下
添加一條指定id的數據
db.xyj.insertOne({_id:"workd",name:"豬八戒",age:28,gender:"男"})
當我們向集合中插入文檔時,如果沒有給文檔指定 _id屬性,則資料庫會自動為文檔添加 _id該屬性用來作為文檔的唯一標識 _id
我們可以自己指定,如果我們指定了資料庫就不會在添加了,如果自己指定 _id 也必須確保它的唯一性
批量添加數據
db.xyj.insert([ ... {name:"沙和尚",age:38,gender:"男"}, ... {name:"白骨精",age:16,gender:"女"}, ... {name:"蜘蛛精",age:14,gender:"女"} ... ])
或者以下命令也是一樣的效果
db.xyj.insertMany([ {name:"沙和尚",age:38,gender:"男"}, {name:"白骨精",age:16,gender:"女"}, {name:"蜘蛛精",age:14,gender:"女"} ])
總結:
db.collection.insertOne() 插入一個文檔對象
db.collection.insertMany() 插入多個文檔對象
額外小知識
try{ db.xyj.insert([ {name:"沙和尚",age:38,gender:"男"}, {name:"白骨精",age:16,gender:"女"}, {name:"蜘蛛精",age:14,gender:"女"} ]); }catch(e){ print(e) }
可以知道那條插入失敗
全量修改操作
db.xyj.update({_id: ObjectId("5f0189a368c6a000f725c87b")},{age:NumberInt(30)})
執行效果:這條數據只有age一個欄位了
局部修改操作
db.xyj.update({_id:ObjectId("5f0189a368c6a000f725c87c")},{$set:{age:NumberInt(30)}})
執行效果:只會修改這條數據的某個欄位
批量修改
db.xyj.update({name:"蜘蛛精"},{$set:{age:NumberInt(100)}},{multi:true})
注意:在修改條數據時,必須要加上第三個參數{multi:true},否則只會修改一條數據
欄位增加操作
db.xyj.update({_id:"workd"},{$inc:{age:NumberInt(1)}})
刪除文檔
db.xyj.remove({_id:"workd"})
刪除文檔欄位
db.xyj.update({"_id": ObjectId("5f0189a368c6a000f725c87d")}, {"$unset": {"name":1}})
刪除所有
db.xyj.remove({})
數組操作
插入測試數據
db.xyj.insertMany([ {name:"沙和尚",age:38,gender:"男",hobby:["打籃球","吃喝"]}, {name:"白骨精",age:16,gender:"女",hobby:["吃喝"]}, {name:"蜘蛛精",age:14,gender:"女",hobby:["跑步","打乒乓球"]}, {name:"唐生",age:25,gender:"男",hobby:["坐禪","吃喝"]} ]);
添加數組內容($push)
db.xyj.update({"name": "白骨精"}, {"$push": {"hobby": "念佛"}})
db.xyj.update({"_id": ObjectId("5f019375caf12a975c177d10")}, {"$pop": {"hobby": 1}})
刪除第一個元素
db.xyj.update({"_id": ObjectId("5f019375caf12a975c177d13")}, {"$pop": {"hobby": -1}})
db.xyj.update({"_id": ObjectId("5f019375caf12a975c177d11")}, {"$pull": {"hobby": "念佛" }})
添加一條測試數據
db.xyj.insert({name:"豬八戒",age:28,gender:"男",address: [{place: "nanji", tel: 123}, {place: "dongbei", tel: 321}]});
更新嵌套數組的值($set)
db.xyj.update({"_id": ObjectId("5f019881caf12a975c177d14")}, {"$set": {"address.0.tel": 213}})
數組查詢:
db.xyj.find({"hobby":"跑步"})
多個元素的查詢
db.xyj.find({"hobby":{"$all": ["跑步", "打乒乓球"]}})
只有hobby數組同時存在跑步和打乒乓球才會匹配
限制數組長度查詢
db.xyj.find({"hobby": {"$size": 1}})
只有數組的長度是1才會匹配
投影查詢
db.xyj.find({name:"白骨精"},{name:1,_id:0})
1表示顯示 0表示強制隱藏
相當於sql裡面只查某些欄位
按欄位條件查詢
db.xyj.find({name:"白骨精"})
按欄位條件查詢並只返回一條
db.xyj.findOne({gender:"女"})
其他api就不都演示了
組合查詢:
語法:db.xyj.find($and:[{},{},{}]) //查詢年級大於20小於50的 db.xyj.find({$and:[{age:{$gt:NumberInt(20)}},{age:{$lt:NumberInt(50)}}]}) //查詢名字里有」精「的或者年紀大於30的 db.xyj.find({$or:[{age:{$gt:NumberInt(30)}},{name:/精/}]})
比較查詢:
db.xyj.find({age:{$gt:NumberInt(20)}}) //查詢年級大於20歲的 $gt--》大於 $lt--》小於 $gte--》大於等於 $lte--》小於等於 $ne---》不等於(不等於不一定要用於數字)
包含查詢:
db.xyj.find({age:{$in:[28,38]}})
不包含:
db.xyj.find({age:{$nin:[28,38]}})
Like:
db.xyj.find({"name": /精/})
統計查詢:
db.xyj.count()或者db.xyj.count({欄位:條件})
取模:
db.xyj.find({"age": {$mod: [5, 1]}}) 比如我們要匹配 age % 5 == 1
是否存在($exists)
db.xyj.find({"love": {"$exists": true}}) // 如果存在欄位love,就返回 db.xyj.find({"love": {"$exists": false}}) // 如果不存在欄位love,就返回
分頁查詢
limit:顯示幾條記錄
skip:跳過幾條記錄
第一次查詢:db.xyj.find().limit(2)
第一次查詢:db.xyj.find().limit(2).skip(2)
結合排序:db.xyj.find().limit(2).skip(2).sort({age:1}) // 1代表升序,-1代表降序
執行順序: sort > skip > limit
描述 | 語法 | |
---|---|---|
$project | 數據投影,主要用於重命名,增加,刪除欄位 | db.article.aggregate({ $project : {title : 1 ,author : 1 ,}}); |
$match | 過濾,篩選符合條件的文檔,作為下一階段輸入 | db.articles.aggregate( [{ $match : { score : { $gt : 70, $lte : 90 } } },{ $group: { _id: null, count: { $sum: 1 } } }] ); |
$limit | 限制經過管道的文檔數量 | db.article.aggregate({ $limit : 5 }); |
$skip | 待操作集合處理前跳過部分文檔 | db.article.aggregate({ $skip : 5 }); |
$unwind | 將數組拆分成獨立欄位 | db.article.aggregate({$project:{author:1,title:1,tags:1}},{$unwind:"$tags"}) |
$group | 對數據進行分組 | db.article.aggregate({ $group : {_id : "$author",docsPerAuthor : { $sum : 1 },viewsPerAuthor : { $sum : "$pageViews" }}}); |
$sort | 對文檔按照指定欄位排序 | db.users.aggregate( { $sort : { age : -1, posts: 1 } }); |
$sample | 隨機選擇從其輸入指定數量的文檔。 | { $sample: { size: <positive integer> } } |
$out | 必須為pipeline最後一個階段管道,因為是將最後計算結果寫入到指定的collection中 | |
$indexStats | 返回數據集合的每個索引的使用情況 |
插入測試數據
document1=({name:'dogOne',age:1,tags:['animal','dog'],type:'dog',money:[{min:100},{norm:200},{big:300}]}); document2=({name:'catOne',age:3,tags:['animal','cat'],type:'cat',money:[{min:50},{norm:100},{big:200}]}); document3=({name:'catTwo',age:2,tags:['animal','cat'],type:'cat',money:[{min:20},{norm:50},{big:100}]}); document4=({name:'dogTwo',age:5,tags:['animal','dog'],type:'dog',money:[{min:300},{norm:500},{big:700}]}); document5=({name:'appleOne',age:0,tags:['fruit','apple'],type:'apple',money:[{min:10},{norm:12},{big:13}]}); document6=({name:'appleTwo',age:0,tags:['fruit','apple'],type:'apple',money:[{min:10},{norm:12},{big:13}]}); document7=({name:'pineapple',age:0,tags:['fruit','pineapple'],type:'pineapple',money:[{min:8},{norm:9},{big:10}]}); db.mycol.insert(document1) db.mycol.insert(document2) db.mycol.insert(document3) db.mycol.insert(document4) db.mycol.insert(document5) db.mycol.insert(document6) db.mycol.insert(document7)
假定我們想提取money中min為100的文檔,並且只輸出名稱和money數組中的min那一項
db.mycol.aggregate( {$match:{'money.min':100}}, {$project:{_id:0,name:'$name',minprice:'$money.min'}} )
假定我們想提取money中min小於100的文檔,並且限制3個文檔,跳過一個文檔再顯示
通過type類型來對數據進行分類,並且同時統計他們的年齡age總和
db.mycol.aggregate( {$group:{_id:'$type',sumage:{$sum:'$age'}}} )
按照年齡對數據進行排序
db.mycol.aggregate( {$group:{_id:'$type',sumage:{$sum:'$age'}}}, {$sort:{sumage:1}} )