基于 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\db
journal:
enabled: true
# 日志数据
systemLog:
destination: file
logAppend: true
path: D:\development\MongoDB\log\mongod.log
# 网络接口
net:
port: 27017
bindIp: 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 数据库
# --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:表示集合中具体的文档,相当于集合中的一个具体文档
测试:
- 环境准备
新建目录,在目录下新建package.json
{
"name": "helloMongoose",
"version": "0.0.1",
}
- 下载安装 mongoose,在新建的目录下执行命令:
npm i mongoose --save
- 新建
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();
- 运行
**> 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 模块化
- 新建 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("数据库连接成功~~~");
});
- 新建 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;
- 在根目录下新建 index.js
require("./tools/conn_mongo");
var Student = require("./models/student");
Student.find({}, function(err, docs){
if(!err){
console.log(docs);
}
});
- 运行
**\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
}
]