mongodb游标与导入导出命令

一、游标

在mongodb中,底层使用js引擎进行各种操作,所以我们在命令行窗口,可直接执行js代码。

#使用for循环,插入1000条数据。
> for (var i=0;i<1000;i++){ db.test.insertOne({_id:i,name:"erha"+i})}
{ "acknowledged" : true, "insertedId" : 999 }
> db.test.find()
#查询结果如下
{ "_id" : 0, "name" : "erha0" }
{ "_id" : 1, "name" : "erha1" }
{ "_id" : 2, "name" : "erha2" }
{ "_id" : 3, "name" : "erha3" }
{ "_id" : 4, "name" : "erha4" }
{ "_id" : 5, "name" : "erha5" }
{ "_id" : 6, "name" : "erha6" }
{ "_id" : 7, "name" : "erha7" }
{ "_id" : 8, "name" : "erha8" }
{ "_id" : 9, "name" : "erha9" }

我们使用find()方法查询时,他会将所有的数据都查询出来给我们,但是当数据量特别大的时候,这种操作并不是很好。我们希望就像python中生成器那样,我们需要数据,调用某些方法,就给我们返回数据。其实在MongoDB中也有类似生成器对象的东西,在mongo中叫做游标。

1.1、游标操作

我们将查询的结果,赋值给一个变量,则该变量就是一个游标。

> var con= db.test.find()
> con.next()  #取出该游标下一个元素。
{ "_id" : 0, "name" : "erha0" }
> con.hasNext() #判断该游标是否有下一个元素。
true
#还可以进行循环打印
> while(mycusor.hasNext()){
... printjson(mycusor.next())
... }
{ "_id" : 0, "name" : "erha0" } 
{ "_id" : 1, "name" : "erha1" }
{ "_id" : 2, "name" : "erha2" }
{ "_id" : 3, "name" : "erha3" }
{ "_id" : 4, "name" : "erha4" }
{ "_id" : 5, "name" : "erha5" }
{ "_id" : 6, "name" : "erha6" }
{ "_id" : 7, "name" : "erha7" }
{ "_id" : 8, "name" : "erha8" }
{ "_id" : 9, "name" : "erha9" }

#可将所有元素取出到一个数组内
> var mycusor = db.test.find().limit(2)
> mycusor.toArray()
[
        {
                "_id" : 0,
                "name" : "erha0"
        },
        {
                "_id" : 1,
                "name" : "erha1"
        }
]
1.2、forEach(回调函数)
> var mycusor = db.test.find().limit(10)
> var get_name=function(obj){  #定义一个函数,打印每个元素的name属性。
... print(obj.name)}
> mycusor.forEach(get_name)
erha0
erha1
erha2
erha3
erha4
erha5
erha6
erha7
erha8
erha9
1.3、游标在分页中的使用
#每页5个。
> var mycusor = db.test.find().skip(0).limit(5)
> var mycusor = db.test.find().skip(5).limit(5)

#总结如下
m:页码
n:每页元素
> var mycusor = db.test.find().skip((m-1)*n).limit(n)
> mycusor.toArray()

二、索引

  • 索引提高查询速度,降低写入速度,一般在常用的查询字段建立索引。
  • 在mongodb中,索引可以按字段升序/降序来创建,便于排序。
  • 默认是用btree来组织索引文件,2.4版本以后,也允许建立hash索引。
2.1、常用命令
(1)查看当前索引状态:db.collection.getIndexes()
> db.test.getIndexes()
[
        {
                "v" : 2,  #版本
                "key" : {
                        "_id" : 1   #排序方式
                },
                "name" : "_id_",    #索引名
                "ns" : "test.test"   #数据库.表
        }
]

(2)创建普通单列索引:db.collection.ensureIndex({field:1/-1})//1为正序,-1为逆序
> db.test.ensureIndex({name:-1})
> db.test.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "test.test"
        },
        {
                "v" : 2,
                "key" : {
                        "name" : -1
                },
                "name" : "name_-1",
                "ns" : "test.test"
        }
]

(3)删除单个索引:db.collection.dropIndex({field:1/-1})
> db.test.dropIndex({name:-1}) #这里的-1,跟设置时的保持一致。
{ "nIndexesWas" : 2, "ok" : 1 }
> db.test.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "test.test"
        }
]
(4)删除所有索引:db.collection.dropIndexes() 
#	_id所在的列的索引不能删除。

(5)创建多列索引:db.collection.ensureIndex({field1:1/-1,field2:1/-1})
> db.test.ensureIndex({_id:1,name:1})
> db.test.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "test.test"
        },
        {
                "v" : 2,
                "key" : {
                        "_id" : 1,
                        "name" : 1
                },
                "name" : "_id_1_name_1",
                "ns" : "test.test"
        }
]

(6)创建多列索引:db.collection.dropIndex({field1:1/-1,field2:1/-1})
> db.test.dropIndex({"_id" : 1,"name" : 1})
> db.test.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "test.test"
        }
]

(7)创建hash索引
> db.test.ensureIndex({name:'hashed'})
> db.test.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "test.test"
        },
        {
                "v" : 2,
                "key" : {
                        "name" : "hashed"
                },
                "name" : "name_hashed",
                "ns" : "test.test"
        }
]

(8)为子文档创建索引
#插入数据
db.goods. insert({name: 'N0kia' , SPC:{weight: 120 , area: ' taiwan ' } } )
db.goods. insert({name: 'sanxing ' , SPC:{weight: 100 , area: 'hanguo'} } ) 

#查询产地为韩国的产品名
> db.goods.find({'SPC.area':'hanguo'},{name:1,_id:0})
{ "name" : "sanxing " }

