使用MongoDB存储数据

在 Ubuntu14.04 上安装

Install MongoDB Community Edition

官方文档

1. Import the public key used by the package management system.

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6

2. Create a list file for MongoDB.

echo "deb [ arch=amd64 ] http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list

3. Reload local package database.

sudo apt-get update

4. Install the MongoDB packages.

Install the latest stable version of MongoDB.

sudo apt-get install -y mongodb-org

使用

1. Start MongoDB.

sudo service mongod start

2. Verify that MongoDB has started successfully

Verify that the mongod process has started successfully by checking the contents of the log file at /var/log/mongodb/mongod.log for a line reading

[initandlisten] waiting for connections on port <port>

3. Stop MongoDB.

sudo service mongod stop

4. Restart MongoDB.

sudo service mongod restart

关闭 mongodb 的守护进程

mongod --shutdown

卸载

Uninstall MongoDB Community Edition

1. Stop MongoDB.

sudo service mongod stop

2. Remove Packages.

sudo apt-get purge mongodb-org*

3. Remove Data Drections.

sudo rm -r /var/log/mongodb
sudo rm -r /var/lib/mongodb

在 windows 上安装

查看当前windows的版本

wmic os get caption

Caption
Microsoft Windows 10 专业版

wmic os get osarchitecture

OSArchitecture
64 位

下载 win-64 安装包

安装路径

C:\myprogram\MongoDB\3.6

自定义脚本

mongo.bat
d:
cd C:\myprogram\MongoDB\3.6\bin
mongod.exe --dbpath "G:\mongodata\db"
mongo-cli.bat
d:
cd C:\myprogram\MongoDB\3.6\bin
mongo.exe

MongoDB操作总结

1 创建数据库
use mydb//没有就创建

2 显示数据库
show dbs

3 显示数据库的状态
db.stats()

4 检查当前所用的数据库
db

5 删除数据库(先用然后删除)
use mydb
db.dropDatabase()

6 在数据库中创建集合(mycol为集合名称)
    a.  db.createCollection('mycol')    //创建默认集合
    db.mycol.insert({id:1,name:'张三',age:20})
    db.mycol.find({})
    db.mycol.insert({_id:'aa',name:'李四',age:20})
    b.  db.createCollection("mycol",{capped:true,autoIndexID:true,size:6142800,max:10000}) //创建指定参数集合
    指定参数:
    capped true 启用封顶集合,固定大小的集合,会自动覆盖最早的条目,如果true,也需要指定尺寸参数
    size number 指定最大字节封顶集合,如果封顶为true,需要指定这个字段
    max number  指定封顶集合最大数量,最高多少条记录
    autoIndexID true 则_id字段自动创建索引,默认false,慎用false,因为会导致同步数据时负载很高,建议true

7 直接插入数据创建集合
db.teacher.insert({'draven':'node'})
//自动创建名为teacher的数据集,里面有一条键值对

8 显示集合
show collections

9 删除集合
db.mycol.drop()

10 删除集合数据
db.mycol.remove({})

11 显示表格记录
db.mycol.find({})

数据类型和嵌套关联

//多条插入
db.mycol.insert([{},{},{}])

//覆盖保存,没有则插入,有则覆盖
db.user.save({})

//插入时间
db.test.insert({time:new Date()})
给mongodb插入日期的数据时发现,日期时间相差8小时,原来存储在mongodb中的时间UTC+0:00,而中国的时区是+8.00

取出时正确
db.test.find()[0].time.getHours()

//保证正确的插入方式
new Date(2017,7,28,21,45,30) //2017-7-28 21:45:30

用自定义函数:
function getFormateDate(time){
    year = time.getFullYear();
    mon = time.getMonth()+1;
    date = time.getDate();
    hour = time.getHours();
    min = time.getMinutes();
    sec = time.getSeconds();
    newtime = year+'-'+mon+'-'+date+' '+hour+':'+min+':'+sec;
    return newtime;
}

getFormateDate(new Date())
getFormateDate(db.user.find()[4].creattime)

修改数据
db.user.update({email:'aa'},{$set:{pwd:'bb'}}) //只能改第一条
db.user.update({email:'aa'},{$set:{pwd:'bb'}},{multi:true}) //允许多条
$unset  删除字段
db.user.update({email:'aa'},{$unset:{pwd:'bb'}}) //删除pwd:'bb'字段
$inc    在原先基础上加一个数
db.user.update({email:'aa'},{$inc:{money:15}},{multi:true}) //email为aa的,每人加15块钱
$push
{$push:{field:value}}
把value追加到field里面去。field一定是数组类型才行,如果field不存在,会新增一个数组类型加进去
$pushAll
{$pushAll:{field:value_array}}
同$push,只是一次可以追加多个值到一个数组字段内
$addToSet
{$addToSet:{field:value}}
增加一个值到数组内,而且只有当这个值不在数组内才增加

