MongoDB 常用语句

MongoDB 常用语句

转载:https://cnodejs.org/topic/559cf0db3d79442724b9f064

下载安装
注意:需要手动创建存放数据的目录,且目录要在磁盘根目录下创建;如,D:\data\db

基础知识
非关系型数据库 关系型数据库
集合 表
文档 行

启动数据库
第一次 mongod --dbpath ../data/db
之后 mongod

开启客户端(默认连接 test 数据库)
mongo

一、显示
显示帮助:help
显示所有数据库:show dbs;
显示当前连接的数据库:db;
显示当前数据库所有集合:show collections;
显示数据库支持的方法:db.help();
显示集合支持的方法:db.test.help();

二、数据库
切换数据库:use test
创建数据库:
删除数据库:db.dropDatabase();

三、集合
创建集合:db.createCollection('users');
删除集合:db.users.drop();
修改集合:


四、文档
4.1 增(insert save)
// 直接新增
db.users.insert({'name': 'zhuzongzhi', 'age': 25});
// 不提供_id,直接新增
db.users.save({'name': 'zzz', age: 18});
// 提供_id,更新已存在文档
db.users.save({'_id': _id, 'name': 'zzz', age: 18});

4.2 删(remove)
remove 操作只删除文档,不删除索引;
db.users.remove({}); // 删除所有文档
db.users.remove({'_id': _id});
db.users.remove({'_id': _id}, true); // 第二个参数:删除一条指定文档

4.3 改(update updateMany)
4.3.1 全局更新
db.users.update({'name': 'zhuzongzhi'}, {'name': 'wangwu', age: 30, sex: 'male'});
4.3.2 局部更新
4.3.2.1 原子操作符
字段:$inc $set $unset
db.users.update({'name': 'zhuzongzhi'}, {$inc: {'age': 5}}); // +5 岁
db.users.update({'name': 'zhuzongzhi'}, {$set: {'age': 40}}); // 修改为40岁
// 修改为40岁,第三个参数:不存在,就新增一条
db.users.update({'name': 'zhuzongzhi'}, {$set: {'age': 40}}, true);
// 修改为40岁,第四个参数:批量修改
db.users.update({'name': 'zhuzongzhi'}, {$set: {'age': 40}}, true, true);
// 取消age键
db.users.update({'name': 'zhuzongzhi'}, {$unset: {'age': 40}});

