一、mongo批量生成數據
MongoDB存儲的是二進制的json(BSON)數據,底層是用js來實現的。
所以在MongoDB中可以將js的for循環代碼和我們的數據庫做操作指令一起配合來使用,在數據庫中批量插入數據。
> for(var i=0;i<1000;i++){
... db.test.insert({_id:i+1,name:'haha'+i})}
二、遊標
如果數據庫中數據量較大,比如剛剛插入的1000條,我們執行 db.test.find() 的話,
他會將所有的數據都查詢出來給我們,如果查詢的時候,像python中生成器那樣,每次只返回一個數據就比較方便。其實在MongoDB中也有類似生成器的東西,它就是 遊標 。
1、遊標的定義和聲明
mongo的遊標相當於python中的迭代器。通過將查詢結構定義給一個變量,這個變量就是遊標。通過這個遊標,我們可以每次獲取一個數據。
var cursor_name = db.test.find()
2、遊標的操作
> var mycursor = db.test.find().limit(5)
> mycursor.next()
{ "_id" : 1, "name" : "haha0" }
> mycursor.next()
{ "_id" : 2, "name" : "haha1" }
> mycursor.hasNext()//判斷遊標是否已經取到盡頭,|true表示沒有到盡頭。
true
> print(mycursor.next())//會顯示是一個bson格式的數據
[object BSON]
> printjson(mycursor.next())
{ "_id" : 4, "name" : "haha3" }
我們可以寫一個while循環來打印遊標結果:
> while(mycursor.hasNext()){printjson(mycursor.next())}
{ "_id" : 1, "name" : "haha0" }
{ "_id" : 2, "name" : "haha1" }
.
.
{ "_id" : 14, "name" : "haha13" }
{ "_id" : 15, "name" : "haha14" }
>
遊標的toArray()方法,方便我們可以看到所有行
> var mycursor = db.test.find().limit(5)
> mycursor.next()
{ "_id" : 1, "name" : "haha0" }
> mycursor.next()
{ "_id" : 2, "name" : "haha1" }
> mycursor.toArray()//看到所有行
[
{
"_id" : 3,
"name" : "haha2"
},
{
"_id" : 4,
"name" : "haha3"
},
{
"_id" : 5,
"name" : "haha4"
}
]
>> var mycursor = db.test.find().limit(5)
> mycursor.toArray()[2]//看到第二行
{ "_id" : 3, "name" : "haha2" }
3、cursor.forEach(回調函數)
> var getname = function(obj){print(obj.name)}
> var cursor = db.test.find().limit(10)
> cursor.forEach(getname)
haha0
haha1
haha2
haha3
haha4
haha5
haha6
haha7
haha8
haha9
4、分頁中的遊標應用
一般的,我們假設每頁N行,當前是page頁,就需要跳過(page-1)*N,再取N行,
在mysql中,用 limit,offset,N來實現;
在MongoDB中,用skip(),limit()函數來實現
> var mycursor = db.test.find().skip(90).limit(10)
> mycursor
{ "_id" : 91, "name" : "haha90" }
{ "_id" : 92, "name" : "haha91" }
{ "_id" : 93, "name" : "haha92" }
{ "_id" : 94, "name" : "haha93" }
{ "_id" : 95, "name" : "haha94" }
{ "_id" : 96, "name" : "haha95" }
{ "_id" : 97, "name" : "haha96" }
{ "_id" : 98, "name" : "haha97" }
{ "_id" : 99, "name" : "haha98" }
{ "_id" : 100, "name" : "haha99" }
三、創建索引
1、作用
- 索引提高查詢速度,降低寫入速度,[權衡常用的查詢字段,不必在太多列上建索引
- 在mongodb中,索引可以按字段升序/降序來創建,便於排序
- 默認是用btree來組織索引文件,2.4版本以後,也允許建立hash索引
2、常用命令
- 查看當前索引狀態:db.test.getIndexes()
- 創建普通單列索引:db.test.ensureIndex({field:1/-1}) //1爲正序,-1爲逆序
- 刪除單個索引:db.test.dropIndex({field:1/-1})
- 刪除所有索引:db.test.dropIndexes() //_id所在的列的索引不能刪除
- 創建多列索引:db.test.ensureIndex({field1:1/-1,field2:1/-1})
多列索引的使用範圍更廣,因爲一般情況下,我們都是通過多個字段來進行查詢數據的,這時候單列索引其實用不到。 兩個列一起建立索引其實就是將兩個列綁定到一起,來創建索引。 - 子文檔索引:
1.插入兩條帶子文檔的數據
db.shop. insert({name: 'N0kia' , SPC: {weight: 120 , area: ' taiwan ' } } ) ;
db.shop. insert({name: 'sanxing ' , SPC :{weight: 100 , area: 'hanguo'} } ) ;
2.查詢出產地在臺灣的手機
db.shop.find({'spc.area':'taiwan'})
3.給子文檔加索引
db.shop.ensureIndex({'spc.area':1})
- 唯一索引:{unique:true} ,唯一索引的列不能重複插入
db.collection.ensureIndex({field:1/‐1},{unique:true})
- hash索引
db.collection.ensureIndex({field:'hashed'})
四、MongoDB數據的導入導出
1、常用命令
導入/導出可以操作的是本地的mongodb服務器,也可以是遠程的
‐‐host host 主機
‐‐port port 端口
‐u username 用戶名
‐p passwd 密碼
2、mongoexport 導出json格式的文件
_id列總是導出。導出csv文件的時候,需要指定導出哪些列
‐d 庫名
‐c 表名
‐f field1,field2...列名
‐q 查詢條件
‐o 導出的文件名
‐‐type csv 導出csv格式(便於和傳統數據庫交換數據)
#例1、
mongoexport ‐d test ‐c news ‐o test.json
#只導出goods_id,goods_name列
mongoexport ‐d test ‐c goods ‐f goods_id,goods_name ‐o goods.json
# 只導出價格低於1000元的行
mongoexport ‐d test ‐c goods ‐f goods_id,shop_price ‐q ‘{shop_ price:{$lt:200}}’ ‐o goods.json
#csv
mongoexport ‐d shop ‐c goods ‐o goods.csv ‐‐type csv ‐f goods_id,cat_id,g oods_name,shop_price
3、Mongoimport 導入
‐d 待導入的數據庫
‐c 待導入的表(不存在會自己創建)
‐‐file 備份文件路徑
#導入json
mongoimport ‐d test ‐c goods ‐‐file ./goodsall.json
#導入csv
mongoimport ‐d test ‐c goods ‐‐type csv ‐f goods_id,goods_name ‐‐file ./g oodsall.csv
4、mongodump 導出二進制bson結構的數據及其索引信息
- 導出的文件放在以database命名的目錄下
- 每個表導出2個文件,分別是bson結構的數據文件, json的索引信息
- 如果不聲明表名, 導出所有的表
‐d 庫名
‐c 表名
mongodum -d test [-c 表名] 默認是導出到mongo下的dump目錄
5、mongorestore 導入二進制文件
二進制備份,不僅可以備份數據,還可以備份索引,備份數據比較小.速度比較快
mongorestore ‐d shop ‐c goods ‐‐dir ./dump/shop/goods.bson
五、replaction複製集
一般情況下,我們通常在機器上安裝了一個數據庫,這是我們的數據都是存在這個數據庫中的,如果有一天,因爲一些不可控因素導致數據庫宕機或者數據庫的文件丟失,此時損失就很大了。針對於這種問 題,我們希望有一個數據庫集,在我們其中一個數據庫進行插入的時候,其他數據庫也能插入數據,這樣 其中一臺服務器宕機了,也能夠使我們的數據正常存取。
在MongoDB中,是通過replaction複製集來實現此功能的。
在Windows下實現複製集的方法:
- 創建複製集之前,把所有的mongo服務器都關掉。
- 創建三個存儲數據庫的文件夾,用來保存數據文件。
- 打開三個cmd窗口,分別啓動三個mongodb,其中的–replSet就表示創建的數據集的名稱,必須指定相同的名稱纔可以。
mongod --dbpath C:\MongoDB\Server\3.4\data\m1 --logpath C:\MongoDB\Server\3.4\data\logs\mongo1.log --port 27017 --replSet rs
mongod --dbpath C:\MongoDB\Server\3.4\data\m2 --logpath C:\MongoDB\Server\3.4\data\logs\mongo2.log --port 27018 --replSet rs
mongod --dbpath C:\MongoDB\Server\3.4\data\m3 --logpath C:\MongoDB\Server\3.4\data\logs\mongo3.log --port 27019 --replSet rs
- 配置
1 var rsconf = {
2 _id:'rs',
3 members:[
4 {_id:0,host:'127.0.0.1:27017'},
5 {_id:1,host:'127.0.0.1:27018'},
6 {_id:2,host:'127.0.0.1:27019'}
7 ]
8 }
這時候我們可以打印rsconf來看一下
printjson(rsconf)
接下來需要將配置初始化
rs.initiate(rsconf)
現在我們看到,現在登錄客戶端已經不是那臺機器,而是rs複製集
我們在主機上插入一條數據,再從機上必須輸入rs.slaveOk()之後才能被允許查看數據
- 刪除複製集
rs.remove('127.0.0.1:27019')
刪除節點後,如果想再添加,必須重新配置纔可以。
1 var rsconf = {
2 _id:'rs',
3 members:[
4 {_id:0,host:'127.0.0.1:27017'},
5 {_id:1,host:'127.0.0.1:27018'},
6 {_id:2,host:'127.0.0.1:27019'}
7 ]
8 }
9 再輸入:rs.reconfig(rsconf)
再輸入rs.status(),可以看到數據集現在又是三個了。