MongoDB 入门使用
说明
MongoDB 是一个基于分布式文件存储的数据库,目的是为 WEB 应用提供可扩展的高性能的数据存储解决方案,它支持的数据结构非常松散,是类似 json 的 bson 格式,因此可以存储比较复杂的数据类型。
1. 安装
查看官网
2. 测试安装成功
# 新建项目
mkdir mongo-demo
cd mongo-demo
# 创建数据文件夹
mkdir data
mkdir data/db
# 启动服务
mongod --dbpath ./data/db
# 重新打开一个终端,链接这个服务
mongo # 输入后进入命令行环境
# 查看存在数据库命令
show dbs
# 查看数据库版本
db.version()
# 能够正常显示以上命令证明安装成功
3. MongoDB 基本 shell 命令
show dbs
显示已有数据库use admin
进入数据库 admin 是默认数据库show collections
显示当前数据库中的集合(关系型数据库中叫表)db
显示当前位置use user
user 数据库不存在,则会创建 user 数据库,这个时候show dbs
不会显示新创建的数据库,因为这个数据库是空的db.user.insert({"name": "test name"})
db.[集合].insert()
用来在当前数据库中创建集合,然后插入数据,如果集合存在,则直接向其中加入数据db.user.find()
查询 user 集合的所有数据db.user.findOne()
查询第一个文件数据db.user.update({"name":"test name"}, {"name": "changed name"})
update({查询}, {修改})
修改某一条数据db.user.remove({"age": "xxx"})
删除某个文件数据db.user.drop()
删除当前集合db.dropDatabase()
删除当前数据库
4. 在 JavaScript 中调用 MongoDB
// 创建 run.js 文件
var userName = 'mjz';
var timeStamp = Date.parse(new Date());
var insertData = {
loginUser: userName,
loginTime: timeStamp
};
var db = connect('log'); // 链接数据库
db.login.insert(insertData); // 创建 login 集合插入数据
print('[demo] log print success');
# 命令行执行
mongo run.js
5. MongoDB 批量插入数据
// 更改 run.js 文件
var userName = 'mjz';
var timeStamp = Date.parse(new Date());
var loginData = {
loginUser: userName,
loginTime: timeStamp
};
var insertData = [loginData];
for (let i = 0; i < 1000; i++) {
insertData.push({count: i});
}
var db = connect('log'); // 链接数据库
db.login.insert(insertData); // insert() 中可以传入数组用于批量插入数据
print('[demo] log print success');
6. 数据修改
使用
db.login.update({"loginUser": "mjz"}, {"loginUser": "new user"})
发现除了loginUser 被修改了,其他的同一行数据也不见了, update() 是将这一行数据整体 替换掉了如果想要只做局部修改可以使用 update 修改器 $set
# 1. $set 用来更改键值对的值,如果键不存在则重新创建一个键值对,用来查询的键值对不会被替换
db.login.update({"loginUser" : "mjz"}, {"$set": {"loginUser": "test name3"}}) #loginUser 值变为 test name3
db.login.update({"loginUser" : "mjz"}, {"$set": {"user": "test name3"}}) # 如果通过 loginUser 索引到的行不存在 user 键则会重新创建一个 user 键值对,loginUser 作为索引不会被替换掉
# 2. $set 可以通过 key.subKey 的方式更改嵌套的内容
db.login.update({"name" : "test name3"}, {"$set": {"loginUser.name": "set name2"}})
# 3. $unset 删除键值对
db.login.update({"name" : "test name3"}, {"$unset": {"loginUser": ""}})
# 4. $inc 用于数字计算
db.login.update({"user" : "test name3"}, {"$inc": {"age": +10}}) # age 原有基础上 + 10
# 5. multi 选项会多选全部符合查询条件的行进行修改
db.login.update({}, {"$set": {"some": "test"}}, {"multi": true})
# 6. upsert 选项表示,没有查询条件的行就以查询条件为基础新增 一行
db.login.update({"name": "xiaobai"}, {"$set": {"some": "test"}}, {"upsert": true})
# 7. $push 追加数组中的值
db.login.update({"loginUser" : "mjz"}, {"$push": {interest: "xxx"}}) # 通过索引找到对应的行,向其中 interest键的数组中加入 “xxx”
# 8. $ne 查找值是否存在,不存在则执行操作
db.login.update({"interest": {"$ne": "xxx"}}, {"$push": {interest: "yyy"}}, {multi:true}) # 查找所有行,如果 interest 数组中没有 “xxx” 就添加 “yyy”
# 9. $addToSet 加入到集合中,存在则不加,不存在则加入
db.login.update({count: 5}, {"$addToSet": {interest: "xxx"}}) # 查询 count 为 5 的项,数组 interest 是都存在 “xxx” 不存在则添加
# 10. $each 批量加入集合
db.login.update({count: 2}, {"$addToSet": {interest: {"$each": ["a", "b", "c"]}}}) # ["a", "b", "c"] 都被加入到了 interest 中
# 11. $pop 删除数组值
db.login.update({count: 2}, {"$pop": {interest: 1}}) # 值为 1 表示末端删除 -1 表示开端删除
# 12. 修改数组某一项的值
db.login.update({count: 2}, {"$set": {"interest.1": "xyxy"}}) # 将interest 数组下标为 1 的项修改为 ”xyxy“
7. find 查询
find 查询的语法
db.collection.find(query, fields).limit().skip().sort()
- query {} 查询参数
- fields {} 定制显示内容样式
- limit (num) 返回查询结果的数量
- skip (num) 跳过多少项显示,配合 limit 实现分页
- sort (1|-1) 排序
# 0. 完整实用
db.login.find({count: {$gt: 5}}, {"_id": 0}).limit(8).skip(16).sort({count: 1})
# 1. $gt、$lt 大于、小于 查询条件
db.login.find({count: {$gt: 10, $lte: 20}}) # 返回 count 10-20 的数据
# 2. $in 查询指定值
db.login.find({count: {$in: [5, 8, 10]}}) # 返回 count 值为 5, 8, 10 的项
# 3. $or 多个查询条件满足一个即可
db.login.find({$or: [{count: 2}, {interest: ["xxx"]}]}) # 查询 count = 2 或者 interest = ["xxx"] 的项
# 4. $and 要满足多个查询条件
db.login.find({$and: [{count: 20}, {"interest" : [ "yyy" ]}]}) # 两个条件都满足才能查询到
# 5. $not 排除条件
db.login.find({count: {$not: {$lt: 20}}})
# 6. 数组查询包含某一项
db.login.find({"interest" : "xxx"}, {"_id": 0}) # 返回 interest 数组中含有 "xxx" 项的数据
db.login.find({"interest" : ["xxx"]}, {"_id": 0}) # 返回 interest 数组值为 ["xxx"] 的项
# 7. $all 他同时含有多个值的数组查询
db.login.find({"interest" : {$all: ["xxx", "yyy"]}}, {"_id": 0}) # 返回数组值同时含有 "xxx", "yyy"
# 8. 数组的 $in 查询,查询满足其中一个值的项
db.login.find({"interest" : {$in: ["xxx", "yyy"]}}, {"_id": 0}) # 返回安祖其中一个值的项
# 9. $size 返回数组长度为指定数量的项
db.login.find({"interest" : {$size: 2}}, {"_id": 0}) # 返回数组长度为 2 的项
// js 文件中使用 find
var db = connect('log');
var results = db.login.find();
var num = 0;
results.forEach(function (result) {
print(num++);
printjson(result);
})
MongoDB 索引
极大的降低了查询时间
// 当前测试使用 find() 查询100000条数据耗时 57 ms 左右
db.randomInfo.find({"username" : "qng"});
1. db.collection.ensureIndex(search)
建立索引
2. db.collection.getIndexes()
获取索引
// 建立对 username 的索引
var db = connect('company'); // 链接数据库
db.randomInfo.ensureIndex({username: 1}); // 建立索引
var rs = db.randomInfo.getIndexes(); // 打印当前索引
printjson(rs);
// 再次执行查询操作 耗时 5 ms 左右
db.randomInfo.find({"username" : "qng"});
3. db.collection.dropIndex(name)
删除索引 name 是 getIndexes() 打印出每一个索引的 name 值
var db = connect('company');
function getRandomId(rs) {
const temp = Math.floor(Math.random() * rs.length);
return temp === 0 ? getRandomId(rs) : temp;
}
var rs = db.randomInfo.getIndexes();
printjson(rs);
var randomId = getRandomId(rs);
var deleteId = rs.filter((item, i) => randomId !== 0 && i === randomId)[0].name;
printjson('delete ' + deleteId);
db.randomInfo.dropIndex(deleteId);
var nextRs = db.randomInfo.getIndexes();
printjson(nextRs);
4. 全文索引
建立索引
var db = connect('company');
// 建立全文查找索引
var rs = db.randomInfo.ensureIndex({username: 'text'}); // username 就是要全文索引的属性
printjson(rs);
执行索引
var results = db.randomInfo.find({$text : {$search: "ut"}}); // ut 就是要全文查找的内容,可以设置多个”“内用空格隔开
MongoDB 的用户管理
1. 建立管理员
> mongod --dbpath ./data/db # 启动
> use admin # 另起一个终端进入 admin
> db.createUser({user: 'root', pwd: '000000', roles: ['userAdminAnyDatabase','dbAdminAnyDatabase']}) # 创建管理员 roles 是权限
> show collections # 可以看到多了一个 system.users 的集合
> db.system.users.find() # 查看用户
2. 管理员登录
# 重新启动数据库,加上 --auth 参数 表示加入数据库验证
> mongod --dbpath ./data/db --auth # 验证启动
> use admin # 另起终端进入 admin
> show collections # 测试,发现会弹出未授权警告 not authorized on admin to execute command
> db.auth('root', '000000') # 授权登录
3. 超级管理员
有全部的权限,可以管理用户、查看数据库、增删改查
db.createUser({user: 'NO1', pwd: '000000', roles: ['root']}) # 超级管理员 root 权限