视频教程:https://www.bilibili.com/video/BV18s411E78K?share_source=copy_web

基于 MongoDB 4.4.3

环境:Windows 10

关于安装

MongoDB服务(服务器)

  • 开启服务 / 数据文件存放路径 / 端口

    mongod -dbpath D:\development\MongoDB\data\db --port 18080
    

    以上设置在永久性服务中,需要另行配置

上述启动方法,每次启动否需要输入命令,所以建立一个永久性的服务,即加入到windows本地服务(系统服务)中

  • 安装MongoDB服务

    D:\development\MongoDB\bin\mongod.exe --config "C:\development\MongoDB\mongod.cfg" --install
    
  • 启动MongoDB服务

    net start MongoDB
    

    启动前在bin目录下检查配置文件mongod.cfg,

    # mongod.conf# 存储数据
    storage:dbPath: D:\development\MongoDB\data\dbjournal:enabled: true# 日志数据
    systemLog:destination: filelogAppend: truepath:  D:\development\MongoDB\log\mongod.log# 网络接口
    net:port: 27017bindIp: 127.0.0.1
  • 关闭MongoDB服务

    net stop MongoDB
    
  • 移除 MongoDB 服务

    mongod --remove
    

命令行(客户端)

  • 打开命令行(连接服务器)

    mongo
    

基本概念

MongoDB面向文档数据库

数据库

  • MongoDB 单个实例可以有多个独立数据库,每个包含集合、权限,

  • 不同的数据库,放置在不同文件

  • 默认数据库 “db”,存储在 data 目录下

集合(表)

  • 集合在数据库中

  • 集合没有固定结构,可以插入不同格式、类型的数据(通常插入有关联性的数据)

  • 第一个 文档 插入时,集合就会被创建

    {"site":"www.baidu.com"}
    {"site":"www.google.com","name":"Google"}
    {"site":"www.runoob.com","name":"菜鸟教程","num":5}
    

文档(行)

  • 对应 RDBMS(关系数据库管理系统:Relational Database Management System):“行”

  • 文档是键值对(BSON)

  • 文档不需要设置相同字段,相同字段不需要相同数据类型

    {"site":"www.runoob.com", "name":"菜鸟教程"}
    

基本操作

数据库操作

  • show dbs: 显示所有数据库

    > show dbs
    admin   0.000GB
    config  0.000GB
    local   0.000GB
    
  • db: 显示当前数据库 / 集合(表)。在 MongoDB 中默认数据库是:test。 如果没有创建过任何数据库,则集合/文档将存储在test数据库中。

    > db
    test
    
  • use: 连接到指定数据库 / 创建数据库。

    用法1: 切换数据库

    > use local
    

    用法2: 数据库名不存在,则创建数据库。

    # 数据库创建成功,但是不能查询到
    > use mytest
    switched to db mytest
    > db
    mytest
    > show dbs
    admin   0.000GB
    config  0.000GB
    local   0.000GB# 新建数据库需要插入数据才可以用 dbs 命令检索出来
    # 在mytest数据库下新建 collectiontest 集合
    > db.collectiontest.insert({"name":"test1"})
    WriteResult({ "nInserted" : 1 })
    > show dbs
    admin   0.000GB
    config  0.000GB
    local   0.000GB
    mytest  0.000GB
    > show collections
    collectiontest
    
  • db.dropDatabase(): 删除数据库

    > show dbs
    admin   0.000GB
    config  0.000GB
    local   0.000GB
    mytest  0.000GB
    > use mytest
    switched to db mytest
    > db.dropDatabase()
    { "dropped" : "mytest", "ok" : 1 }
    > show dbs
    admin   0.000GB
    config  0.000GB
    local   0.000GB
    >
    

集合操作

  • db.createCollection():

    在test数据库创建runoob集合,

    > db
    test
    > show collections
    > db.createCollection("runoob")
    { "ok" : 1 }
    > show collections
    runoob
    
  • db.createCollection(): 带参

    创建固定集合 mycol,整个集合空间大小 6142800 KB, 文档最大个数为 10000 个

    > db.createCollection("mycol", { capped : true, autoIndexId : true, size : 6142800, max : 10000 } )
    { "ok" : 1 }
    > show collections
    mycol
    runoob
    >
    
  • show collections: 查看已有集合

    > use test
    switched to db test
    > show collections
    mycol
    runoob
    >
    
  • 集合如果不存在,在插入文档时,会自动创建集合

    > use test
    switched to db test
    > db.mycol02.insert({"name":"runoob-test"})
    WriteResult({ "nInserted" : 1 })
    > show collections
    mycol
    mycol02
    runoob
    
  • db..drop(): 删除集合

    > show collections
    mycol
    mycol02
    runoob
    > db.mycol02.drop()
    true
    > show collections
    mycol
    runoob
    >
    

文档操作

添加

  • db.collection.insert():

    向集合中插入一个或多个文档

    向集合插入文档时,如果没有给指定指定 _id 属性,则数据库会自动为文档添加,该属性用来作为文档的唯一标识

    _id 可以自己指定,这样数据库就不会自动添加了。自己指定的 _id 也必须唯一,否则报错

  • 插入一个文档

    > db.stus.insert({name: "孙悟空", age: 20, gender: "男"});
    WriteResult({ "nInserted" : 1 })
    > db.stus.find();
    { "_id" : ObjectId("61b58a89e4b077ad0bb9c270"), "name" : "孙悟空", "age" : 20, "gender" : "男" }
    >
    
  • 插入多个文档

    > db.stus.insert([
    ...     {name: "猪八戒", age: 15, gender: "男"},
    ...     {name: "白骨精", age: 19, gender: "男"},
    ...     {name: "蜘蛛精", age: 16, gender: "女"}
    ... ]);
    BulkWriteResult({"writeErrors" : [ ],"writeConcernErrors" : [ ],"nInserted" : 3,  // 新插入3条"nUpserted" : 0,"nMatched" : 0,"nModified" : 0,"nRemoved" : 0,"upserted" : [ ]
    })
    > db.stus.find();
    { "_id" : ObjectId("61b58a89e4b077ad0bb9c270"), "name" : "孙悟空", "age" : 20, "gender" : "男" }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb1"), "name" : "猪八戒", "age" : 15, "gender" : "男" }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb2"), "name" : "白骨精", "age" : 19, "gender" : "男" }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb3"), "name" : "蜘蛛精", "age" : 16, "gender" : "女" }
    >
    

    _id 也可以自己生成,也可以自己指定

    # 自己生成
    > ObjectId()
    ObjectId("61b5d73d68ba54fa0c434669")
    ># 自己指定
    > db.stus.insert({_id: 'hello123', name: "如来佛", age: 20, gender: "男"});
    WriteResult({ "nInserted" : 1 })
    > db.stus.find()
    { "_id" : ObjectId("61b58a89e4b077ad0bb9c270"), "name" : "孙悟空", "age" : 20, "gender" : "男" }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb1"), "name" : "猪八戒", "age" : 15, "gender" : "男" }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb2"), "name" : "白骨精", "age" : 19, "gender" : "男" }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb3"), "name" : "蜘蛛精", "age" : 16, "gender" : "女" }
    { "_id" : "hello123", "name" : "如来佛", "age" : 20, "gender" : "男" }# 自己指定的 _id 也必须唯一,否则报错
    > db.stus.insert({_id: 'hello123', name: "如来佛", age: 20, gender: "男"});
    WriteResult({"nInserted" : 0,"writeError" : {"code" : 11000,"errmsg" : "E11000 duplicate key error collection: test.stus index: _id_ dup key: { _id: \"hello123\" }"}
    })
    >
    
  • db.collection.insertOne():db.collection.insertMany():

    这两个方法是在 3.2 以后新加入的,分别用于 添加一个添加多个

