来源:https://github.com/Vacricticy/mongodb_practice/blob/master/README.md

安装:

  • 官网
  • 启动mongodb服务器:mongod
  • 修改默认端口:mongod --port 新的端口号
    • mongodb默认的端口:27017
  • 设置mongodb数据库的存储路径:mongod --dbpath 路径
  • ⭐ 连接mongodb数据库:mongo

三大基本概念:

  • 数据库 database
  • 集合(数组) collection
    • 类似与SQL中的数据表,本质上是一个数组,里面包含看多个文档对象,[{},{},{}]
  • 文档对象 document
    • 类似与SQL中的记录,一个文档对象{}就是一条记录
  • 一个数据库由多个集合构成,一个集合包含多个文档对象。

基本使用:

  • show dbs 或show databases
    • 查看所有的数据库
  • use xxx
    • 切换到指定的数据库
  • db
    • 查看当前操作的数据库
  • show collections
    • 查看当前数据库中所有的集合

数据库的CRUD操作:

插入数据

  • 插入一条数据
    • db.collectionName.insertOne( {name:’liu’} )
      • db表示的是当前操作的数据库
      • collectionName表示操作的集合,若没有,则会自动创建
      • 插入的文档如果没有手动提供_id属性,则会自动创建一个
  • 插入多条数据
    • db.collectionName.insertMany( [ {name:’liu5’} , {name:’liu6’} ] )
      • 需要用数组包起来
  • 万能API:db.collectionName.insert()
  1. #添加两万条数据
  2. for(var i=0;i<20000;i++){
  3. db.users.insert({username:'liu'+i}) #需要执行20000次数据库的添加操作
  4. }
  5. db.users.find().count()//20000
  6. #优化:
  7. var arr=[];
  8. for(var i=0;i<20000;i++){
  9. arr.push({username:'liu'+i})
  10. }
  11. db.user.insert(arr) #只需执行1次数据库的添加操作,可以节约很多时间

查询数据

  • db.collectionName.find() 或db.collectionName.find({})
    • 查询集合所有的文档,即所有的数据。
    • 查询到的是整个数组对象。在最外层是有一个对象包裹起来的。
    • db.collectionName.count()或db.collectionName.length() 统计文档个数
  • db.collectionName.find({_id:222})
    • 条件查询。注意:结果返回的是一个数组
  • db.collectionName.findOne() 返回的是查询到的对象数组中的第一个对象
    • 注意:
      1. > db.students.find({_id:222}).name //错误
      2. > db.students.findOne({_id:222}).name //正确
  1. # 1.mongodb支持直接通过内嵌文档的属性值进行查询
  2. # 什么是内嵌文档:hobby就属于内嵌文档
  3. {
  4. name:'liu',
  5. hobby:{
  6. movies:['movie1','movie2'],
  7. cities:['zhuhai','chengdu']
  8. }
  9. }
  10. db.users.find({hobby.movies:'movie1'}) //错误
  11. db.users.find({"hobby.movies":'movie1'})//此时查询的属性名必须加上引号
  12. #2.查询操作符的使用
  13. #比较操作符
  14. $gt 大于
  15. $gte 大于等于
  16. $lt 小于
  17. $lte 小于等于
  18. $ne 不等于
  19. $eq 等于的另一种写法
  20. db.users.find({num:{$gt:200}}) #大于200
  21. db.users.find({num:{$gt:200,$lt:300}}) #大于200小于300
  22. $or 或者
  23. db.users.find(
  24. {
  25. $or:[
  26. {num:{$gt:300}},
  27. {num:{$lt:200}}
  28. ]
  29. }
  30. ) #大于300或小于200
  31. #3.分页查询
  32. db.users.find().skip(页码-1 * 每页显示的条数).limit(每页显示的条数)
  33. db.users.find().limit(10) #前10条数据
  34. db.users.find().skip(50).limit(10) #跳过前50条数据,即查询的是第61-70条数据,即第6页的数据
  35. #4.排序
  36. db.emp.find().sort({sal:1}) #1表示升序排列,-1表示降序排列
  37. db.emp.find().sort({sal:1,empno:-1}) #先按照sal升序排列,如果遇到相同的sal,则按empno降序排列
  38. #注意:skip,limit,sort可以以任意的顺序调用,最终的结果都是先调sort,再调skip,最后调limit
  39. #5.设置查询结果的投影,即只过滤出自己想要的字段
  40. db.emp.find({},{ename:1,_id:0}) #在匹配到的文档中只显示ename字段