删除记录(remove)
db.user.remove({email:'aa'})
db.user.remove({email:'aa'},1)  //只删除一条
db.user.remove({})  //全部清空

update操作符删除
$pop
删除数组内的一个值
删除最后一个值 {$pop:{field:1}}
删除第一个值  {$pop:{field:-1}}

$pull
{$pull:{field:value}}
从数组field内删除一个等于value的值

$pullAll
{$pullAll:{field:value_array}}
同$pull,可以一次删除数组内多个值
db.test.update({_id:5},{$pullAll:{test1:['ccc','ffff']}})

$ 操作符
代表安条件找出的数组里面某项它自己
需要注意的是,如果后面不跟{multi:true},$只会应用找到的第一条数据项,后面的就不管了

查询数据
db.user.find()
db.user.find().pretty() //格式化,输出格式比较公正好看一点
db.user.findOne() //只查询碰到的第一条
db.user.find()[0] //只查询碰到的第一条,更灵活点,可以查第几条

db.mycol.count()    //查看有几条记录
db.mycol.count({age:20})    //age为20的有几条数据
db.mycol.find({},{name:1,age:1})    //1为显示,0为不显示,查询mycol所有记录,只显示name和age字段,但是此时_id是显示的
db.mycol.find({},{name:1,age:1,_id:0})    //只显示name和age,_id是不显示的

db.mycol.find({'likes':{$lt:50}}).pretty()  //查出likes小于50的
<   $lt     小于
<=  $lte    小于等于
>   $gt     大于
>=  $gte    大于等于
!=  $ne     不等于
db.user.find({money:{$lt:80,$gt:20}})   //money大于20小于80

多条件查询and
db.user.find({key1:value1,key2:value2}).pretty()    //如果两个key一样,后面的会覆盖前面的
多条件查询or
db.mycol.find({$or:[{key1:value1},{key2:value2}]}).pretty()
多条件查询and和or一起用
db.mycol.find({'likes':{$gt:10},{$or:[key1:value1,key2:value2]}})

db.user.find({pwd:/li/}).pretty()   //查询出pwd里面包含li的所有记录,大小写敏感
db.user.find({pwd:/li/i}).pretty()   //查询出pwd里面包含li的所有记录,忽略大小写,主要针对英文的
db.user.find({'by':{$regex:/or.*/i}})   //包含or的,忽略大小写
db.user.find({'by':/^tut/i})   //tut打头的,忽略大小写

分页(limit)
db.COLLECTION_NAME.find().limit(NUMBER)
db.mycol.find().limit(3)
db.mycol.find({},{'title':1,_id:0}).limit(1).skip(3)    //跳到第三条记录,向后显示1条
db.mycol.find({},{'title':1,_id:0}).skip(3)    //跳到第三条记录,向后显示所有记录

降序排序
db.mycol.find({},{title:1,_id:0}).sort({'title':-1})    //1用于升序排序,而-1用于降序

php查询方法
$paramArr = array(
    "nicheng"=>new MongoRegex("/.*".$_POST["nicheng"].".*/")
)


聚合查询
$match:匹配条件,可选,过滤条件
$limit:结果条数,可选
$group:聚合规则
$sort:对查询结果排序,-1表示降序

1 每个学生参考几门
db.course.aggregate([{$group:{_id:"$uid",科目数:{$sum:1}}},{$sort:{_id:-1}}])

2 每个学生的总成绩
db.course.aggregate([{$group:{_id:{uid:'$uid',姓名:'$name'},参考门数:{$sum:1},总成绩:{$sum:'$score'}}},{$sort:{_id:1}}])

3 平均成绩
db.course.aggregate([{$group:{_id:{uid:"$uid",姓名:"$name"},参考门数:{$sum:1},总分:{$sum:'$score'},平均分:{$avg:'$score'}}},{$score:{_id:1}}])
查询结果如下:
{"id":{uid:1,"姓名":"张三"},"参考门数":4,"总分":278,"平均分":69.5}
{"id":{uid:2,"姓名":"李四"},"参考门数":5,"总分":331,"平均分":66.2}
{"id":{uid:3,"姓名":"王五"},"参考门数":5,"总分":383,"平均分":76.6}

4 每个及格的学生的平均成绩
{$match:{score:{$gte:60,$lt:90}}}
先过滤再统计
db.course.aggregate([{$match:{score:{$gte:60,$lt:90}}},{$group:{_id:{uid:"$uid",姓名:"$name"},参考门数:{$sum:1},总分:{$sum:'$score'},平均分:{$avg:'$score'}}},{$score:{_id:1}}])