查询

  • db.collection.find(): 参数是{},返回的是文档数组

    find():查询集合中所有符合条件的文档,可以接收一个对象作为条件参数

    # 没有参数,或者传入一个空对象 {},表示查询所有文档
    > db.stus.find();
    > db.stus.find({});
    { "_id" : ObjectId("61b58a89e4b077ad0bb9c270"), "name" : "孙悟空", "age" : 20, "gender" : "男" }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb1"), "name" : "猪八戒", "age" : 15, "gender" : "男" }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb2"), "name" : "白骨精", "age" : 19, "gender" : "男" }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb3"), "name" : "蜘蛛精", "age" : 16, "gender" : "女" }
    { "_id" : "hello123", "name" : "如来佛", "age" : 20, "gender" : "男" }
    
    # { 属性名: 值 }
    # 查询 _id 为 "hello123" 的文档
    > db.stus.find({_id: "hello123"})
    { "_id" : "hello123", "name" : "如来佛", "age" : 20, "gender" : "男" }# 查询 age==15 而且 gender==男
    > db.stus.find({ age: 15, gender: "男"})
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb1"), "name" : "猪八戒", "age" : 15, "gender" : "男" }
    >
    

    查询操作符:

    • 比较操作符
    操作符 描述 例子
    $eq 等于 db.col.find({“by”: {$eq:“辛小花”}})
    $ne 不等于 db.col.find({“by”: {$ne:“辛小花”}})
    $gt 大于 db.col.find({“like”: {$gt: 3}})
    $gte 大于等于 db.col.find({“like”: {$gte: 3}})
    $lt 小于 db.col.find({“like”: {$lt: 120}})
    $lte 小于等于 db.col.find({“like”: {$lte: 120}})
    $in 在数组中 db.col.find({“by”: {$in: [“辛小花”, “黄仁宇”]}})
    $nin 不在数组中 db.col.find({“by”: {$nin: [“辛小花”, “黄仁宇”]}})
    • 逻辑操作符
    操作符 描述 例子
    $and 逻辑与, db.col.find({KaTeX parse error: Expected '}', got 'EOF' at end of input: and: [{"by": {in: [“辛小花”, “黄仁宇”]}}, {“like”: {$lt: 120}}]})
    $or 逻辑或 db.col.find({KaTeX parse error: Expected '}', got 'EOF' at end of input: or: [{"by": {in: [“辛小花”, “黄仁宇”]}}, {“like”: {$lt: 120}}]})
    $not 逻辑否 db.col.find({“by”: {$not: { $eq: “辛小花”}}})
    $nor 同时不能匹配 db.col.find({KaTeX parse error: Expected '}', got 'EOF' at end of input: …花'}, {"like": {gt: 120}}]})
  • db.collection.findOne(): 参数是{},返回的是文档对象

    > db.stus.find({ age: 20})             )
    { "_id" : ObjectId("61b58a89e4b077ad0bb9c270"), "name" : "孙悟空", "age" : 20, "gender" : "男" }
    { "_id" : "hello123", "name" : "如来佛", "age" : 20, "gender" : "男" }
    > db.stus.findOne({ age: 20})
    {"_id" : ObjectId("61b58a89e4b077ad0bb9c270"),"name" : "孙悟空","age" : 20,"gender" : "男"
    }
    >
    
  • db.collection.find().count(): 计数,统计查询的结果有多少条

    > db.stus.find( {} ).count()
    5
    >
    

修改

  • db.collection.update(): 更新文档

    参数:query:查询条件,类似where

    ​ update:更新操作符,类似set

    ​ upsert:不存在记录是否插入,true(插入),false(不插入,默认)

    ​ multi:只更新一条,true(更新全部),false(默认)

    ​ writeConcern:抛出异常级别

     # db.collection.update(#   <query>,#   <update>,#   {#     upsert: <boolean>,#     multi: <boolean>,#     writeConcern: <document>#   }# )
    

    update() 方法默认以新对象替换旧对象

    # 原有的文档被替换了
    > db.stus.update({ name: "孙悟空" }, {age: 15});
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.stus.find({});
    { "_id" : ObjectId("61b58a89e4b077ad0bb9c270"), "age" : 15 }
    ... ...
    >
    

    $set: 使用 update(修改操作符)修改指定属性而不替换

    > db.stus.update({name: "猪八戒"},{$set: {age: 16}}
    )
    Updated 1 existing record(s) in 1ms
    > db.stus.find({name: "猪八戒"})
    {"_id" : ObjectId("61b58cd8d00f32f85a47ddb1"), "name" : "猪八戒", "age" : 16.0, "gender" : "男"}
    

    $unset: 删除文档指定属性

    # age赋值无所谓,目的为移除属性
    > db.stus.update({name: "猪八戒"},{$unset: {age: "" }}
    )
    Updated 1 existing record(s) in 1ms# age属性没有了
    > db.stus.find()
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb1"), "name" : "猪八戒", "gender" : "男" }
    
  • multi: update默认操作一个文档,multi: true 操作所有符合条件的文档

    > db.stus.update({gender: "男"},{$set: {age: "17" }},{multi: true}
    )
    db.stus.find({name: "猪八戒"})# 查看所有,发现 gender=="男" 的文档都被修改了
    > db.stus.find()
    { "_id" : ObjectId("61b58a89e4b077ad0bb9c270"), "age" : 15 }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb1"), "name" : "猪八戒", "gender" : "男", "age" : "17" }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb2"), "name" : "白骨精", "age" : "17", "gender" : "男" }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb3"), "name" : "蜘蛛精", "age" : 16, "gender" : "女" }
    { "_id" : "hello123", "name" : "如来佛", "age" : "17", "gender" : "男" }
    >
    
  • $inc: 对数字属性增加值

    > db.stus.update({age: 15},{$inc: {age: 1 }}
    )
    Updated 1 existing record(s) in 1ms# age==15 的文档,age增长1
    > db.stus.find()
    { "_id" : ObjectId("61b58a89e4b077ad0bb9c270"), "age" : 16 }
    
  • $rename: 修改属性名称

    > db.stus.update({name: "如来佛"},{$rename: {age: "ageNum" }}
    )
    Updated 1 existing record(s) in 1ms# 属性名被修改了
    > db.stus.find({name: "如来佛"})
    { "_id" : "hello123", "name" : "如来佛", "gender" : "男", "ageNum" : "17" }
    >
    
  • $push: 给文档追加一个属性

    > db.stus.find({age: 16})
    { "_id" : ObjectId("61b58a89e4b077ad0bb9c270"), "age" : 16 }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb3"), "name" : "蜘蛛精", "age" : 16, "gender" : "女" }# 给文档追加一个属性,此属性只能是数组,如果不存在,则添加一个属性,
    > db.stus.update({age: 16},{$push: {name: "孙悟空" }}
    )
    Updated 1 existing record(s) in 1ms
    > db.stus.find({age: 16})
    { "_id" : ObjectId("61b58a89e4b077ad0bb9c270"), "age" : 16, "name" : [ "孙悟空" ] }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb3"), "name" : "蜘蛛精", "age" : 16, "gender" : "女" }
    
  • $addToSet: 加一个值到属性的数组内,而且只有当这个值在数组中不存在时才增加。

    > db.stus.update({name: "猪八戒"},{$addToSet: {food: "越多越好" }}
    )
    Updated 1 existing record(s) in 1ms
    > db.stus.findOne({name: "猪八戒"})
    {"_id" : ObjectId("61b58cd8d00f32f85a47ddb1"),"name" : "猪八戒","gender" : "男","age" : "17","food" : ["越多越好"       # 多次执行addToSet,只会有一个 "越多越好"]
    }# 追加一个其他值,可以追加成功
    > db.stus.update({name: "猪八戒"},{$addToSet: {food: "多多益善" }}
    )
    Updated 1 existing record(s) in 1ms
    > db.stus.findOne({name: "猪八戒"})
    {"_id" : ObjectId("61b58cd8d00f32f85a47ddb1"),"name" : "猪八戒","gender" : "男","age" : "17","food" : ["越多越好","多多益善"]
    }
    >
    
  • $pull: 指定属性的数组内删除一个指定的值

    # 多追加一个属性
    > db.stus.update({age: 16},{$push: {name: "孙行者" }}
    )
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.stus.find({age: 16})
    { "_id" : ObjectId("61b58a89e4b077ad0bb9c270"), "age" : 16, "name" : [ "孙悟空", "孙行者" ] }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb3"), "name" : "蜘蛛精", "age" : 16, "gender" : "女" }# 从属性的数组内移除一个值
    > db.stus.update({age: 16},{$pull: {name: "孙悟空" }}
    )
    Updated 1 existing record(s) in 2ms
    > db.stus.find({age: 16})
    { "_id" : ObjectId("61b58a89e4b077ad0bb9c270"), "age" : 16, "name" : [ "孙行者" ] }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb3"), "name" : "蜘蛛精", "age" : 16, "gender" : "女" }
    >
    
  • $pop: 删除属性数组内的一个值

    > db.stus.find({name: "猪八戒"})
    {"_id" : ObjectId("61b58cd8d00f32f85a47ddb1"),"name" : "猪八戒","gender" : "男","age" : "17","food" : [ "越多越好", "多多益善", "一顿千金", "吃穷唐僧"]
    }# 删除数组第一个:  {$pop:{tags:-1}}        -1 -> 删除tags[0]
    # 删除数组最后一个: {$pop:{tags:1}}
    > db.stus.update({name: "猪八戒"},{$pop: {food: 1 }}
    )
    > db.stus.find({name: "猪八戒"})
    Updated 1 existing record(s) in 1ms
    {"_id" : ObjectId("61b58cd8d00f32f85a47ddb1"),"name" : "猪八戒","gender" : "男","age" : "17","food" : [ "越多越好", "多多益善", "一顿千金"]
    }
    
  • 其他方法

    • db.collection.updateOne(): 修改一个
    • db.collection.updateMany(): 修改多个
    • db.collection.updatereplaceOne(): 替换

删除

  • db.collection.remove():

    传参和 find() 方法一样

    > db.stus.find({})
    { "_id" : ObjectId("61b58a89e4b077ad0bb9c270"), "age" : 16, "name" : [ "孙行者" ] }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb1"), "name" : "猪八戒", "gender" : "男", "age" : "17", "food" : [ "越多越好", "多多益善", "一顿千金" ] }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb2"), "name" : "白骨精", "age" : "17", "gender" : "男" }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb3"), "name" : "蜘蛛精", "age" : 16, "gender" : "女" }
    { "_id" : "hello123", "name" : "如来佛", "gender" : "男", "ageNum" : "17" }# 根据条件删除
    db.stus.remove({name: "猪八戒"}
    )
    Removed 1 record(s) in 1ms
    > db.stus.find({})
    { "_id" : ObjectId("61b58a89e4b077ad0bb9c270"), "age" : 16, "name" : [ "孙行者" ] }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb2"), "name" : "白骨精", "age" : "17", "gender" : "男" }
    { "_id" : ObjectId("61b58cd8d00f32f85a47ddb3"), "name" : "蜘蛛精", "age" : 16, "gender" : "女" }
    { "_id" : "hello123", "name" : "如来佛", "gender" : "男", "ageNum" : "17" }
    >
    
  • 删除所有

    # 删除所有
    > db.stus.remove({})
    Removed 4 record(s) in 1ms
    
  • 其他方法

    • db.collection.deleteOne():
    • db.collection.deleteMany():