#创建索引
> db.goods.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "test.goods"
        }
]
> db.goods.ensureIndex({'SPC.weight':1})
> db.goods.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "test.goods"
        },
        {
                "v" : 2,
                "key" : {
                        "SPC.weight" : 1
                },
                "name" : "SPC.weight_1",
                "ns" : "test.goods"
        }
]

(9)、唯一索引,设置了唯一索引的列,元素不能重复
> db.goods.ensureIndex({"SPC.weight":1},{unique:1})
#插入weight相同的数据
> db.goods. insert({name: 'N0kia' , SPC:{weight: 120 , area: ' taiwan ' } } )
WriteResult({
        "nInserted" : 0,
        "writeError" : {
                "code" : 11000,
                "errmsg" : "E11000 duplicate key error collection: test.goods index: SPC.weight_1 dup key: { SPC.weight: 120.0 }"
        }
})

三、mongodb数据库的导出与导入

3.1、通用选项
--host host   主机
--port port    端口
-u username 用户名
-p passwd   密码
3.2、导出
-d  库名
-c  表名
-f  field1,field2...列名
-q  查询条件
-o  导出的文件名。
--type csv  导出csv格式(便于和传统数据库交换数据),需要指定列名。
--skip 跳过多少个
--limit 指定导出多少个
-- sort: 导出时,可指定字段排序
示例1、导出json
mongoexport -d shop -c goods -o goods.json
示例2、导出指定字段为csv文件
mongoexport -d shop -c goods -f "goods_id","goods_name","shop_price" --type csv  -o goods.csv

示例3、导出指定数量,并且按照价格从高到低排序
mongoexport -d shop -c goods --limit 5 --sort {shop_price:-1} --f "goods_id","goods_name","shop_price" --type csv  -o goods.csv

3.3、导入
-d 待导入的数据库
-c 待导入的表(不存在会自己创建)
--file 备份文件路径
示例1、导入json
mongoimport -d douban -c top250 --file ./doubantop250.json
示例2、导入csv
mongoimport -d test -c shop --type csv -f "goods_id","goods_name","shop_price" ./goods.csv

> use test
> db.shop.find()
{ "_id" : ObjectId("5e844e4d05ffa52ba53b45b4"), "goods_id" : 3, "goods_name" : "诺基亚原装5800耳机", "shop_price" : 68 }
{ "_id" : ObjectId("5e844e4d05ffa52ba53b45b5"), "goods_id" : 5, "goods_name" : "索爱原装M2卡读卡器", "shop_price" : 20 }
...
3.4、导出为二进制
-d  库名
-c  表名

#默认导出到执行命令位置dump目录下
#导出的文件放在以database命名的目录下
#每个表导出2个文件,分别是bson结构的数据文件, json的索引信息
#如果不声明表名, 导出所有的表。
示例1、导出一个数据库下的所有表。
mongodump -d test
示例2、导出指定表
mongodump -d shop -c goods

3.5、导入二进制文件
mongorestore -d shop1 -c goods --dir ./dump/shop/goods.bson
> use shop1
switched to db shop1
> show tables
goods

四、mongo复制集,类似于 redis( 主从+哨兵),以下操作都在windows上。

4.1、目录准备
#创建数据库目录
C:\Users\28295\Desktop>md data1
C:\Users\28295\Desktop>md data2
C:\Users\28295\Desktop>md data3

#创建日志目录,及日志文件
C:\Users\28295\Desktop>md log1
C:\Users\28295\Desktop>md log2
C:\Users\28295\Desktop>md log3
C:\Users\28295\Desktop>echo >>log3\\log.log
C:\Users\28295\Desktop>echo >>log2\\log.log
C:\Users\28295\Desktop>echo >>log1\\log.log
4.2、启动服务
#关闭mongodb服务(没有配置服务自启,请忽略。),启动三个服务端。
PS C:\Users\28295\Desktop\spider> net stop MongoDB  #注意要用管理员权限打开命令窗口。
MongoDB 服务正在停止.
MongoDB 服务已成功停止。

#--replSet 代表复制集的名称,必须要一致。
mongod --dbpath ‪C:\Users\28295\Desktop\data1  --logpath ‪C:\Users\28295\Desktop\log1\log.log  --port 27017 --replSet db

mongod --dbpath ‪C:\Users\28295\Desktop\data2  --logpath ‪C:\Users\28295\Desktop\log2\log.log  --port 27018 --replSet db

mongod --dbpath ‪C:\Users\28295\Desktop\data3  --logpath ‪C:\Users\28295\Desktop\log3\log.log  --port 27019 --replSet db

4.3、用客户端连接其中一台服务器,进行配置。
var rsconf = {
	_id:'db',
	members:[
			{_id:0,host:'127.0.0.1:27017'},
			{_id:1,host:'127.0.0.1:27018'},
			{_id:2,host:'127.0.0.1:27019'}
			]
}
rs.initiate(rsconf) #初始化,主服务端随机分配。

初始化完成后,主服务端会变成如下样子(27018).

从服务端下(27017,127019)

主服务端插入数据后,从服务端必须输入rs.slaveOk()之后才能被允许查看数据,不然会报错。

db:PRIMARY> db.goods.insert({name:'erha',age:12})
WriteResult({ "nInserted" : 1 })

假如主服务器死亡(27018),则在剩下的mongodb服务器中选出一台作为主服务器。

rs.status() #该命令可以查看具体的复制集信息

有上图可知,在我强制关闭(27018)主服务器后,(27017)此时变为了主服务器。

posted @ 2020-04-02 00:17  叶落西南  阅读(382)  评论(0编辑  收藏  举报