只显示两条
db.course.aggregate([{$match:{score:{$gte:60,$lt:90}}},{$group:{_id:{uid:"$uid",姓名:"$name"},参考门数:{$sum:1},总分:{$sum:'$score'},平均分:{$avg:'$score'}}},{$score:{_id:1}},{$limit:2}])
跳过一条向下显示两条
db.course.aggregate([{$match:{score:{$gte:60,$lt:90}}},{$group:{_id:{uid:"$uid",姓名:"$name"},参考门数:{$sum:1},总分:{$sum:'$score'},平均分:{$avg:'$score'}}},{$score:{_id:1}},{$skip:1},{$limit:2}])

参数:
$sum 总结从集合中的所有文件所定义的值.
$avg 从所有文档集合中所有给定值计算的平均.
$min 获取集合中的所有文件中的相应值最小.
$max 获取集合中的所有文件中的相应值的最大.
$push 值插入到一个数组生成文档中. db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])
$addToSet 值插入到一个数组中所得到的文档,但不会创建重复. db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])
$first 根据分组从源文档中获取的第一个文档。通常情况下,这才有意义,连同以前的一些应用 “$sort”-stage. db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])
$last 根据分组从源文档中获取最后的文档。通常,这才有意义,连同以前的一些应用 “$sort”-stage. db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])


创建索引
db.mycol.ensureIndex({"title":1})   //1是按升序排列
//mongodb会为我们去一个默认的名字,规则为keyname1_dir1_keyname2_dir2...keynameN_dirN

查看我们创建的索引
db.system.indexes.find()

删除索引
db.runCommand({"dropIndexes":"user","index":"IX_name"})

多字段索引
db.mycol.ensureIndex({"title":1,"description":1})

唯一索引
db.user.ensureIndex({"name":1},{unique:true})
db.user.ensureIndex({email:1},{unique:true,name:'email_uiq'})

联合唯一索引
db.user.ensureIndex({uid:1,cid:1},{unique:true,name:"uid_cid_unique"})


存储过程
保存为存储过程:    
db.system.js.save({_id:存储过程名称,value:存储过程体}) //添加一个新的存储过程或者更新一个已经存在的存储过程    

db.system.js.insert({_id:'add',value:function(a,b){
    return a+b*2;
}})

db.system.js.save({_id:'add',value:function(a,b){
    return a+b;
}})

查看存储过程
db.system.js.find()

db.eval("add(9,3)") //函数名,参数

WARNING:db.eval() is deprecated //这方法新版已经弃用了

删除存储过程
db.system.js.remove({_id:'add'})

//--------------------临时数据----------------------------
db.user.insert({name:'张三',birthday:new Date(1990,6,7)})
db.user.insert({name:'李四',birthday:new Date(1997,3,5)})
db.user.insert({name:'王五',birthday:new Date(1989,4,20)})
db.user.insert({name:'周六',birthday:new Date(1992,5,9)})
db.user.insert({name:'蒋七',birthday:new Date(1994,8,7)})

db.user.find()

存储过程最高支持es5的写法

//加载文件
load('g:/data/storepro.js')
db.system.js.find()
db.user.find()
//调用
getUserRS = db.eval('getUserRS')
getUserRS(db.user.find())

备份和恢复

一 备份数据库
新建文件夹G:/mongodata/back
cd C:\myprogram\MongoDB\3.6\bin
mongodump -d mydb -o g:/mongodata/back

mongodump -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -o 文件要存的路径
如果没有用户,可以去掉-u和-p。
如果导出本机的数据库,可以去掉-h。
如果是默认端口,可以去掉--port。
如果想导出所有数据库,可以去掉-d。

导出所有数据库(以下的是linux的路径格式,windows环境类似)
命令:mongodump -h 127.0.0.1 -o /home/draven/mongodb/

导出指定数据库
mongodump -h 192.168.1.108 -d tank -o /home/draven/mongodb/

二 mongorestore还原数据库
1,常用命令格式
 mongorestore -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 --drop 文件存在路径 
 --drop的意思是,先删除所有的记录,然后恢复。
  mongorestore /home/draven/mongodb/  #这里的路径是所有库的备份

C:\myprogram\MongoDB\3.6\bin>mongorestore -d mydb1 --dir g:/data/back/mydb

2,恢复所有数据库到mongodb中
mongorestore /home/draven/mongodb/  #这里的路径是所有库的备份

3,还原指定的数据库
C:\myprogram\MongoDB\3.6\bin>mongorestore -d mydb1 --dir g:/data/back/mydb
mydb1是新的数据库名称,mydb是备份目录中的mydb的数据库的文件夹

??不明白的
mongorestore -d tank /home/draven/mongodb/tank/  #tank这个数据库的备份路径
mongorestore -d tank_new /home/draven/mongodb/tank/  #将tank还有tank_new数据库中

三 mongoexport导出表,或者表中部分字段
mongoexport -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -c 表名 -f 字段 -q 条件导出 --csv -o 文件名 

