在学习了一段时间的基于nodejs的全栈开发技术—mean框架后,对于mongo数据库也有了一定程度的认识。在接触mean之前,我使用过一段时间的sql server,对于我个人来讲至少在体验上没有mongo方便,当然这不应该是一个开发者的态度(为了追求方便)。
简介
MongoDB 是一个基于分布式文件存储的开源数据库。分布式数据库的特点在于,在高负载的情况下,添加更多的节点,可以保证服务器性能。MongoDB 将数据存储为一个文档(document),数据结构由键值对(key=>value)组成。MongoDB 文档类似于JSON对象。字段值可以包含其他文档,数组及文档数组。1
2
3
4
5
6
7
8
9
10
11
12{
name: 'john',
age: 21,
sex: 'male',
tel: '12345678',
hobby: ['basketball', 'soccerball', 'chess'],
score: {
chinese: 96,
math: 85,
physical: 92
}
}
Mongo支持丰富的查询表达式,查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。增删改查操作语法采用javascript,与JSON可谓是异曲同工,相比于sql语句,数据操作比较简单和容易。
安装配置
首先在MongoDB官网下载页下载对应版本,这里用3.2.0 Windows 64-bit 2008 R2+版来介绍。
- 安装完毕后将安装目录下的
bin目录加入系统Path环境变量中; - 指定数据库文件目录以及日志文件目录:
2.1. 这里我选定D:\Codes\MongoDB为数据库文件根目录;
2.2. 依次新建data/db目录和data/log/mongolog.log文件;
2.3. 新建mongodb.bat作为mongoDB的启动脚本,添加如下内容:1
mongod --dbpath "D:\Codes\MongoDB\data\db" --logpath "D:\Codes\MongoDB\data\log\mongodb.log"
- 双击该脚本启动mongoDB服务,以后每次都可以使用该脚本启动数据库;
- 另开一个命令提示符窗口,输入
mongo回车进入mongo命令行模式; - 为数据库建立超级用户,依次执行以下命令:
1
2use admin
db.createUser({user: 'sa', pwd: 'admin', roles: [{role: 'userAdminAnyDatabase', db: 'admin'}]}) - 将两个命令提示符窗口都关闭,编辑
mongoDB.bat,在末尾加上" -auth"参数以启用用户验证。
简单使用
首先运行之前创建的bat脚本启动mongoDB服务,在另一个cmd窗口通过mongo命令来执行简单的增删查改操作。这里不再新建另外的数据库,操作均在admin数据库中进行。首先使用sa账户登录admin数据库:1
mongo admin -usa -padmin
新建一个use文档集合(类似于SQL中表的概念):1
db.createCollection('user')
查看是否创建成功:1
show collections
插入数据
插入数据:1
2
3db.user.insert({name: 'James', age: 20, sex: 'male'})
db.user.insert({name: 'Mary', age: 18, sex: 'female'})
db.user.insert({name: 'Taylor', age: 26, sex: 'female'})
这时user集合中已经有了3条数据,分别记录着3人的姓名等信息,使用find函数查询数据:
查询数据
显示所有用户:1
db.user.find()
查询年龄在20-30之间的用户:1
db.user.find({age: {'$gte': 18, '$lte': 30}})
删除数据
将Mary从集合中删除:1
db.user.remove({name: 'Mary'})
修改数据
修改Taylor的年龄为32:1
db.user.update({name: 'Taylor'}, {$set: {age: 32}})
高级查询及数据操作
上述简单使用仅仅是针对一些单值,然而在实际开发中这些是远远不够的,实际的数据场景要复杂得多,为此MongoDB内置了一些操作运算符以满足各种需求。
操作运算符
- 条件比较:大于
$gt、大于等于$gte、小于$lt、小于等于$lte、不等于$ne、非$not。
关系判断:包含于$in、不包含于$nin、全部属于$all。 - 高级查找:取模
$mod、或$or、且$and、异或$nor、数量$size、字段存在$exists、字段类型$type、条件组合查询$elemMatch、自定义函数查询$where。 - 操作符:截取数组元素
$slice、增减数值型的值$inc、添加数组元素$push、无重复添加数组元素$addToSet、头或尾删除数组元素$pop、删除指定数组元素$pull、更新创建键值$set、删除键$unset。
返回数据处理
可以限制结果集返回部分字段,字段值等于1时表示需要返回,0时表示不需要返回:1
db.person.find({}, {status:1,age:1})
find返回json对象数据,可以采用以下方法遍历:1
2
3
4
5
6
7
8
9
10
11// next方式
var myCursor = db.inventory.find( { type: 'food' } );
var myDocument = myCursor.hasNext() ? myCursor.next() : null;
if (myDocument) {
var myItem = myDocument.item;
print(tojson(myItem));
}
// forEach循环遍历
var myCursor = db.inventory.find( { type: 'food' } );
myCursor.forEach(printjson);
嵌套查询
MongoDB还支持文档数组以及内嵌文档的数据结构。如果采用嵌套方式存储数据,使用update修改数据时应该留意。假设现有如下一条记录在数据库中:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21{
name:'李四',
sex:'男',
age:23,
score:[
{
semester:1,
chinese:95,
math:89,
english:83,
program:90
},
{
semester:2,
chinese:90,
math:96,
english:86,
program:90
}
]
}
那么修改李四第一学期的英语成绩并在控制台打印他的所有成绩,可以采用以下方法:1
2
3
4
5
6
7
8Model.update({name:'李四',"score.semester":1},{$set:{"score.$.english":92}},function(err,res){
if(!err) {
console.log("修改成功!");
Model.find({name:"李四"},function(err,res){
console.log(res);
});
}
});
更多详细资料请参看MongoDB官方文档。