一、前言
各位FEer,大家好。最近呢,公司项目没有之前那么紧了,我就在自己驱动学习下其他周边知识,因为想做一个全栈型的开发者,所以我就着手学习了Nodejs做后端接口和MongoDB做数据库存储这样一个架构。写了一个原生的移动App。今天我们来分享下MongoDB数据库的学习新得。
二、数据库初识
众所周知,数据库的存在对于技术开发者来说,就好比是仓库,用来存储信息的仓库。而一般数据库又分为关系型数据库和非关系型数据库。关系型数据库比较常见的是Mysql和Oracle,非关系数据库比较常见的是memcached(key-value),redis(key-value),和mongoDB(Document-oriented)等等很多NoSQL数据库。
三、MongoDB的特点
MongoDB是一个介于关系型数据库和非关系型数据库之间的产品,是非关系型数据库当中功能最丰富,最像关系数据库的。他支持的数据库结构非常松散,类似json的bjson格式,因此可以存储比较复杂的数据类型。Mongodb最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
特点
- 高性能
- 易部署
- 易使用
- 存储数据非常方便
主要功能特性
- 面向集合存储,易存储对象类型的数据
“面向集合”(Collenction-Orented)意思是数据库被分组存储在数据集中,被称为一个集合(Collenction)每个 集合在数据库中都有一个唯一的标识名,并且可以包含无限数目的文档,集合的概念类似关系型数据库(RDBMS)里的表(table)不同的是它不需要定义任何模式(schema) - 模式自由
模式自由(schema-free)意为着存储在mongodb数据库中的文件,我们不需要知道它的任何结构定义。 - 支持动态查询
- 支持完全索引,包含内部对象
- 支持查询
- 支持复制和故障恢复
- 使用高效的二进制数据存储,包括大型对象
- 自动处理碎片、以支持云计算层次的扩展性
学习细节
1、启动mongoDB数据库
xuhao@localhost private-code$ cd MongoDB-Project/
xuhao@localhost MongoDB-Project$ mongod
2、进入命令行操作
xuhao@localhost MongoDB-Project$ mongo
MongoDB shell version v4.0.13
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("ccf999e2-2300-4438-acef-4a8bb23862f5") }
MongoDB server version: 4.0.13
3、mongo命令行模式下,练习基本操作命令
> var a = 5
> print a
2019-12-09T22:24:39.248+0800 E QUERY [js] SyntaxError: missing ; before statement @(shell):1:6
> print(a)
5
> function sum(x,y){
... return x+y;
... }
> sum(5,6)
11
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
> use weichuang
switched to db weichuang
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
> db
weichuang
> show collections
> db.user.insert({"name":"xuhao"})
WriteResult({ "nInserted" : 1 })
> db.user.find()
{ "_id" : ObjectId("5dee5a2df4dd815948930114"), "name" : "xuhao" }
> db.user.insert({"name":"luolanyu"})
WriteResult({ "nInserted" : 1 })
> db.user.find()
{ "_id" : ObjectId("5dee5a2df4dd815948930114"), "name" : "xuhao" }
{ "_id" : ObjectId("5dee5a75f4dd815948930115"), "name" : "luolanyu" }
> db.user.findOne()
{ "_id" : ObjectId("5dee5a2df4dd815948930114"), "name" : "xuhao" }
> db.user.remove({"name":"xuhao"})
WriteResult({ "nRemoved" : 1 })
> db.user.find()
{ "_id" : ObjectId("5dee5a75f4dd815948930115"), "name" : "luolanyu" }
> db.user.drop()
true
> db.user.find()
> load('./1.js')
connecting to: mongodb://127.0.0.1:27017/weichuang
Implicit session: session { "id" : UUID("a2e0831a-e3ee-449d-98bc-62ab536381e3") }
MongoDB server version: 4.0.13
Insert Success!
true
// 清空数据库
> db.user.drop()
true
// 查询数据库(此时为空)
> db.user.find()
>
// 插入多个数据
> load('2.js')
connecting to: mongodb://127.0.0.1:27017/weichuang
Implicit session: session { "id" : UUID("f3d004c8-20d0-4d0e-a5e9-0ec57b273d8a") }
MongoDB server version: 4.0.13
Insert Success!
true
> db.user.find()
{ "_id" : ObjectId("5dee627166e1e1543cfcf6b9"), "name" : "xutiantian", "age" : 11, "hobby" : [ "画画", "弹琴", "民族舞" ], "piano" : { "brand" : "Bluthner", "price" : 140000 } }
{ "_id" : ObjectId("5dee627166e1e1543cfcf6ba"), "name" : "wangqianqian", "age" : 12, "hobby" : [ "毛笔字", "弹琴", "民族舞" ], "piano" : { "brand" : "Fazioli", "price" : 110000 } }
{ "_id" : ObjectId("5dee627166e1e1543cfcf6bb"), "name" : "liangyunwei", "age" : 12, "hobby" : [ "吃饭", "弹琴", "民族舞" ], "piano" : { "brand" : "C. Bechstein", "price" : 310000 } }
// 更新数据库中的数据(错误方式,会覆盖并丢数据)
> db.user.update({name:'xutiantian'},{age:10})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("5dee627166e1e1543cfcf6b9"), "age" : 10 }
{ "_id" : ObjectId("5dee627166e1e1543cfcf6ba"), "name" : "wangqianqian", "age" : 12, "hobby" : [ "毛笔字", "弹琴", "民族舞" ], "piano" : { "brand" : "Fazioli", "price" : 110000 } }
{ "_id" : ObjectId("5dee627166e1e1543cfcf6bb"), "name" : "liangyunwei", "age" : 12, "hobby" : [ "吃饭", "弹琴", "民族舞" ], "piano" : { "brand" : "C. Bechstein", "price" : 310000 } }
// 某一条数据更新(正确方式,但不方便)
> db.user.update({ name: 'xutiantian' }, {
... name: 'xutiantian',
... age: 10,
... hobby: ['画画', '弹琴', '民族舞'],
... piano: {
... brand: 'Bluthner',
... price: 140000
... }
... })
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("5dee649f66e1e1543cfcf6bf"), "name" : "xutiantian", "age" : 10, "hobby" : [ "画画", "弹琴", "民族舞" ], "piano" : { "brand" : "Bluthner", "price" : 140000 } }
{ "_id" : ObjectId("5dee649f66e1e1543cfcf6c0"), "name" : "wangqianqian", "age" : 12, "hobby" : [ "毛笔字", "弹琴", "民族舞" ], "piano" : { "brand" : "Fazioli", "price" : 110000 } }
{ "_id" : ObjectId("5dee649f66e1e1543cfcf6c1"), "name" : "liangyunwei", "age" : 12, "hobby" : [ "吃饭", "弹琴", "民族舞" ], "piano" : { "brand" : "C. Bechstein", "price" : 310000 } }
// // 某一条数据更新(正确方式,方便)
> db.user.update({name:'xutiantian'},{$set:{age: 11.5}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("5dee649f66e1e1543cfcf6bf"), "name" : "xutiantian", "age" : 11.5, "hobby" : [ "画画", "弹琴", "民族舞" ], "piano" : { "brand" : "Bluthner", "price" : 140000 } }
{ "_id" : ObjectId("5dee649f66e1e1543cfcf6c0"), "name" : "wangqianqian", "age" : 12, "hobby" : [ "毛笔字", "弹琴", "民族舞" ], "piano" : { "brand" : "Fazioli", "price" : 110000 } }
{ "_id" : ObjectId("5dee649f66e1e1543cfcf6c1"), "name" : "liangyunwei", "age" : 12, "hobby" : [ "吃饭", "弹琴", "民族舞" ], "piano" : { "brand" : "C. Bechstein", "price" : 310000 } }
> db.user.drop()
true
> db.user.find()
> load('2.js')
connecting to: mongodb://127.0.0.1:27017/weichuang
Implicit session: session { "id" : UUID("a391815d-fd2a-4012-819f-b488ecbfb648") }
MongoDB server version: 4.0.13
Insert Success!
true
> db.user.find()
{ "_id" : ObjectId("5defb269af75827244d1f227"), "name" : "xutiantian", "age" : 11, "hobby" : [ "画画", "弹琴", "民族舞" ], "piano" : { "brand" : "Bluthner", "price" : 140000 } }
{ "_id" : ObjectId("5defb269af75827244d1f228"), "name" : "wangqianqian", "age" : 12, "hobby" : [ "毛笔字", "弹琴", "民族舞" ], "piano" : { "brand" : "Fazioli", "price" : 110000 } }
{ "_id" : ObjectId("5defb269af75827244d1f229"), "name" : "liangyunwei", "age" : 12, "hobby" : [ "吃饭", "弹琴", "民族舞" ], "piano" : { "brand" : "C. Bechstein", "price" : 310000 } }
// 删除一条数据中的某个值(unset)
> db.user.update({name:'wangqianqian'},{$unset:{'hobby':''}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("5defb269af75827244d1f227"), "name" : "xutiantian", "age" : 11, "hobby" : [ "画画", "弹琴", "民族舞" ], "piano" : { "brand" : "Bluthner", "price" : 140000 } }
{ "_id" : ObjectId("5defb269af75827244d1f228"), "name" : "wangqianqian", "age" : 12, "piano" : { "brand" : "Fazioli", "price" : 110000 } }
{ "_id" : ObjectId("5defb269af75827244d1f229"), "name" : "liangyunwei", "age" : 12, "hobby" : [ "吃饭", "弹琴", "民族舞" ], "piano" : { "brand" : "C. Bechstein", "price" : 310000 } }
// upsert: 如果有某一个属性,则去更新,如果没有这个属性,则插入这个属性
> db.user.update({name:'xutiantian'},{$set: {age: 10}},{upsert: true})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("5defb269af75827244d1f227"), "name" : "xutiantian", "age" : 10, "hobby" : [ "画画", "弹琴", "民族舞" ], "piano" : { "brand" : "Bluthner", "price" : 140000 } }
{ "_id" : ObjectId("5defb269af75827244d1f228"), "name" : "wangqianqian", "age" : 12, "piano" : { "brand" : "Fazioli", "price" : 110000 } }
{ "_id" : ObjectId("5defb269af75827244d1f229"), "name" : "liangyunwei", "age" : 12, "hobby" : [ "吃饭", "弹琴", "民族舞" ], "piano" : { "brand" : "C. Bechstein", "price" : 310000 } }
// multi 给每条数据的某个属性统一为一个值, 如果没有multi: true,则只会作用于第一条数据
> db.user.update({}, {$set: {hobby:['弹琴']}}, {multi: true})
WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 })
> db.user.find()
{ "_id" : ObjectId("5defb269af75827244d1f227"), "name" : "xutiantian", "age" : 10, "hobby" : [ "弹琴" ], "piano" : { "brand" : "Bluthner", "price" : 140000 } }
{ "_id" : ObjectId("5defb269af75827244d1f228"), "name" : "wangqianqian", "age" : 12, "piano" : { "brand" : "Fazioli", "price" : 110000 }, "hobby" : [ "弹琴" ] }
{ "_id" : ObjectId("5defb269af75827244d1f229"), "name" : "liangyunwei", "age" : 12, "hobby" : [ "弹琴" ], "piano" : { "brand" : "C. Bechstein", "price" : 310000 } }
// push 在某条数据中给数组格式的数据属性中添加一个新的值
> db.user.update({name: 'liangyunwei'}, {$push:{hobby: '玩游戏'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("5defb269af75827244d1f227"), "name" : "xutiantian", "age" : 10, "hobby" : [ "弹琴" ], "piano" : { "brand" : "Bluthner", "price" : 140000 } }
{ "_id" : ObjectId("5defb269af75827244d1f228"), "name" : "wangqianqian", "age" : 12, "piano" : { "brand" : "Fazioli", "price" : 110000 }, "hobby" : [ "弹琴" ] }
{ "_id" : ObjectId("5defb269af75827244d1f229"), "name" : "liangyunwei", "age" : 12, "hobby" : [ "弹琴", "玩游戏" ], "piano" : { "brand" : "C. Bechstein", "price" : 310000 } }
// addToSet 查找某条数据中数组格式的数据属性中是否有这个属性值(检查),如果不存在,则插入
// 如果是push,并不会进行检查,则插入的数据可能会重复
> db.user.update({name: 'xutiantian'}, {$addToSet: {hobby: '睡觉'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("5defb269af75827244d1f227"), "name" : "xutiantian", "age" : 10, "hobby" : [ "弹琴", "睡觉" ], "piano" : { "brand" : "Bluthner", "price" : 140000 } }
{ "_id" : ObjectId("5defb269af75827244d1f228"), "name" : "wangqianqian", "age" : 12, "piano" : { "brand" : "Fazioli", "price" : 110000 }, "hobby" : [ "弹琴" ] }
{ "_id" : ObjectId("5defb269af75827244d1f229"), "name" : "liangyunwei", "age" : 12, "hobby" : [ "弹琴", "玩游戏" ], "piano" : { "brand" : "C. Bechstein", "price" : 310000 } }
// each 把好几个属性每一个都插入到数据库中
> var newHobby = ['吃零食','出去玩','学习'];
> db.user.update({name: 'xutiantian'}, {$addToSet: {hobby:{$each: newHobby}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("5defb269af75827244d1f227"), "name" : "xutiantian", "age" : 10, "hobby" : [ "弹琴", "睡觉", "吃零食", "出去玩", "学习" ], "piano" : { "brand" : "Bluthner", "price" : 140000 } }
{ "_id" : ObjectId("5defb269af75827244d1f228"), "name" : "wangqianqian", "age" : 12, "piano" : { "brand" : "Fazioli", "price" : 110000 }, "hobby" : [ "弹琴" ] }
{ "_id" : ObjectId("5defb269af75827244d1f229"), "name" : "liangyunwei", "age" : 12, "hobby" : [ "弹琴", "玩游戏" ], "piano" : { "brand" : "C. Bechstein", "price" : 310000 } }
// 把某个属性中的值(按照下标)修改
> db.user.update({name: 'xutiantian'}, {$set: {'hobby.0':'看动画片'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("5defb269af75827244d1f227"), "name" : "xutiantian", "age" : 10, "hobby" : [ "看动画片", "睡觉", "吃零食", "出去玩", "学习" ], "piano" : { "brand" : "Bluthner", "price" : 140000 } }
{ "_id" : ObjectId("5defb269af75827244d1f228"), "name" : "wangqianqian", "age" : 12, "piano" : { "brand" : "Fazioli", "price" : 110000 }, "hobby" : [ "弹琴" ] }
{ "_id" : ObjectId("5defb269af75827244d1f229"), "name" : "liangyunwei", "age" : 12, "hobby" : [ "弹琴", "玩游戏" ], "piano" : { "brand" : "C. Bechstein", "price" : 310000 } }
//findAndModify 应答式的,会返回成功或失败的结果
// 3.js
var modify = {
findAndModify: 'user',
query: {name: 'xutiantian'},
update: {$set: {age: 11}},
new: true
};
var result = db.runCommand(modify);
printjson(result);
> load('3.js')
{
"lastErrorObject" : {
"n" : 1,
"updatedExisting" : true
},
"value" : {
"_id" : ObjectId("5defb269af75827244d1f227"),
"name" : "xutiantian",
"age" : 11,
"hobby" : [
"看动画片",
"睡觉",
"吃零食",
"出去玩",
"学习"
],
"piano" : {
"brand" : "Bluthner",
"price" : 140000
}
},
"ok" : 1
}
true
> db.user.drop()
> load('2.js')
// 按条件范围查询查找 大于等于12 小于等于15
> db.user.find(
... {age: {$gte:12, $lte: 15}}
... )
{ "_id" : ObjectId("5df4b5da39980975e9ca7b9a"), "name" : "wangqianqian", "age" : 12, "hobby" : [ "毛笔字", "弹琴", "民族舞" ], "piano" : { "brand" : "Fazioli", "price" : 110000 } }
{ "_id" : ObjectId("5df4b5da39980975e9ca7b9b"), "name" : "liangyunwei", "age" : 12, "hobby" : [ "吃饭", "弹琴", "民族舞" ], "piano" : { "brand" : "C. Bechstein", "price" : 310000 } }
// 按条件范围查找,大于10,小于14
> db.user.find(
... {age: {$gt:10, $lt: 14}},
... {name: true, age: true}
... )
{ "_id" : ObjectId("5e0aacf66ad7fc9f6c8bc5b8"), "name" : "xutiantian", "age" : 11 }
// 按条件查找,含某些条件
> db.user.find(
... {age: {$in: [10,11]}},
... {name: true, age: true, _id: false}
... )
{ "name" : "xutiantian", "age" : 11 }
>
// “或”逻辑,按条件查找,满足其一就行
> db.user.find({
... $or: [
... {age: {$gte: 18}},
... {'piano.brand': 'Fazioli'}
... ]},
... {name: true, age: true, _id: false}
... )
{ "name" : "wangqianqian", "age" : 14 }
{ "name" : "liangyunwei", "age" : 18 }
// “与”逻辑,全部条件同时满足进行查询
// db.user.find({
// $and: [
// {age: {$gte: 18}},
// {'piano.brand': 'Fazioli'}
// ]},
// {name: true, age: true, _id: false}
// )
// 无数据满足
// “非逻辑”,查找不是当前条件的数据项 not
// 精确匹配 必须全部满足
// 如果有[],则表示数据要完全一致,才能被查到
> db.user.find(
... {hobby: ['毛笔字', '弹琴', '民族舞']},
... {name: true, age: true, _id: false}
...)
{ "name" : "wangqianqian", "age" : 14 }
// 模糊查询,
// 没有[], 只要含这个条件,则筛选出所有数据
> db.user.find(
... {hobby: '弹琴'},
... {name: true, age: true, _id: false}
...)
// 数组查询 ,$all, 需要这些条件都存在,才符合条件
> db.user.find(
... {hobby: {$all: ['画画', '弹琴']}},
... {name: true, age: true, _id: false}
... )
{ "name" : "xutiantian", "age" : 11 }
// 数组查询 ,$in, 需要这些条件符合一个,即可
> db.user.find(
... {hobby: {$in:['画画', '吃饭']}},
... {name: true, age: true, _id: false}
... )
{ "name" : "xutiantian", "age" : 11 }
{ "name" : "liangyunwei", "age" : 18 }
// 数组查询 ,可根据某个数据项的个数去筛选
> db.user.find(
... {hobby: {$size:3}},
... {name: true, age: true, _id: false}
... )
{ "name" : "xutiantian", "age" : 11 }
{ "name" : "wangqianqian", "age" : 14 }
{ "name" : "liangyunwei", "age" : 18 }
// 分页查询,
其中limit代表每次显示几条数据,
skip代表跳过几条数据,
sort代表排序【-1是降序,1是升序】
> db.user.find(
... {},
... {name: true, age: true, _id: false}
... ).limit(1).skip(0).sort({age: -1})
{ "name" : "liangyunwei", "age" : 18 }
四、总结
前端技术庞而杂,所以我们需要不断的精进,提高技术的深度和广度。谢谢各位同学,如果这篇文章对您有用的话,麻烦记得点赞收藏哦!
Comments | NOTHING