上面的参数好理解,重点说一下:
-f    导出指字段,以字号分割,-f name,email,age导出name,email,age这三个字段
-q    可以根据查询条件导出,-q '{ "uid" : "100" }' 导出uid为100的数据
--csv 表示导出的文件格式为csv的,这个比较有用,因为大部分的关系型数据库都是支持csv,在这里有共同点

导出整张表
mongoexport -d tank -c users -o /home/zhangy/mongodb/tank/users.dat

根据条件导出数据
mongoexport -d tank -c users -q '{uid:{$gt:1}}' -o tank/users.json

四 mongoimport导入表,或者表中部分字段

还原整表导出的非csv文件
mongoimport -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -c 表名 --upsert --drop 文件名  
重点说一下--upsert,其他参数上面的命令已有提到,--upsert 插入或者更新现有数据

还原部分字段的导出文件
mongoimport -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -c 表名 --upsertFields 字段 --drop 文件名  
--upsertFields根--upsert一样

还原导出的csv文件
mongoimport -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -c 表名 --type 类型 --headerline --upsert --drop 文件名  

还原导出的表数据
mongoimport -d tank -c users --upsert tank/users.dat

部分字段的表数据导入
mongoimport -d tank -c users  --upsertFields uid,name,sex  tank/users.dat 

还原csv文件
mongoimport -d tank -c users --type csv --headerline --file tank/users.csv


应用
Express中操作mongodb
1.npm install mongodb --save-dev
2.打开dos窗口:启动mongodb      
C:\myprogram\MongoDB\3.6\bin>mongod.exe --dbpath "G:\mongodata\db"
mongoose连接mongodb
Mongoose库简而言之就是在node环境中操作MongoDB数据库的一种便捷的封装,一种对象模型工具,增加里一些api,类似ORM
1.安装      
npm install mongoose --save-dev      
2.mongoose.js
sails中操作mongodb
1.创建项目:  
G:\www\nodejs\sails>sails new blog  
G:\www\nodejs\sails\blog>npm install sails-mongo --save-dev
2.config/connections.js中
someMongodbServer: {
    adapter: 'sails-mongo',
        host: 'localhost',
            port: 27017,
                // user: 'username',  
                // password: 'password',  
                database: 'segment'
},  
  
3.config/models.js中
connection: 'someMongodbServer',
    migrate: 'safe'

4.models/User.js
module.exports = {
    tableName: 'user',
    adapter: 'sails-mongo',
    autoCreatedAt: false,
    autoUpdatedAt: false,
    attributes: {
        id: { columnName: '_id' }, email: {}, pwd: {}, nicheng: {}, updtime: {}, createtime: {},
    }
};

5.api/controllers/UserController.js
User = require('../models/User');
function formatDate(date) {
    return date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
}
module.exports = {
    /**  
     * `UsersController.zhuce()`  
     */
    zhuce: function (req, res) {
        var user = { id: 2, email: 'cc', pwd: 'cc', nicheng: '王五' };
        user.createtime = formatDate(new Date());
        User.create(user).exec(function (err, created) {
            if (err) {
                var errStr = err.message;
                res.send(errStr);
                return;
            }
            res.send("注册成功");
        })
    },
    login: function (req, res) {
        /*  
        User.find({email:'aa',pwd:'aa'},function(err,rs){  
            console.log(rs);  
            res.send('查到:'+rs);  
        });  
        */
        User.findOne({ email: 'aa', pwd: 'aa' }, function (err, rs) {
            console.log(rs);
            res.send('查到:' + rs);
        });
    }
};

6.启动Mongodb服务  
C:\myprogram\MongoDB\3.6\bin> mongod.exe --dbpath "G:\mongodata\db"
  
7.启动Mongodb管理器  
C:\myprogram\MongoDB\3.6\bin> mongo.exe

8.启动sails: sails lift  
  
9.访问: http://localhost:1337/user/zhuce
nodejs调用mongodb存储过程

Node/Express/Mongoose 中的使用

已上传至我的 Github 主页: 参考源码


想要查看更多文章,敬请关注 dravenxiaokai 的简书

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容

  • 以 MongoDB Community Edition on Ubuntu 为例,参考MongoDB官网 安装mo...
    HiFi不二阅读 3,757评论 0 3
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,647评论 18 139
  • 毕业设计采用 Python 写电影个性化推荐,于是切换到Linux,安装了Ubuntu 16.04。 数据储存选用...
    Leoshi阅读 713评论 0 1
  • 一定要选择自己爱的 一定要爱自己选择的 纷乱浮华的尘世 唯能予你情比金坚 _______清净独觉
    清净独觉阅读 288评论 0 24
  • 我只是不想再站在你身后 等待你转身了 谢谢你啊
    精分的一只小猴子阅读 327评论 0 0