内容简介:数据库服务器本质上是一个用于存储数据的服务器;数据库服务器中可以放多个数据库。在MongoDB中,数据库和集合都不需要手动创建,当我们创建文档时,如果文档所在的集合或者数据库不存在会自动创建数据库。如果
数据库服务器本质上是一个用于存储数据的服务器;数据库服务器中可以放多个数据库。
一、3个概念
数据库(database)
数据库是一个仓库;可以在仓库中放多个集合。 复制代码
集合(collection)
集合类似于数据;在集合中可以存放多个文档。 复制代码
文档(document)
文档是数据库中的最小单位,我们存储操作的内容都是文档。 复制代码
3个概念的关系
在 MongoDB 中,数据库和集合都不需要手动创建,当我们创建文档时,如果文档所在的集合或者数据库不存在会自动创建数据库。
二、数据库操作(database)
启动数据库命令
mongo 复制代码
查询所有数据库
show dbs; //or show databases; 复制代码
进入(创建)数据库
//进入(创建)my_test数据库 use my_test; 复制代码
如果 my_test
数据库存在,则直接 进入
数据库;
如果 my_test
不存在,则 创建并进入
数据库。
三、集合操作(collection)
新建集合
//新建集合:number db.createCollection('number') 复制代码
查看集合List
show collections; 复制代码
删除集合
/** * @collectionName [集合名] */ db.collectionName.drop(); 复制代码
四、1.文档操作——新增
友情提示:
文档——增、删、改、查的案例是基于如下的基础上:
新建一个数据库 todos
,新建一个集合 todo
。
insertOne()
插入一条数据
/** * @todo [集合名] * @obj {Object} [要插入的数据] * * @TODO: * 只能插入一条 */ db.<collection>.insertOne(obj); 复制代码
Example :
db.todo.insertOne({ name: 'a1', age: 10 }) //查询todo集合中的所有文档 db.todo.find(); //结果:{ "_id" : ObjectId("5cf64b69743e692169bbdbf7"), "name" : "a1", "age" : 10 } 复制代码
insertMany()
插入多条数据
/** * @arr {Array|Object} [要插入的多条数据] */ db.<collection>.insertMany(arr) 复制代码
Example :
db.todo.insertMany([ { name: 'a2', age: 11 }, { name: 'a3', age: 12 } ]); db.todo.find(); /** 结果: { "_id" : ObjectId("5cf64e57743e692169bbdbfa"), "name" : "a1", "age" : 10 } { "_id" : ObjectId("5cf64e5e743e692169bbdbfb"), "name" : "a2", "age" : 11 } { "_id" : ObjectId("5cf64e5e743e692169bbdbfc"), "name" : "a3", "age" : 12 } */ 复制代码
insert()
插入多条 or
插入单条
/** * @data {Object|Array} [要插入的单条或者多条数据] * * @TODO: * * 即2个方法的合集 */ db.todo.insert(data); 复制代码
Example: 同上面 insertOne()
和 insertMeny()
的用法相同。
关于_id
当插入一个文档没有指定 _id
,则文档会根据时间戳自动生成一个 _id
的值。
如果指定了 _id
,则使用 _id
作为ID。
四、2.文档操作——查询
find()
返回所有符合条件的数据;
/** * @obj {Object} [需要筛选的条件] * @return {Array} [符合条件值的集合] */ db.todo.find(obj) 复制代码
Example:
查询 name = a1
的数据
db.todo.find({ name: 'a1' }); // { "_id" : ObjectId("5cf67ae40f133022c604d5b8"), "name" : "a1", "age" : 10 } 复制代码
findOne()
返回符合条数据中的第一条数据;
Example:
/** * @obj {Object} [需要筛选的条件] * @return {Object} [符合条件的值] */ db.todo.find(obj) 复制代码
count()
查询符合条件的数据有多少条;
Example:
/** * @obj {Object} [需要筛选的条件] * @return {Number} [符合条件的值] */ db.todo.find(obj).count(); 复制代码
四、3.文档操作——修改
update()
替换 1个
或者 n个
文档的对象;
修改 1个
或者 n个
文档的对象的值;
删除 1个
或者 n个
文档的对象的键;
/** * @filterObj {Any|Object} [筛选条件] * @newObj {Any} [新的值] * $set {Object} [修改对象的值] * $unset {Object} [删除对象的键] * @config {Object} [配置项] * * multi {Boolean} [是否修改多个对象][default:false] * @TODO: * * 默认值修改筛选条件的第一个对象 */ db.<collection>.update(filterObj, newObj, config); 复制代码
Example:
//将age=10的全部数据的name改为a14 db.todo.update( { //筛选出age=10的数据 age: 10 }, { //将原数据中的name设置为'a14' $set: { name: 'a14' } }, { //修改多个数据 multi: true } ) //删除掉 第一条name=a14的这条数据的name属性 db.todo.update( { name: 'a14' }, { $unset: { name: 'a14' } } ) 复制代码
$unset
、 $set
是MongoDB的文档操作符;
更多的内容请查阅:MongoDB官网操作符
updateOne()
更新一条数据;
updateMany()
更新多条数据;
replaceOne()
替换第一条数据;
四、4.文档操作——删除
@TODO: 在实际开发中,这个操作并不常用,因为实际上所有的删除操作知识改变了数据的状态,保证不会被输出,但是实际上数据还是存在于数据库中。
remove()
删除多个文档或第一个;
deleteOne()
删除第一个;
deleteMany()
删除多个;
Example All Api :
/** * 默认:删除符合条件所有的文档 @removeOne: true; 只删除查询条件的第一个 **/ db.<collection>.remove(query, removeOne); //删除多个 db.<collection>.deleteOne(query); //删除多个 db.<collection>.deleteMany(query); 复制代码
四、5.文档操作——练习题
- 习题的知识点汇总:
比较操作符:
$gt
:大于
$gte
:大于等于
$lt
:小于
$lte
:小于等于
$eq
:等于,必须要全等;
修改/新增/删除操作符
$set
:修改[value];新增{[key]: [value]}
unset
: 删除[key]
添加操作符
$push
:向数组中添加一个值
$addToSet
:向数组中添加一个值(被添加进来的值在这个数组中必须不存在)
方法
limit(n)
:取出n条数据;
skip(m)
:跳过第m条之前的数据,即从 m+1
条开始取。
Example :
/** * [分页] * @page {Number} [当前页] * @page_size {Number} [每页条数] * * @return {Object} * @data {Array} [符合条件的数据] * @total {Number} [总数量] */ function getDataList(page, page_size) { var skip = ( page - 1 ) + page_size; var data = db.<collection>.find({/*筛选条件*/}); return { data: data.limit(page_size).skip(skip), total: data.count() }; } 复制代码
-
习题:
-
答案:
//1 use my_test //2 db.user.insert({ username: 'sunwukong' }); //3 db.user.find(); //4 db.user.insert({ username: 'zhubajie' }); //5 db.user.find(); //6 db.user.find().count(); //7 db.user.find({ username: 'sunwukong' }) //8 db.user.update( { username: 'sunwukong' }, { $set: { address: 'huaguoshan' } }, { //修改多个 multi: true } ) //9 db.user.update( { username: 'zhubajie' }, { $set: { username: 'tangseng' } }, { multi: true } ) //10 db.user.update( { username: 'sunwukong', }, { $unset: { // 这里的值随便填写,主要是给:`$unset`添加一个键,准备删除。 address: 'delete' } }, { multi: true } ) //11 db.user.update( { username: 'sunwukong' }, { $set: { hobby: { cities: ['beijing', 'shanghai', 'shenzhen'], movies: ['sanguo', 'hero'] } } }, { multi: true } ) //12 db.user.update( { username: 'tangseng' }, { $set: { hobby: { movies: ['A Chinese Odyssey', 'King of comedy'] } } }, { multi: true } ) //13 db.user.find( { 'hobby.movies': 'hero' } ) //14 db.user.update( { username: 'tangseng' }, { // 操作符:$push可以向数组中添加数据 // 操作符: $addToSet也可以;区别是`$addToSet`对于重复数据不添加;$push则不会。 $push: { 'hobby.movies': 'Intersterllar' } } ) //15 db.user.remove( { 'hobby.cities': 'beijing' } ) //16 db.user.drop(); //17.插入20,00条数据 var data = []; for(var i = 1; i <= 1000*20; i++) { data.push( { num: i } ) } db.numbers.insert(data) //创建numbers集合并插入2w条数据 //18.查询num = 500的数据 numbers.find({ num: 500 }) //or numbers.find({ num: { $eq: 500 } }) //区别: // 前者会匹配数组中值为500的数据; // 后者只匹配num=500的数据; //19.查询num>5000的文档 numbers.find({ num: { $gt: 5000 }) //20.查询num>=19996的文档 numbers.find({ num: { $gte: 19996 }) //21.查询num<30的文档 numbers.find({ num: { $lt: 30 }) //22.查询 40 < num < 50 的文档 numbers.find({ num: { $lt: 50, $gt: 40 } }) //23.查询集合中前10条数据 numbers.find().limit(10) //24.查询集合中第11-20条数据 numbers.find().limit(10).skip(10) //25.查询第21-30条数据 numbers.find().limit(10).skip(20) 复制代码
五、1.文档间的关系
一对一(one to one)
一个人 对应 一个身份证号码
db.human.insert({ name: 'david', idcard: { idcard: 123465789102345678 } }) 复制代码
一对多(one to many)/ 多对一 (many to one)
一个账户 对应 多个订单
/** 用户david有订单 d1、d2,可以使用d1、d2查询到商品信息; 商品通过user_id可以查询到用户; 一个订单只能对应一个用户,一个用户可以拥有多个订单。 */ db.users.insert({ _id: 1, name: 'david', //订单 orders: ['d1', 'd2'] }) db.orders.insert([ { user_id: 1, id: 'd1', name: '商品1' }, { user_id: 1, id: 'd1', name: '商品1' } ]) 复制代码
多对多(many to many)
多个老师对应多个学生
/** */ db.teachers.insert([ { tid: 't1', name: 't1', students: ['s1', 's2'] }, { tid: 't2', name: 't2', students: ['s1', 's2', 's3'] }, { tid: 't3', name: 't3', students: ['s1'] } ]) db.students.insert([ { sid: 's1', name: 's1 students: ['t1', 't2'] }, { sid: 's2', name: 's2', students: ['t1', 't2', 't3'] }, { sid: 's3', name: 's3', students: ['t3'] } ]) 复制代码
五、2.文档间的关系——习题
知识点归纳:
$or
:或操作符,详细用法见 29
题答案
$inc
:自增操作符,详细用法见 33
题答案
原始数据:
//dept.json /* 1 */ { "_id" : ObjectId("5cf7c7c0ffd6ea864b5a22cc"), "deptno" : 10.0, "dname" : "财务部", "loc" : "北京" } /* 2 */ { "_id" : ObjectId("5cf7c7c0ffd6ea864b5a22cd"), "deptno" : 20.0, "dname" : "办公室", "loc" : "上海" } /* 3 */ { "_id" : ObjectId("5cf7c7c0ffd6ea864b5a22ce"), "deptno" : 30.0, "dname" : "销售部", "loc" : "广州" } /* 4 */ { "_id" : ObjectId("5cf7c7c0ffd6ea864b5a22cf"), "deptno" : 40.0, "dname" : "运营部", "loc" : "深圳" } //emp.json /* 1 */ { "_id" : ObjectId("5cf7ca79ffd6ea864b5a22d0"), "empno" : 7369.0, "ename" : "林冲", "job" : "职员", "mgr" : 7902.0, "hiredate" : ISODate("1980-12-16T16:00:00.000Z"), "sal" : 1200.0, "depno" : 20.0 } /* 2 */ { "_id" : ObjectId("5cf7ca79ffd6ea864b5a22d1"), "empno" : 7499.0, "ename" : "孙二娘", "job" : "销售", "mgr" : 7698.0, "hiredate" : ISODate("1981-02-19T16:00:00.000Z"), "sal" : 1600.0, "comm" : 300.0, "depno" : 30.0 } /* 3 */ { "_id" : ObjectId("5cf7ca79ffd6ea864b5a22d2"), "empno" : 7521.0, "ename" : "扈三娘", "job" : "销售", "mgr" : 7698.0, "hiredate" : ISODate("1981-02-19T16:00:00.000Z"), "sal" : 800.0, "comm" : 500.0, "depno" : 30.0 } /* 4 */ { "_id" : ObjectId("5cf7ca79ffd6ea864b5a22d3"), "empno" : 7566.0, "ename" : "卢俊义", "job" : "经理", "mgr" : 7839.0, "hiredate" : ISODate("1981-02-19T16:00:00.000Z"), "sal" : 2975.0, "depno" : 20.0 } /* 5 */ { "_id" : ObjectId("5cf7ca79ffd6ea864b5a22d4"), "empno" : 7654.0, "ename" : "潘金莲", "job" : "销售", "mgr" : 7839.0, "hiredate" : ISODate("1981-02-19T16:00:00.000Z"), "sal" : 2975.0, "depno" : 20.0 } 复制代码
问题:
问题答案:
var emp = db.getCollection('emp') var dept = db.getCollection('dept') //33.为所有工资低于1000的员工增加工资400元 emp.update({ sal: { $lte: 1000 } }, { $inc: { sal: 400 } }) //32.查询所有mgr为7698的所有员工 emp.find({ mgr: 7698 }); //31.查询销售部所有员工 var cwbId = dept.findOne({ dname: '销售部' }).deptno emp.find({depno: cwbId}) //30.查询财务部的所有员工 var cwbId = dept.findOne({ dname: '财务部' }).deptno emp.find({depno: cwbId}) //29.工资 >= 2500 或者 <= 1000 emp.find({ $or: [{sal: { $gte: 2500 }}, { sal: { $lte: 1000 } }] }) //28.工资1000-2000 emp.find({ sal: { $lte: 2000, $gte: 1000 } }) //27.工资<= 2000 emp.find({ sal: { $lte: 2000 } }); 复制代码
六、 排序 和投影
排序
sort()
指定查询文档的筛选条件; sort()
、 limit()
、 skip()
排序部分先后,因为总会先进行排序。
1
:升序排列
-1
:降序排列
默认:如果不指定 sort()
,则按照 _id
排序,而 _id = 时间戳 + 机器码
组成,所以实际上默认是按照 创建时间
排序。
Example :
//按照 工资 降序 排列 emp.find().sort({ sal: -1 }) //先按照 工资(sal) 升序;如果工资相同,再按照编号(empno) 降序排列 emp.find().sort({ sal: 1, empno: -1 }) 复制代码
映射
指定查询时,需要返回的字段。
1
:允许映射;
0
:禁止映射;
//返回 工资(sal) >= 1250 的员工姓名 emp.find({ sal: { $gte: 1250 } }, { ename: 1 }) /*_id会自动加上 {"_id" : ObjectId("5cf7ca79ffd6ea864b5a22d1"),"ename" : "孙二娘"}, {"_id" : ObjectId("5cf7ca79ffd6ea864b5a22d2"),"ename" : "扈三娘"} {"_id" : ObjectId("5cf7ca79ffd6ea864b5a22d3"),"ename" : "卢俊义"} {"_id" : ObjectId("5cf7ca79ffd6ea864b5a22d4"),"ename" : "潘金莲"} */ //如果想忽略_id,可以尝试: emp.find({ sal: { $gte: 1250 } }, { ename: 1, _id: 0 }) 复制代码
七、1.操作MongoDB的库——Mongoose
Mongoose是一个对象文档模型(ODM)库,他对Node原生的MongoDB模块进行了进一步的优化封装,并提供了更多的功能。
为什么要使用mongoose?
- 可以为文档创建一个模式结构(Schema|约束)
- 可以对模型中的对象/文档进行验证
- 数据可以通过类型转换转换为对象模型
- 可以使用中间件来应用业务逻辑挂钩
- 比Node原生的MongoDB驱动更容易
七、2.mongoose——3个概念
Schema(模式对象)
Schema对象定义约束数据库中的文档结构
Model
Model对象作为集合中的所有文档的表示,相当于MongoDB数据库中的集合collection
Document
Document表示集合中的具体文档,相当于集合中的一个具体文档。
创建顺序:先有Schema约束Model,在用Model操作Document
七、3.Mongoose——第一个DEMO
连接数据库,并插入第数据
const mongoose = require('mongoose'); var Schema = mongoose.Schema; mongoose.connect( 'mongodb://localhost:27017/mongoose_test', {useNewUrlParser: true}, function () { console.log('数据库连接成功') }); var stuSchema = new Schema({ name: String, age: Number, gender: { type: String, default: 'woman' }, address: String }) var StuModel = mongoose.model('student', stuSchema) StuModel.create({ name: '孙悟空', age: 18, gender: 'man', address: '花果山' }, function (err) { if(!err) { console.log('插入成功') } }) StuModel.create({ name: '白骨精', age: 18, address: '盘丝洞' }, function (err) { if(!err) { console.log('插入成功') } }) 复制代码
关于更多的 mongoose
api请参阅mongoose官网文档
以上所述就是小编给大家介绍的《MongoDB入门》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- TiDB入门(四):从入门到“跑路”
- MyBatis从入门到精通(一):MyBatis入门
- MyBatis从入门到精通(一):MyBatis入门
- Docker入门(一)用hello world入门docker
- 赵童鞋带你入门PHP(六) ThinkPHP框架入门
- 初学者入门 Golang 的学习型项目,go入门项目
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
VC++.NET入门
Davis Chapman / 中国电力出版社 / 2003-5 / 55.0
《VC++.NET入门》提供了学习Visual C++工具的循序渐进的指导和创建应用程序的向导。你将学习设计应用程序窗口、使用控件、显示图形、创建SDI和MDI应用程序、操作数据库以及创建多任务程序,也将学习在微软的新.E平台下使用Visual C++的一些基本技巧,以及学习它影响设计和编写应用程序的方式。一起来看看 《VC++.NET入门》 这本书的介绍吧!