修改数据

  1. # 1.替换整个文档
  2. # db.collectionName.update(condiction,newDocument)
  3. > db.students.update({_id:'222'},{name:'kang'})
  4. # 2.修改对应的属性,需要用到修改操作符,比如$set,$unset,$push,$addToSet
  5. db.collectionName.update(
  6. # 查询条件
  7. {_id:222},
  8. {
  9. #修改对应的属性
  10. $set:{
  11. name:'kang2',
  12. age:21
  13. }
  14. #删除对应的属性
  15. $unset:{
  16. gender:1 //这里的1可以随便改为其他的值,无影响
  17. }
  18. }
  19. )
  20. # 3.update默认与updateOne()等效,即对于匹配到的文档只更改其中的第一个
  21. # updateMany()可以用来更改匹配到的所有文档
  22. db.students.updateMany(
  23. {name:'liu'},
  24. {
  25. $set:{
  26. age:21,
  27. gender:222
  28. }
  29. }
  30. )
  31. # 4.向数组中添加数据
  32. db.users.update({username:'liu'},{$push:{"hobby.movies":'movie4'}})
  33. #如果数据已经存在,则不会添加
  34. db.users.update({username:'liu'},{$addToSet:{"hobby.movies":'movie4'}})
  35. # 5.自增自减操作符$inc
  36. {$inc:{num:100}} #让num自增100
  37. {$inc:{num:-100}} #让num自减100
  38. db.emp.updateMany({sal:{$lt:1000}},{$inc:{sal:400}}) #给工资低于1000的员工增加400的工资

删除数据

  1. # 1. db.collectionName.remove()
  2. # remove默认会删除所有匹配的文档。相当于deleteMany()
  3. # remove可以加第二个参数,表示只删除匹配到的第一个文档。此时相当于deleteOne()
  4. db.students.remove({name:'liu',true})
  5. # 2. db.collectionName.deleteOne()
  6. # 3. db.collectionName.deleteMany()
  7. db.students.deleteOne({name:'liu'})
  8. # 4. 删除所有数据:db.students.remove({})----性格较差,内部是在一条一条的删除文档。
  9. # 可直接通过db.students.drop()删除整个集合来提高效率。
  10. # 5.删除集合
  11. db.collection.drop()
  12. # 6.删除数据库
  13. db.dropDatabase()
  14. # 7.注意:删除某一个文档的属性,应该用update。 remove以及delete系列删除的是整个文档
  15. # 8.当删除的条件为内嵌的属性时:
  16. db.users.remove({"hobby.movies":'movie3'})

文档之间的关系:

一对一

一对多

  1. #用户与订单:
  2. db.users.insert([
  3. {_id:100,username:'liu1'},
  4. {_id:101,username:'liu2'}
  5. ])
  6. db.orders.insert([
  7. {list:['apple','banana'],user_id:100},
  8. {list:['apple','banana2'],user_id:100},
  9. {list:['apple'],user_id:101}
  10. ])
  11. 查询liu1的所有订单:
  12. 首先获取liu1id: var user_id=db.users.findOne({name:'liu1'})._id;
  13. 根据id从订单集合中查询对应的订单: db.orders.find({user_id:user_id})

多对多

  1. #老师与学生
  2. db.teachers.insert([
  3. {
  4. _id:100,
  5. name:'liu1'
  6. },
  7. {
  8. _id:101,
  9. name:'liu2'
  10. },
  11. {
  12. _id:102,
  13. name:'liu3'
  14. }
  15. ])
  16. db.students.insert([
  17. {
  18. _id:1000,
  19. name:'xiao',
  20. tech_ids:[100,101]
  21. },
  22. {
  23. _id:1001,
  24. name:'xiao2',
  25. tech_ids:[102]
  26. }
  27. ])

mongoose:

简介:

  • 1.mongoose是nodejs中的专门用于操作mongodb数据库的js库
  • 2.mongoose中的对象:
    • Schema 模式对象(用于约束文档的结构)
    • Model 模型对象(即mongodb中的集合)
    • Document 文档对象(即mongodb中的文档)

安装:

  1. npm i -s mongoose

连接数据库:

  1. // 1.引入mongoose
  2. const mongoose = require("mongoose");
  3. // 2.连接mongodb数据库
  4. mongoose.connect("mongodb://localhost/users", {
  5. useNewUrlParser: true,
  6. useUnifiedTopology: true,
  7. });
  8. // 3.监听mongodb数据库的连接状态
  9. // 绑定数据库连接成功事件
  10. mongoose.connection.once("open", function () {
  11. console.log("连接成功");
  12. });
  13. // 绑定数据库连接失败事件
  14. mongoose.connection.once("close", function () {
  15. console.log("数据库连接已经断开");
  16. });
  17. // 4.断开数据库连接(一般不用)
  18. mongoose.disconnect();