数组:$push $addToSet $each $pop $pull
// array[] 若不存在,会自动创建
db.users.update({'name': 'zhuzongzhi'}, {$push: {'array': object}});
// 若字符串已存在,则不添加
db.users.update({'name': 'zhuzongzhi'}, {$addToSet: {'array': 'qaz'}});
// 和$puah 配合使用,循环遍历插入多个值
db.users.update({'name': 'zhuzongzhi'}, {$push: {'array': {$each: [1,2,3,4,5]}}});
// 从数组尾部删除一个元素 index=1 数组最后一个 index=-1 数组第一个
db.users.update({'name': 'zhuzongzhi'}, {$pop: {'array': index}});
// 指定删除某个元素 value=1:删除数组中元素值为1的元素
db.users.update({'name': 'zhuzongzhi'}, {$pull: {'array': value});


4.4 查(find findOne)
4.4.1 无条件查询:db.users.find({});
4.4.2 有条件查询:db.users.find({_id: ObjectId('123456789')});
等价 select * from tablename where id = '123456789';

4.4.2.1 原子操作符
条件操作符: $gt:大于 $gte:大于等于 $lt:小于 $lte:小于等于 $ne 不等于
db.users.find({age: {$gt: 20}}) <=> select * from users where age >= 20
db.users.find(age: {$gte: 20, $lte: 30}); <=> select * from users where age >= 20 and age <= 30
db.users.find({age: {$ne: 25}});

逻辑操作符:$and $or
db.users.find({
$and: [
{'name': 'zhuzongzhi'},
{age: {$lte: 30}}
]
});
等价于
select * from users where name = 'zhuzongzhi' and age <= 30;

db.users.find({
$or: [
{'name': 'zhuozngzhi'},
{'name': 'wangwu'}
]
});
等价于
select * from users where name = 'zhuozngzhi' or 'name' = 'wangwu';

包含:$in $nin
db.users.find({_id: {$in: ['123', '456']}});
等价于
select * from users where id in ('123', '456');

db.users.find({_id: {$nin: ['123', '456']}});
等价于
select * from users where id not in ('123', '456');

其他:$regex $where 正则表达式
db.users.find({'name': {$regex: 'zhu'}}); // 模糊查询
db.users.find({'name': /^k/}); // 正则
db.users.find({$where: function () { // js 函数
// 逻辑
return this.name == 'zhuzongzhi';
}});

计数器:
db.users.count(); // 无条件
db.users.count({'age': {$gte: 20}}); // 有条件

去重(唯一值):
db.users.distinct('name'); // 返回数组

五、聚合工具(group分组 和 aggregate 聚合)
各有优缺点,详情参考:https://www.cnblogs.com/zhouxuchen/p/5136446.html
5.1 group 特点:灵活
数据:
{ "_id" : ObjectId("55910457607379845607d9e2"), "name" : "kiinlam", "age" : 29 }
{ "_id" : ObjectId("55910468607379845607d9e3"), "name" : "shadow", "age" : 26 }
{ "_id" : ObjectId("55910992607379845607d9e5"), "name" : "foo", "age" : 29 }
{ "_id" : ObjectId("55911fca607379845607d9e6"), "name" : "dd", "age" : 22 }
{ "_id" : ObjectId("55911fd3607379845607d9e7"), "name" : "mm", "age" : 22 }
{ "_id" : ObjectId("55911fdf607379845607d9e8"), "name" : "gg", "age" : 22 }
{ "_id" : ObjectId("55911feb607379845607d9e9"), "name" : "jj", "age" : 22 }
{ "_id" : ObjectId("55920545ff40738c1fd0a839"), "name" : "zz", "age" : 1 }

db.users.group({
'key': {'age': true}, // 按年龄分组
'initial': {'user': []}, // 初始化
'$reduce': function (cur, prev) { // 简化
prev.user.push(cur.name);
},
'condition': {'age': {$lte: 22}}, // 过滤
'finalize': function (out) { // 最后调用函数
out.count = out.user.length;
}
});

结果:
[
{
"age" : 29,
"user" : [
"kiinlam",
"foo"
]
},
{
"age" : 26,
"user" : [
"shadow"
]
},
{
"age" : 22,
"user" : [
"dd",
"mm",
"gg",
"jj"
]
},
{
"age" : 1,
"user" : [
"zz"
]
}
]

5.2 aggregate 特点:效率高
$match $unwind $group $sort $project $skip $limit
db.users.aggregate([
{$match: {'age': {$lte: 22}}}, // 匹配
{$unwind: '$material'}, // 打散对象数组
{$group: {'_id': {'materialName': 'material.name'}, times: {$sum: 1}, totalNum: {$sum: '$material.num'}}, // 分组
{$sort: {'_id': 1}}, // 排序
// 修改文档结构
{$project: {'_id': 0, 'materialName': '$_id.materialName', count: 1, totalNum: 1}},
{$skip: 10}, // 跳过10条文档
{$limit: 20} // 限制返回文档数
]);

六、mapReduce(分组聚合的另外一种方式)
优点:
适用于大型复杂的数据聚合查询;
Map 函数和 Reduce 函数都是js实现,十分灵活强大;
db.users.mapReduce(
function () {emit(this.name, this.age);}, // map 函数,必须执行emit()函数,遍历文档按 this.name 分组,多个this.age 合成一个数组,作为reduce的两个参数(key, valus);
function (key, vlaus) {
return Array.sum(values);
}, // reduce 函数
{
query: {state: 'active'}, // 过滤,在 map 函数执行之前过滤;
out: 'totals' // 统计结果存放集合。若不定义,默认临时集合,客户端断开连接自动删除;
// sort 排序 limit 限制
}
);

例子:orders
{cust_id: 'A123', amount: 500, status: 'A'},
{cust_id: 'A456', amount: 250, status: 'A'},
{cust_id: 'A456', amount: 250, status: 'A'},

{cust_id: 'A123', amount: 500, status: 'B'}

db.orders.mapreduce(
function () {emit(this.cust._id, this.amount);},
function (key, values) {
return Array.sum(values);
},
{
query: {status: 'A'},
out: 'results'
}
);

查询 result 集合结果: db.result.find() // 注意:这个不是 mapreduce 函数执行的结果
{
_id: 'A123',
value: 500
},
{
_id: 'A456',
value: 750
}


七、游标
7.1 sort skip limit
db.users.find({'name': 'zhuzongzhi'}).sort('createTime': 1).skip(skipNum).limit(limitNum);
7.2 forEach遍历 next遍历
let rslist = db.users.find();
reslist.forEach(function (item) {
// 逻辑
});
或者
while(1) {
if (rslist.hasNext()) {
rslist.next();
} else {
break;
}
}

八、索引ensureIndex
8.0 什么是索引?
索引是一种特殊的数据结构,索引是对数据表中的一列或多列进行排序的结构;
优点:极大的提过查询效率;
缺点:索引占据内存(RAM),会产生额外的开销;能不用则不用;

8.1 创建索引
唯一索引(单个字段):db.users.ensureIndex({'name': 1}, {'unique': true}); // 1代表升序,-1代表降序
组合索引/多字段索引(关系型数据库:复合索引):db.users.ensureIndex({'name': 1, 'age'; -1});
8.2 查看索引
db.users.getIndexes(); // db.users.indexes.find();
8.3 删除索引
删除所有:db.users.dropIndexes();
删除指定:db.users.dropIndex('name');

8.4 按索引查询(直接查询)
db.users.find('name': 'zhuzongzhi');
db.users.find('name': 'zhuzongzhi').hint('name': 1, 'age': -1);

8.5 对索引进行解释分析
db.users.find({'name': 'zhuzongzhi'}).explain();
详情:https://blog.csdn.net/linfenliang/article/details/54946411

九、分片技术
将数据库集合(表)拆分后,均摊到几个分片数据库实例上;

十、性能分析函数explain
对执行函数进行解释分析,参考8.5;

十一、备份与恢复
备份
mongodump -h <hostname><:port> -d dbname -o D:\mongodb\backup
-h mongoDB 所在服务器地址
-d 数据库名称/数据库实例
-o 备份数据存放位置
恢复
mongorestore -h <hostname><:port> -d dbname --drop D:\mongodb\backup
-d 若使用,可修改数据库名称
--drop 恢复前删除当前数据,慎用!

十二、监控

其他、
主从数据库
副本集replSet:没有特定的主数据库,任何一个节点都可做主节点;一个数据库宕机,其他数据库顶上;




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值