实战练习

  • 进入 my_test 数据库

    > use my_test
    switched to db my_test
    >
    
  • 向数据库 user 集合中插入文档

    > db.users.insert({username:"孙悟空"})
    WriteResult({ "nInserted" : 1 })
    >
    
  • 查询 user 集合中的文档

    > db.users.find()
    { "_id" : ObjectId("61bac4d71d938538c23fce5f"), "username" : "孙悟空" }
    >
    
  • 统计 user 集合中的文档数量

    > db.users.find().count()
    1
    >
    
  • 查询 user 集合中 username 为 “孙悟空” 的文档

    > db.users.find({username:"孙悟空"})
    { "_id" : ObjectId("61bac4d71d938538c23fce5f"), "username" : "孙悟空" }
    >
    
  • 向 user 集合中 username 为 “孙悟空” 的文档添加一个 address属性,值为 “花果山”

    > db.users.update({username:"孙悟空"}, {$set:{address:"花果山"}})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    
  • 用 {username: “唐僧”} 替换 username 为 “猪八戒” 的文档

    > db.users.insert({username:"猪八戒"})
    WriteResult({ "nInserted" : 1 })
    > db.users.find()
    { "_id" : ObjectId("61bac4d71d938538c23fce5f"), "username" : "孙悟空", "address" : "花果山" }
    { "_id" : ObjectId("61bac83f1d938538c23fce60"), "username" : "猪八戒" }
    > db.users.replaceOne({username:"猪八戒"}, {username: "唐僧"})
    { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
    > db.users.find()
    { "_id" : ObjectId("61bac4d71d938538c23fce5f"), "username" : "孙悟空", "address" : "花果山" }
    { "_id" : ObjectId("61bac83f1d938538c23fce60"), "username" : "唐僧" }
    >
    
  • 删除 username 为 “孙悟空” 的文档的 address 属性

    > db.users.update({username: "孙悟空"}, {$unset:{address: 1}})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.users.find({username:"孙悟空"})
    { "_id" : ObjectId("61bac4d71d938538c23fce5f"), "username" : "孙悟空" }
    >
    
  • 给 username 为 “孙悟空” 的文档添加一个 hobby 属性

    当一个文档的属性值是一个文档时,称这个内部的文档叫内嵌文档

    > db.users.update({username: "孙悟空"}, {$set: {hobby: {cities: ["北京","上海","深圳"], movies: ["复仇者联盟","加勒比海盗"]}}}
    )
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.users.find({username:"孙悟空"})
    {"_id" : ObjectId("61bac4d71d938538c23fce5f"),"username" : "孙悟空","hobby" : {"cities" : [ "北京", "上海", "深圳"],"movies" : [ "复仇者联盟", "加勒比海盗"]}
    }
    

    给 username 为 “唐僧” 的文档,添加一个属性

    > db.users.update({username: "唐僧"}, {$set: {hobby: {movies: ["红楼梦","女儿国"]}}}
    )
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
    
  • 查询喜欢电影 “复仇者联盟” 的文档

    # mongoDB支持通过内嵌文档的属性查询,通过 . 的形式
    # 根据内嵌文档属性查询,属性名必须使用引号
    # movies是数组,里面有一个元素可以匹配,就可以查询成功
    > db.users.find({"hobby.movies":"复仇者联盟"})
    { "_id" : ObjectId("61bac4d71d938538c23fce5f"), "username" : "孙悟空", "hobby" : { "cities" : [ "北京", "上海", "深圳" ], "movies" : [ "复仇者联盟", "加勒比海盗" ] } }
    >
    
  • 向 “唐僧” 文档中添加一个新的电影 “大闹天竺”

    # $push         用于向数组添加一个新的元素,不考虑重复
    # $addToSet     用于向数组添加一个新的元素,只能添加不存在的元素
    > db.users.update({username:"唐僧"}, {$push:{"hobby.movies":"大闹天竺"}})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    
  • 删除喜欢 “北京” 的文档

    > db.users.remove({"hobby.cities": "北京"})
    WriteResult({ "nRemoved" : 1 })
    >
    
  • 删除 users 集合

    # 方法一:更像清空集合
    > db.users.remove({})
    WriteResult({ "nRemoved" : 1 })
    >
    # 方法二:
    > db.users.drop()
    true
    >
    
  • 向 numbers 集合中插入 20000 条数据

    结果显示的是最后一条的时间

    for(var i = 1; i <= 20000; i++) {db.numbers.insert({num: i})
    }
    Inserted 1 record(s) in 7.2s
    

    可以提高插入速度,先插入数组,在把数组插入集合(IO速度:内存 > 硬盘)

    var arr = [];
    for(var i = 1; i <= 20000; i++) {arr.push({num: i})
    }
    db.numbers.insert(arr)
    Inserted 1 record(s) in 206ms
    
  • 查询 numbers 集合中 num 大于 5000 的文档

    # $gt  大于
    # $gte  大于等于
    # $lt   小于
    # $lte  小于等于
    # $eq   等于
    # $ne   不等于
    > db.numbers.find({num: {$gt: 5000}})
    { "_id" : ObjectId("61bb35ff15a563aa27c0b681"), "num" : 5001 }
    { "_id" : ObjectId("61bb35ff15a563aa27c0b682"), "num" : 5002 }
    { "_id" : ObjectId("61bb35ff15a563aa27c0b683"), "num" : 5003 }
    { "_id" : ObjectId("61bb35ff15a563aa27c0b684"), "num" : 5004 }
    ... ...
    
  • 查询 numbers 集合中 num 大于 40,小于 50 的文档

    > db.numbers.find({num: {$gt: 40, $lt: 50}})
    { "_id" : ObjectId("61bb35ff15a563aa27c0a321"), "num" : 41 }
    ... ...
    { "_id" : ObjectId("61bb35ff15a563aa27c0a329"), "num" : 49 }
    >
    
  • 查询 numbers 集合中的前 10 条数据

    > db.numbers.find().limit(10)
    { "_id" : ObjectId("61bb35ff15a563aa27c0a2f9"), "num" : 1 }
    { "_id" : ObjectId("61bb35ff15a563aa27c0a2fa"), "num" : 2 }
    ... ...
    
  • 查看 numbers 集合中第 11 到第 20 条数据(第二页)

    # db.numbers.find().skip((页码-1)*每页条数).limit(每页条数)
    > db.numbers.find().skip(10).limit(10)
    { "_id" : ObjectId("61bb35ff15a563aa27c0a303"), "num" : 11 }
    { "_id" : ObjectId("61bb35ff15a563aa27c0a304"), "num" : 12 }
    { "_id" : ObjectId("61bb35ff15a563aa27c0a305"), "num" : 13 }
    { "_id" : ObjectId("61bb35ff15a563aa27c0a306"), "num" : 14 }
    { "_id" : ObjectId("61bb35ff15a563aa27c0a307"), "num" : 15 }
    { "_id" : ObjectId("61bb35ff15a563aa27c0a308"), "num" : 16 }
    { "_id" : ObjectId("61bb35ff15a563aa27c0a309"), "num" : 17 }
    { "_id" : ObjectId("61bb35ff15a563aa27c0a30a"), "num" : 18 }
    { "_id" : ObjectId("61bb35ff15a563aa27c0a30b"), "num" : 19 }
    { "_id" : ObjectId("61bb35ff15a563aa27c0a30c"), "num" : 20 }
    >
    
  • 将 json 格式的数据文件导入到 mongodb 数据库
    dept.json:https://download.csdn.net/download/weixin_41420295/66181526
    emp.json:https://download.csdn.net/download/weixin_41420295/66181734

    # --host[h]                主机
    # --port                端口
    # -db[d]                目标数据库
    # -username[u]          用户名
    # -password[p]          密码
    # -collection[c]        目标Collection,不指定则采用文件名称
    # --numInsertionWorkers 并发数
    # --file                目标导入文件
    # -legacy               识别json v1.0,MongoDB4.2以后,识别{"_id":{"$oid":"5be19b932ab79c00013074ed"}}# 导入部门
    **\bin> mongoimport --host 127.0.0.1 --port 27017 -d my_test -c dept --file "e:\dept.json" --legacy
    2021-12-17T11:00:41.780+0800    connected to: mongodb://127.0.0.1:27017/
    2021-12-17T11:00:42.064+0800    4 document(s) imported successfully. 0 document(s) failed to import.
    > db.dept.find()
    { "_id" : ObjectId("5941f2bac1bc86928f4de49a"), "deptno" : 10, "dname" : "财务部", "loc" : "北京" }
    { "_id" : ObjectId("5941f2bac1bc86928f4de49b"), "deptno" : 20, "dname" : "办公室", "loc" : "上海" }
    { "_id" : ObjectId("5941f2bac1bc86928f4de49c"), "deptno" : 30, "dname" : "销售部", "loc" : "广州" }
    { "_id" : ObjectId("5941f2bac1bc86928f4de49d"), "deptno" : 40, "dname" : "运营部", "loc" : "深圳" }
    ># 导入人员
    **\bin> mongoimport --host 127.0.0.1 --port 27017 -d my_test -c emp --file "e:\emp.json" --legacy
    2021-12-17T11:07:09.970+0800    connected to: mongodb://127.0.0.1:27017/
    2021-12-17T11:07:10.248+0800    14 document(s) imported successfully. 0 document(s) failed to import.
    > db.emp.find()
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4ac"), "empno" : 7369, "ename" : "林冲", "job" : "职员", "mgr" : "7902", "hiredate" : ISODate("1980-12-16T16:00:00Z"), "sal" : 800, "deptno" : 20 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4af"), "empno" : 7566, "ename" : "卢俊义", "job" : "经理", "mgr" : "7839", "hiredate" : ISODate("1981-04-01T16:00:00Z"), "sal" : 2975, "deptno" : 20 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4ad"), "empno" : 7499, "ename" : "孙二娘", "job" : "销售", "mgr" : "7698", "hiredate" : ISODate("1981-02-19T16:00:00Z"), "sal" : 1600, "deptno" : 30, "comm" : 300 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4ae"), "empno" : 7521, "ename" : "扈三娘", "job" : "销售", "mgr" : "7698", "hiredate" : ISODate("1981-02-21T16:00:00Z"), "sal" : 1250, "deptno" : 30, "comm" : 500 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b1"), "empno" : 7698, "ename" : "西门庆", "job" : "经理", "mgr" : "7839", "hiredate" : ISODate("1981-04-30T16:00:00Z"), "sal" : 2850, "deptno" : 30 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b2"), "empno" : 7782, "ename" : "柴进", "job" : "经理", "mgr" : "7839", "hiredate" : ISODate("1981-06-08T16:00:00Z"), "sal" : 2450, "deptno" : 10 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b3"), "empno" : 7788, "ename" : "公孙胜", "job" : "分析师", "mgr" : "7566", "hiredate" : ISODate("1987-07-12T16:00:00Z"), "sal" : 3000, "deptno" : 20 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b0"), "empno" : 7654, "ename" : "潘金莲", "job" : "销售", "mgr" : "7698", "hiredate" : ISODate("1981-09-27T16:00:00Z"), "sal" : 1250, "deptno" : 30, "comm" : 1400 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b4"), "empno" : 7839, "ename" : "宋江", "job" : "董事长", "hiredate" : ISODate("1981-11-16T16:00:00Z"), "sal" : 5000, "deptno" : 10 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b5"), "empno" : 7844, "ename" : "阎婆惜", "job" : "销售", "mgr" : "7698", "hiredate" : ISODate("1981-09-07T16:00:00Z"), "sal" : 1500, "deptno" : 30, "comm" : 0 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b6"), "empno" : 7876, "ename" : "李逵", "job" : "职员", "mgr" : "7902", "hiredate" : ISODate("1987-07-12T16:00:00Z"), "sal" : 1100, "deptno" : 20 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b9"), "empno" : 7934, "ename" : "鲁智深", "job" : "职员", "mgr" : "7782", "hiredate" : ISODate("1982-01-22T16:00:00Z"), "sal" : 1300, "deptno" : 10 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b7"), "empno" : 7900, "ename" : "武松", "job" : "职员", "mgr" : "7782", "hiredate" : ISODate("1981-12-02T16:00:00Z"), "sal" : 950, "deptno" : 10 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b8"), "empno" : 7902, "ename" : "吴用", "job" : "分析师", "mgr" : "7566", "hiredate" : ISODate("1981-12-02T16:00:00Z"), "sal" : 3000, "deptno" : 20 }
    >
  • 查询工资 “sal” 在 1000~2000 直接的员工

    > db.emp.find({sal: {$gt: 1000, $lt: 2000}})
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4ad"), "empno" : 7499, "ename" : "孙二娘", "job" : "销售", "mgr" : "7698", "hiredate" : ISODate("1981-02-19T16:00:00Z"), "sal" : 1600, "deptno" : 30, "comm" : 300 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4ae"), "empno" : 7521, "ename" : "扈三娘", "job" : "销售", "mgr" : "7698", "hiredate" : ISODate("1981-02-21T16:00:00Z"), "sal" : 1250, "deptno" : 30, "comm" : 500 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b0"), "empno" : 7654, "ename" : "潘金莲", "job" : "销售", "mgr" : "7698", "hiredate" : ISODate("1981-09-27T16:00:00Z"), "sal" : 1250, "deptno" : 30, "comm" : 1400 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b5"), "empno" : 7844, "ename" : "阎婆惜", "job" : "销售", "mgr" : "7698", "hiredate" : ISODate("1981-09-07T16:00:00Z"), "sal" : 1500, "deptno" : 30, "comm" : 0 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b6"), "empno" : 7876, "ename" : "李逵", "job" : "职员", "mgr" : "7902", "hiredate" : ISODate("1987-07-12T16:00:00Z"), "sal" : 1100, "deptno" : 20 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b9"), "empno" : 7934, "ename" : "鲁智深", "job" : "职员", "mgr" : "7782", "hiredate" : ISODate("1982-01-22T16:00:00Z"), "sal" : 1300, "deptno" : 10 }
    >
    
  • 查询工资 “sal” 小于 1000 或者大于 2500 的员工

    > db.emp.find({$or: [{sal: {$lt: 1000}}, {sal: {$gt: 2500}}]});
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4ac"), "empno" : 7369, "ename" : "林冲", "job" : "职员", "mgr" : "7902", "hiredate" : ISODate("1980-12-16T16:00:00Z"), "sal" : 800, "deptno" : 20 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4af"), "empno" : 7566, "ename" : "卢俊义", "job" : "经理", "mgr" : "7839", "hiredate" : ISODate("1981-04-01T16:00:00Z"), "sal" : 2975, "deptno" : 20 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b1"), "empno" : 7698, "ename" : "西门庆", "job" : "经理", "mgr" : "7839", "hiredate" : ISODate("1981-04-30T16:00:00Z"), "sal" : 2850, "deptno" : 30 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b3"), "empno" : 7788, "ename" : "公孙胜", "job" : "分析师", "mgr" : "7566", "hiredate" : ISODate("1987-07-12T16:00:00Z"), "sal" : 3000, "deptno" : 20 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b4"), "empno" : 7839, "ename" : "宋江", "job" : "董事长", "hiredate" : ISODate("1981-11-16T16:00:00Z"), "sal" : 5000, "deptno" : 10 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b7"), "empno" : 7900, "ename" : "武松", "job" : "职员", "mgr" : "7782", "hiredate" : ISODate("1981-12-02T16:00:00Z"), "sal" : 950, "deptno" : 10 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b8"), "empno" : 7902, "ename" : "吴用", "job" : "分析师", "mgr" : "7566", "hiredate" : ISODate("1981-12-02T16:00:00Z"), "sal" : 3000, "deptno" : 20 }
    >
    
  • 查询财务部所有员工

    > var deptno = db.dept.findOne({dname: "财务部"}).deptno;
    > db.emp.find({deptno: deptno});
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b2"), "empno" : 7782, "ename" : "柴进", "job" : "经理", "mgr" : "7839", "hiredate" : ISODate("1981-06-08T16:00:00Z"), "sal" : 2450, "deptno" : 10 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b4"), "empno" : 7839, "ename" : "宋江", "job" : "董事长", "hiredate" : ISODate("1981-11-16T16:00:00Z"), "sal" : 5000, "deptno" : 10 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b9"), "empno" : 7934, "ename" : "鲁智深", "job" : "职员", "mgr" : "7782", "hiredate" : ISODate("1982-01-22T16:00:00Z"), "sal" : 1300, "deptno" : 10 }
    { "_id" : ObjectId("5941f5bfc1bc86928f4de4b7"), "empno" : 7900, "ename" : "武松", "job" : "职员", "mgr" : "7782", "hiredate" : ISODate("1981-12-02T16:00:00Z"), "sal" : 950, "deptno" : 10 }
    >
    
  • 所有工资低于 1000 的员工,涨工资 400

    > db.emp.updateMany({sal: {$lt:1000}}, {$inc: {sal: 400}})
    { "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }
    >
    

文档之间的关系

一对一(one to one)

可以通过内嵌文档的形式体现

db.wifeAndHusband.insert({name: "黄蓉",husband: {name: "郭靖"}},{name: "潘金莲",husband: {name: "武大郎"}}
)
Inserted 1 record(s) in 264ms

一对多(one to many)/多对一(many to one)

用户(user)和订单(order)

# 用户
> db.users.insert([{name: "张三"}, {name: "李四"}
])
Inserted 1 record(s) in 156ms
> db.users.find()
{ "_id" : ObjectId("61bb541615a563aa27c0f11c"), "name" : "张三" }
{ "_id" : ObjectId("61bb541615a563aa27c0f11d"), "name" : "李四" }
# 订单
db.order.insert({list: ["香蕉","苹果","鸭梨"],user_id: ObjectId("61bb541615a563aa27c0f11c")
})
db.order.insert({list: ["西瓜","香蕉"],user_id: ObjectId("61bb541615a563aa27c0f11c")
})
db.order.insert({list: ["牛肉","锅巴"],user_id: ObjectId("61bb541615a563aa27c0f11d")
})
> db.order.find()
{ "_id" : ObjectId("61bb54b215a563aa27c0f11e"), "list" : [ "香蕉", "苹果", "鸭梨" ], "user_id" : ObjectId("61bb541615a563aa27c0f11c") }
{ "_id" : ObjectId("61bb551315a563aa27c0f11f"), "list" : [ "西瓜", "香蕉" ], "user_id" : ObjectId("61bb541615a563aa27c0f11c") }
{ "_id" : ObjectId("61bb554f15a563aa27c0f120"), "list" : [ "牛肉", "锅巴" ], "user_id" : ObjectId("61bb541615a563aa27c0f11d") }
>

查找用户 “张三” 的订单

> var user_id = db.users.findOne({name: "张三"})._id;
> db.order.find({user_id: user_id})
{ "_id" : ObjectId("61bb54b215a563aa27c0f11e"), "list" : [ "香蕉", "苹果", "鸭梨" ], "user_id" : ObjectId("61bb541615a563aa27c0f11c") }
{ "_id" : ObjectId("61bb551315a563aa27c0f11f"), "list" : [ "西瓜", "香蕉" ], "user_id" : ObjectId("61bb541615a563aa27c0f11c") }
>

多对多(many to many)

老师(teacher)和学生(student)

# 老师
db.teacher.insert([{name: "洪七公"}, {name: "黄药师"},{name: "龟仙人"}
])
> db.teacher.find()
{ "_id" : ObjectId("61bb584e15a563aa27c0f121"), "name" : "洪七公" }
{ "_id" : ObjectId("61bb584e15a563aa27c0f122"), "name" : "黄药师" }
{ "_id" : ObjectId("61bb584e15a563aa27c0f123"), "name" : "龟仙人" }
>
# 学生
db.student.insert([{name: "郭靖",tech_ids: [ObjectId("61bb584e15a563aa27c0f121"),ObjectId("61bb584e15a563aa27c0f122")]},{name: "孙悟空",tech_ids: [ObjectId("61bb584e15a563aa27c0f121"),ObjectId("61bb584e15a563aa27c0f122"),ObjectId("61bb584e15a563aa27c0f123")]}
])
> db.student.find()
{ "_id" : ObjectId("61bb58fe15a563aa27c0f124"), "name" : "郭靖", "tech_ids" : [ ObjectId("61bb584e15a563aa27c0f121"), ObjectId("61bb584e15a563aa27c0f122") ] }
{ "_id" : ObjectId("61bb58fe15a563aa27c0f125"), "name" : "孙悟空", "tech_ids" : [ ObjectId("61bb584e15a563aa27c0f121"), ObjectId("61bb584e15a563aa27c0f122"), ObjectId("61bb5
84e15a563aa27c0f123") ] }
>

排序和投影

  • 查询文档时,默认是以 _id 升序排列,可以使用 sort() 指定排序规则

    # 1标识升序,-1标识降序
    > db.emp.find({}).sort({sal:1, empno:-1})
    
  • 查询时,可以用第二个参数,设置查询结果的投影

    # _id是默认显示的
    > db.emp.find({},{_id:0, ename:1, sal:1})
    { "ename" : "卢俊义", "sal" : 2975 }
    { "ename" : "孙二娘", "sal" : 1600 }
    ... ...
    >
    

Mongoose

简介

Mongoose 是一个可以通过 Node 来操作 MongoDB 的模块。Mongoose 是一个对象文档模型(ODM)库,它对 Node 原生的 MongoDB 模块进一步的优化封装,并提供了更多的功能。

mongoose 的好处:

  • 可以为文档创建一个模式结构(Schema),或者说一个约束。
  • 可以对模型中的对象/文档进行验证
  • 数据可以通过类型转换为对象模型
  • 可以使用中间件来应用业务逻辑挂钩
  • 比 Node 原生的 MongoDB 驱动更容易

mongoose 中提供了几个新的对象

  • Schema(模式对象):定义了数据库中的文档结构
  • Model:作为集合中所有文档的表示,相当于 MongoDB 数据库中的集合 collection
  • Document:表示集合中具体的文档,相当于集合中的一个具体文档

测试:

  1. 环境准备

    新建目录,在目录下新建 package.json

    {"name": "helloMongoose","version": "0.0.1",
    }
    
  2. 下载安装 mongoose,在新建的目录下执行命令:

    npm i mongoose --save
    
  3. 新建 helloMongoose.js 文件

    /*** 1. 下载安装 mongoose*       npm i mongoose --save* * 2. 引入 mongoose* * 3. 连接 MongoDB 数据库,新版本MongoDB需要加参数{useMongoClient: true}*       mongoose.connect('mongodb://ip:port/dbName', {useMongoClient: true})*       如果是默认端口(27017)可以省略* * 4. 断开数据库连接(一般不需要调用)*       MongoDB 数据库,在一般情况下,只需要连接一次,除非项目停止服务器关闭,否则一般不会断开*       mongoose.disconnect()* * 5. 监听 MongoDB 数据库的连接状态*       在 mongoose 对象中,有一个 connection 属性,该属性表示的就是数据库连接*       通过监视该对象的状态,可以监听数据库的连接、断开* *       数据库连接成功的事件*       mongoose。connection。once("open", function(){})* *       数据库断开的事件*       mongoose。connection。once("close", function(){})*/// 引入var mongoose = require("mongoose");// 连接mongoose.connect('mongodb://127.0.0.1/mongoose_test');// 监听连接mongoose.connection.once('open', function(){console.log("数据库连接成功~~~");});// 监听断开mongoose.connection.once('close', function(){console.log("数据库连接已经断开~~~");})// 断开mongoose.disconnect();
    
  4. 运行

    **> node .\helloMongoose.js
    数据库连接成功~~~
    数据库连接已经断开~~~
    

Schema 和 Model

  • 文件 helloSchema.js

     var mongoose = require("mongoose");mongoose.connect('mongodb://127.0.0.1/mongoose_test');mongoose.connection.once("open", function(){console.log("数据库连接成功~~~");});/*** Schema*/// 将 mongoose.Schema 赋值给一个变量var Schema = mongoose.Schema;// 创建 Schema (模式/约束)对象var stuSchema = new Schema({name: String,age: Number,gender: {type: String,default: "female"},address: String});// 通过 Schema 创建 Model// Model 代表数据库中的集合,通过 Model 才能对数据库进行操作// 语法:mongoose.model(modelName, schema);// 其中 modelName 是映射的集合名,MongoDB 会自动将单数改为复数var StuModel = mongoose.model("student", stuSchema);// 向数据库插入一个文档StuModel.create({name: "孙悟空",age: 18,gender: "male",address: "花果山"}, function(err){if(!err){console.log("插入成功~~~");}});
    
  • 运行

    **\helloMongoose> node .\helloSchema.js
    数据库连接成功~~~
    插入成功~~~

Model 的方法

操作 Model,对数据库进行增删改查

新增

  • Model.crate(doc(s), [callback])

    用来创建一个或多个文档添加到数据库中

    参数:

    • doc(s) 可以是一个文档对象,也可以是一个文档对象的数组
    • callback 回调函数
    StuModel.create([{name: "猪八戒",age: 28,gender: "male",address: "高老庄"},{name: "唐僧",age: 17,gender: "male",address: "东土大唐"}
    ], function(err){if(!err){console.log("插入成功~~~");}
    });
    
  • 探究一下,回调函数的返回值

    StuModel.create([{name: "沙和尚",age: 38,gender: "male",address: "流沙河"}
    ], function(err){if(!err){console.log(arguments);}
    });
    /*
    **\helloMongoose> node .\helloModel.js
    数据库连接成功~~~
    [Arguments] {'0': null,   # err'1': [       # 插入的文档{name: '沙和尚',age: 38,gender: 'male',address: '流沙河',_id: new ObjectId("61bd3f924545d40f7c4ac800"),__v: 0}]
    }
    */
    

查询

  • Model.find(conditions, [projection], [options], [callback]) :查询所有符合条件的文档

  • Model.findById(id, [projection], [options], [callback]) :根据文档的ID查询文档

  • Model.findOne([conditions], [projection], [options], [callback]) :查询符合条件的第一个文档

  • conditions:查询条件

  • projection:投影

  • options:查询选项(skip、limit)

  • callback:回调函数,查询结果通过回调函数返回

  • 条件查询

  • // 查询所有符合条件的文档
    StuModel.find({name: "唐僧"}, function(err, docs){if(!err) {console.log(docs);}
    });
    /*
    返回结果是数组
    [{_id: new ObjectId("61bd3e1885eebfa86f8a2e04"),name: '唐僧',age: 17,gender: 'male',address: '东土大唐',__v: 0}
    ]
    */// 查询符合条件的第一个文档
    StuModel.findOne({}, function(err, doc){if(!err) {console.log(doc);}
    });
    /*
    返回结果是对象
    {_id: new ObjectId("61bc9aef975b266f07bb657e"),name: '孙悟空',age: 18,gender: 'male',address: '花果山',__v: 0
    }
    */// 根据文档的ID查询文档
    StuModel.findById("61bd3e1885eebfa86f8a2e04", function(err, doc){if(!err) {console.log(doc);}
    });
    /*
    返回结果是对象
    {_id: new ObjectId("61bd3e1885eebfa86f8a2e04"),name: '唐僧',age: 17,gender: 'male',address: '东土大唐',__v: 0
    }
    */
    
  • 投影

    // 方式一:{_id:0, name:1}
    // 方式二:"-_id name"
    StuModel.find({}, {_id:0,name:1}, function(err, docs){if(!err) {console.log(docs);}
    });
    /*
    [{ name: '孙悟空' },{ name: '白骨精' },{ name: '猪八戒' },{ name: '唐僧' },{ name: '沙和尚' }
    ]
    */StuModel.find({}, "-_id name age", function(err, docs){if(!err) {console.log(docs);}
    });
    /*
    [{ name: '孙悟空', age: 18 },{ name: '白骨精', age: 18 },{ name: '猪八戒', age: 28 },{ name: '唐僧', age: 17 },{ name: '沙和尚', age: 38 }
    ]
    */
    
  • 查询选项

    StuModel.find({}, "-_id name age", {skip:3, limit:1},function(err, docs){if(!err) {console.log(docs);}
    });
    /*
    [ { name: '唐僧', age: 17 } ]
    */
    
  • Document 对象是 Model 的实例

    StuModel.findOne({}, function(err, doc){if(!err) {console.log(doc instanceof StuModel);}
    });
    /*
    true
    */
    

修改

  • Model.update(conditions, doc, [options], [callback])

  • Model.updateMany(conditions, doc, [options], [callback])

  • Model.updateOne(conditions, doc, [options], [callback])

    • conditions:查询条件
    • doc:修改后的文档
    • options:配置参数
    • callback:回调函数
  • 修改

    StuModel.updateOne({name: "唐僧"}, {$set: {age: 20}}, function(err){if(!err){console.log("修改成功~~~");}
    });
    

删除

  • Model.remove(conditions, [callback])

  • Model.deleteOne(conditions, [callback])

  • Model.deleteMany(conditions, [callback])

  • 删除

    StuModel.remove({name: "白骨精"}, function(err){if(!err){console.log("删除成功~~~");}
    });
    
    # 根据返回值,remove已经被废除,建议使用 deleteOne, deleteMany
    **\helloMongoose> node .\helloModel.js
    数据库连接成功~~~
    (node:73468) [MONGODB DRIVER] Warning: collection.remove is deprecated. Use deleteOne, deleteMany, or bulkWrite instead.
    删除成功~~~

计数

  • Model.count(conditions, [callback])

  • 计数

    StuModel.count({}, function(err, count){if(!err){console.log(count);}
    });
    

Document 的方法

新增

  • 创建一个 Document

    var StuModel = mongoose.model("student", stuSchema);// 创建一个 Document
    var stu = new StuModel({name: "奔波霸",age: 40,gender: "male",address: "碧波潭"
    });
    
  • 保存

    stu.save(function(err){if(!err){console.log("保存成功~~~");}
    });
    

修改

  • 直接修改已经存在的数据

    StuModel.findOne({}, function(err, doc){if(!err){doc.update({$set: {age:26}}, function(err){if(!err) {console.log("修改成功~~~");}})}
    });
    /*
    # 可以看到,update方法已经过时,建议使用updateOne, updateMany。
    PS E:\workplace_private\mongoDBTest\helloMongoose> node .\helloDocument.js
    数据库连接成功~~~
    (node:66616) [MONGODB DRIVER] Warning: collection.update is deprecated. Use updateOne, updateMany, or bulkWrite instead.
    修改成功~~~
    */
    
  • 也可以使用以下方法修改

    StuModel.findOne({}, function(err, doc){if(!err){doc.age = 20;doc.save();}
    });
    

删除

  • 删除查询到的数据

    StuModel.findOne({}, function(err, doc){if(!err){doc.remove(function(err){if(!err){console.log("删除成功~~~");}})}
    });
    

其他方法/属性

  • get(name):获取文档中指定属性值
  • set(name, value):设置文档指定属性值
  • id:文档的 _id 属性值
  • toJSON()
  • toObject()

mongoose 模块化

  1. 新建 tools 目录,并在 tools 目录下新建 conn_mongo.js 文件

    /*** 定义一个模块,连接 MongoDB 数据库*/
    var mongoose = require("mongoose");
    mongoose.connect('mongodb://127.0.0.1/mongoose_test');
    mongoose.connection.once("open", function(){console.log("数据库连接成功~~~");
    });
    
  2. 新建 models 目录,并在 models 下新建 student.js 文件

    /*** 定义 student 模型*/
    var mongoose = require("mongoose");var Schema = mongoose.Schema;var stuSchema = new Schema({name: String,age: Number,gender: {type: String,default: "female"},address: String
    });// 定义模型
    var StuModel = mongoose.model("student", stuSchema);module.exports = StuModel;
    
  3. 在根目录下新建 index.js

    require("./tools/conn_mongo");
    var Student = require("./models/student");Student.find({}, function(err, docs){if(!err){console.log(docs);}
    });
    
  4. 运行

    **\helloMongoose> node .\index.js
    数据库连接成功~~~
    [{_id: new ObjectId("61bc9aef975b266f07bb657e"),name: '孙悟空',age: 20,gender: 'male',address: '花果山',__v: 0},{_id: new ObjectId("61bd3e1885eebfa86f8a2e03"),name: '猪八戒',age: 28,gender: 'male',address: '高老庄',__v: 0},{_id: new ObjectId("61bd3e1885eebfa86f8a2e04"),name: '唐僧',age: 20,gender: 'male',address: '东土大唐',__v: 0},{_id: new ObjectId("61bd3f924545d40f7c4ac800"),name: '沙和尚',age: 38,gender: 'male',address: '流沙河',__v: 0},{_id: new ObjectId("61bd7a9702aa404c44bf1877"),name: '奔波霸',age: 40,gender: 'male',address: '碧波潭',__v: 0}
    ]

MongoDB基础教程笔记相关推荐

  1. MongoDB基础教程系列--目录结构

     MongoDB基础教程系列--目录结构

  2. python基础教程笔记—即时标记(详解)

    最近一直在学习python,语法部分差不多看完了,想写一写python基础教程后面的第一个项目.因为我在网上看到的别人的博客讲解都并不是特别详细,仅仅是贴一下代码,书上内容照搬一下,对于当时刚学习py ...

  3. 阮一峰:jQuery官方基础教程笔记

    原文地址:http://www.jobbole.com/entry.php/1151 jQuery是目前使用最广泛的javascript函数库. 据统计,全世界排名前100万的网站,有46%使用jQu ...

  4. pytho基础教程笔记(7-9)(类、递归、生成器)

    第七章 更加抽象 类和类型 类 概念: __metaclass__=type # 确保类是新版的 class Person:def setName(self, name):self.name = na ...

  5. Cytoscape基础教程笔记

    昨天开始学用Cytoscape,其tutorial分为两个部分,基础的和高级 的.基础教程又分成了四课:Getting Started.Filters & Editor.Fetching Ex ...

  6. 绘制对象iPhone开发基础教程 笔记

    每日一贴,今天的内容关键字为绘制对象 1. 虚拟内存 iPhone OS其实不会将易掉性内存(如应用程序数据)写到交换文件,因此应用程序可用内存量将受到更多的制约. Cocoa Touch供给一种内置 ...

  7. MongoDB 基础教程CURD帮助类

    最近两天在学习MongoDB,强大的文档数据库.给我最大的感觉就是相比于SQL或者MSQ等传统的关系型数据库,在使用和配置上真的是简化了很多.无论是在集群的配置还是故障转移方面,都省去了许多繁琐的步骤 ...

  8. php修改mongo,php操作MongoDB基础教程(连接、新增、修改、删除、查询)

    代码如下: //连接localhost:27017 $conn = new Mongo(); //连接远程主机默认端口 $conn = new Mongo('test.com'); //连接远程主机2 ...

  9. MongoDB基础教程

    一.如何使用MongoDB 官网下载MongoDB后,验证是否链接: 在bin下打开cmd,输入以下 然后命令行会显示一些日志信息: 浏览器输入localhost:27017,若如下显示,则你的Mon ...

最新文章

  1. mysql min函数 结果全为null_MySQL ----- 聚集函数(AVG,SUM,COUNT,MIN,MAX) (十一)
  2. Python2 Python3 爬取赶集网租房信息,带源码分析
  3. iqn怎么查 linux_程序员必备:46个Linux面试常见问题!收藏!
  4. 数据结构--图的广度优先搜索
  5. 程序员学会精刷LeetCode后,会变得有多强...
  6. expandablelistview 折叠动画_这个机械手到底有几个自由度,31个机械原理、设计动画来了。。。...
  7. 在ASP.NET中使用ObjectDataSource数据控件和GridView显示数据(2)
  8. 2018年,云计算的6大未来趋势
  9. java教师考勤系统,javaweb课堂考勤管理系统
  10. coreldrawx4缩略图显示不出来_CorelDRAW缩略图不显示解决办法
  11. 排序算法-冒泡排序详细讲解(BubbleSort)
  12. 0x0000004e蓝屏代码解决教程
  13. halcon学习拓展系列—修改图片分辨率算子modify_image_size(尺度不缩放)
  14. Mysql孤儿文件_PostgreSQL中的孤儿文件(orphaned data files)
  15. 修改win7电脑主题脚本
  16. oracle事件的特点,ORACLE 深入解析10053事件(1)
  17. “偷梁换柱”的库打桩机制
  18. 【原创】MATLAB模糊控制算法Fuzzy Control
  19. 阿里巴巴的机器视觉有多强!ET城市大脑发布四大AI视觉产品
  20. excel高效之拆分单元格数据、导入ppt实现修改同步

热门文章

  1. java生成P12秘钥
  2. CentOS:安装Docker
  3. 9月高价域名TOP35:Gay.XXX位居榜首
  4. Android WebView控件
  5. Google啊,你伤不起啊伤不起
  6. 使用预先训练好的单词向量识别影评的正负能量
  7. 手机android id修改密码,手机锁屏密码忘了?一个方法搞定
  8. Cassandra使用总结
  9. Python项目之学生管理系统
  10. Catch That Cow(农夫和牛)(BFS入门)(详解)