创建模式对象和模型对象:

  1. const Schema=mongoose.schema;
  2. //创建模式对象
  3. const stuSchema=new Schema({
  4. name:String,
  5. age:Number,
  6. gender:{
  7. type:String,
  8. default:'female'
  9. },
  10. address:String,
  11. // 嵌套
  12. list: {
  13. // 如果加了type:Object,那么就没有下面的默认空值。
  14. list1: [],
  15. list2: []
  16. }
  17. }, { collection: 'student'} )
  18. // 这里mongoose.Schema最好要写上第二个参数,明确指定到数据库中的哪个表取数据
  19. // 目的就是为了以后操作数据要去这个表中。这里不写第二个参数的话,后面你会遇到坑。
  20. //创建模型对象
  21. const StuModel=stuSchema.model("student",stuSchema); //第一个参数表示创建的集合的名称,第二个参数表示利用的模式对象

利用模型对象进行增删查改操作:

添加操作:

  1. UserModel.create({ user_id: 100, name: "liu1" }, function (err) {
  2. if (!err) {
  3. console.log("插入成功");
  4. } else {
  5. console.log(err);
  6. }
  7. });
  8. let data = [
  9. { user_id: 101, name: "liu2", age: 22 },
  10. { user_id: 102, name: "liu3" },
  11. ];
  12. UserModel.create(data, function (err) {
  13. console.log(arguments[1]); //第二个值表示的是所添加的文档对象,是一个数组
  14. });

查询操作:

  1. /*
  2. 查询:
  3. model.find(conditions,[projection],[options],callback)
  4. conditions:查询的条件
  5. projection:投影 { name: 1, gender: 1, _id: 0 } 或 'name gender -_id'
  6. options:查询选项 { skip: xx, limit: xx }
  7. model.findOne(...)
  8. model.findById(...)
  9. model.countDocuments(conditions,callback) 查询文档的数量
  10. */
  11. UserModel.find({}, function (err, data) {
  12. console.log(data);
  13. });
  14. UserModel.find(
  15. { name: /liu/i },
  16. "name gender -_id",
  17. { skip: 2, limit: 1 },
  18. function (err, data) {
  19. console.log(data); //返回的是一个文档对象数组
  20. }
  21. );
  22. UserModel.findById("5f9fbfba14319e492c0f5bc4", function (err, data) {
  23. console.log(data);
  24. console.log(data instanceof UserModel); //true 返回的文档对象属于模型对象(即集合)的实例对象
  25. });
  26. UserModel.countDocuments({}, function (err, data) {
  27. console.log(data);
  28. });

修改操作:

  1. /* 修改:
  2. model.update(conditions,[doc],[options],callback)
  3. doc:修改后的文档对象
  4. model.updateMany(...)
  5. model.uodateOne(...)
  6. */
  7. UserModel.updateOne({ name: "liu1" }, { $set: { age: 22 } }, function (
  8. err,
  9. data
  10. ) {
  11. if (!err) {
  12. console.log("修改成功");
  13. }
  14. });
  15. UserModel.find({ name: "liu1" }, function (err, data) {
  16. console.log(data);
  17. });

删除操作:

  1. /*
  2. 删除:
  3. model.remove(conditions,callback)
  4. model.deleteOne(...)
  5. model.deleteMany(...)
  6. */
  7. UserModel.remove(
  8. {
  9. name: "liu2",
  10. },
  11. function (err, data) {
  12. console.log("删除成功");
  13. }
  14. );
  15. UserModel.find({}, function (err, data) {
  16. console.log(data);
  17. });

模块化处理:

  • 1.单独创建一个数据库连接文件dbconncet.js
    1. const mongoose = require("mongoose");
    2. mongoose.connect("mongodb://localhost/mongooes_test", {
    3. useNewUrlParser: true,
    4. useUnifiedTopology: true,
    5. });
    6. mongoose.connection.once("open", function () {
    7. console.log("连接成功");
    8. });
  • 2.为每一个集合创建一个模型对象文件xxxModel.js
    1. const mongoose = require("mongoose");
    2. const Schema = mongoose.Schema;
    3. const userSchema = new Schema({
    4. user_id: String,
    5. name: String,
    6. age: Number,
    7. gender: {
    8. type: Number,
    9. default: 0,
    10. },
    11. });
    12. const UserModel = mongoose.model("user", userSchema);
    13. module.exports = UserModel;
  • 3.在最终的文件index.js中引入数据库连接文件和创建模型的文件: ```javascript const mongoose = require(“./dbconncet”); const PostModel = require(“./models/postModel”);

PostModel.findOne({}, function (err, data) { if (!err) { console.log(data); } }); ```