MongoDB
作为NoSQL
数据库的佼佼者,其强大的查询和操作能力令人印象深刻。
本文将深入探讨MongoDB
的CRUD
操作,包括插入、查询、更新和删除的详细步骤和技巧。通过实例代码,助您轻松掌握MongoDB
的核心操作,提升数据库管理效率。
插入操作
db.collection.insertOne()
db.collection('inventory').insertOne({
item: 'canvas',
qty: 100,
tags: ['cotton'],
size: { h: 28, w: 35.5, uom: 'cm' }
});
insertOne() 会返回一个提供 result 的 Promise。result.insertedId Promise 包含新插入文档的 _id
db.collection.insertMany()
db.collection('inventory').insertMany([
{
item: 'journal',
qty: 25,
name: 'toy',
tags: ['blank', 'red'],
size: { h: 14, w: 21, uom: 'cm' }
},
{
item: 'mat',
qty: 85,
tags: ['gray'],
size: { h: 27.9, w: 35.5, uom: 'cm' }
}
]);
insertMany() 会返回一个提供 result 的 Promise。result.insertedIds 字段包含一个数组,其中包含每个新插入文档的 _id。
查询操作
MongoDB 查询的通用方式 : db.表名.find({},{}).功能
- 第一个{} 为条件查询
- 第二个{} 为返回的列 {字段名:1}
- 功能 : sort(字段:1) | skip(num) | limit(num) | count()
查询所有字段信息
db.collection('inventory').find({})
条件查询
db.collection('inventory').find({item: "mat"})
查询指定字段(投影)
db.collection('inventory').find({item: 'mat'},{
_id:0,
item: 1,
qty: 1
});
此操作对应于以下 SQL
语句:
SELECT item, qty from inventory WHERE item = "mat"
返回嵌入式文档中的特定字段:
// 返回 size 中的 uom 字段
db.collection('inventory').find({}, { "size.uom": 1 })
1表示该字段显示,0表示不显示,比如这儿默认会返回主键"_id"信息,如果不想要就可以赋值为0。
条件+查询指定字段
db.collection('inventory').find({item: "mat"},{
_id:0,
item: 1,
qty: 1
});
比较查询操作符
符号条件查询,可以对查询的字段进行大小、相对、包含等过滤查询,例如查询 qty 大于等于 80的数据
// 查询 qty 大于或等于 80 的数据
db.collection('inventory').find({qty: {$gte: 80}})
以下是常用比较操作符
操作符 | 说明 |
---|---|
$eq | 字段等于 = |
$ne | 字段不等于 != |
$gt | 字段大于 > |
$gte | 字段大于等于 >= |
$lt | 字段小于 < |
$lte | 字段小于等于 <= |
$in | 字段值在数组里 |
$nin | 字段值不在数组里,与$in相反 |
使用$in时,必须用数组来设置条件值,比如获取 qty 为 25 和 85 的值
// 查询 qty 为 25 或 85 的值
db.inventory.find({qty: {$in: [25, 85]}})
逻辑查询操作符
逻辑操作符根据计算结果为 true
或 false
的表达式来返回数据。
有如下逻辑操作符:
操作符 | 说明 |
---|---|
$and | 所有条件同时满足时成立 |
$nor | 与$and相反,所有条件都不满足时成立 |
$or | 只要有一个条件满足则成立 |
$not | 返回所有无法满足条件的文档 |
隐式的 and
查询
// 查询 qty 字段存在,并且不等于 85 的文档
db.collection('inventory').find({
qty: { $ne: 85, $exists: true }
});
// 查询 qty 等于85 并且 item 等于 mat 的文档
db.collection('inventory').find({
qty: 85,
item: 'mat'
});
显示的 and
查询
// 查询 qty 等于25,并且item等于 mat 的文档
db.collection('inventory').find({
$and: [{
qty: { $eq: 25 }
}, {
item: 'mat'
}]
})
$nor
与 $and
相反,查询 qty 不等于25和item不是 mat 的文档
db.collection('inventory').find({
$nor: [{
qty: { $eq: 25 }
}, {
item: 'mat'
}]
})
$or
查询 qty = 25
或 item = mat
的文档
db.collection('inventory').find({
$or: [{
qty: { $eq: 25 }
}, {
item: 'mat'
}]
});
$not
查询 qty != 25
的文档
/** 查询的文档会满足如下条件
* * qty 小于等于25
* * qty 为非数字
* * qty 字段不存在
**/
db.collection('inventory').find({
qty: {$not: {$eq: 25}}
});
元素查询操作符
根据字段是否存在或数据类型来查询
操作符 | 说明 |
---|---|
$exists | 判断文档中字段是否存在,true为存在,false为不存在 |
$type | 查询字段是否为指定的类型 |
$exists
查询 name
字段存在的文档
await db.collection('inventory').find({
{name: {$exists: true}}
});
$type
查询 tags
字段为数组的文档
// 查询 tags 为数组的文档
db.collection('inventory').find({
{ tags: {$type:"array"} }
});
// 查询 item 为字符串的文档
db.collection('inventory').find({
{ name: {$type:"string"} }
});
$type
支持的类型见该文档:可用类型
查询数组
例如插入的数据如下:
await db.collection('inventory').insertMany([
{
item: 'journal',
qty: 25,
tags: ['blank', 'red'],
dim_cm: [14, 21]
},
{
item: 'notebook',
qty: 50,
tags: ['red', 'blank'],
dim_cm: [14, 21]
},
{
item: 'paper',
qty: 100,
tags: ['red', 'blank', 'plain'],
dim_cm: [14, 21]
},
{
item: 'planner',
qty: 75,
tags: ['blank', 'red'],
dim_cm: [22.85, 30]
},
{
item: 'postcard',
qty: 45,
tags: ['blue'],
dim_cm: [10, 15.25]
}
]);
对数组的查询方法有如下几种:
// 查询 tags 等于 ['red', 'blank']的数据,元素和顺序都相同
db.collection('inventory').find({
tags: ['red', 'blank']
});
// 查询同时包含 "red" 和 "blank" 元素的数组
db.collection('inventory').find({
tags: { $all: ['red', 'blank'] }
});
// 查询所有 tags 中包含 "red" 的数组
db.collection('inventory').find({
tags: 'red'
});
对数组进行多条件查询:
// 或的关系,查询 dim_cm 包含大于15或小于20的元素
db.collection('inventory').find({
dim_cm: { $gt: 15, $lt: 20 }
});
// 且的关系,查询 dim_cm 包含一个大于22或小于30的元素
db.collection('inventory').find({
dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } }
});
按数组元素索引查询:
// 查询第二个元素大于25的数据
db.collection('inventory').find({
'dim_cm.1': { $gt: 25 }
});
按数组长度查询
// tags 有 3 个元素的文档
db.collection('inventory').find({
tags: { $size: 3 }
});
更新操作
更新的操作方法有三个:
db.collection.updateOne()
: 更新符合条件的第一个文档db.collection.updateMany()
: 更新符合条件的所有文档db.collection.replaceOne()
:替换符号条件的第一个文档(除 _id 字段外)- $set:用于修改字段的值,如果字段不存在则创建该字段,
updateOne
更新符合条件的第一个文档
db.inventory.updateOne(
{ item: "paper" },
{
$set: { "size.uom": "cm", status: "P" }
}
)
- $currentDate:用于更新字段为当前日期
db.inventory.updateOne(
{ item: "paper" },
{ $currentDate: { lastModified: true } }
)
- 更新多个文档
db.inventory.updateMany(
{ qty: { $lt: 50 } },
{ $set: { "size.uom": "in", status: "P" } }
)
replaceOne()
:替换符合条件的第一个文档(除 _id 字段外)
db.inventory.replaceOne(
{ item: "paper" },
{
item: "paper",
instock: [{ warehouse: "A", qty: 60 }, { warehouse: "B", qty: 40 }]
}
);
- 更新或插入(
upsert
) upsert: true:如果无匹配文档,则创建新文档。
db.inventory.updateOne(
{ item: "newItem" },
{ $set: { qty: 100 } }, { upsert: true }
)
删除操作
删除操作主要有三个方法:
deleteOne()
: 删除与指定筛选器匹配的单个文档(即使有多个匹配)deleteMany()
:删除所有与指定筛选器匹配的文档remove()
: 删除单个或多个文档findOneAndDelete()
: 根据 filter 和 sort 条件删除单个文档,并返回已删除的文档findAndModify()
:
db.collection.deleteOne() 删除单个文档
db.users.deleteOne({ name: "Alice" });
db.collection.deleteMany() 删除符合条件的所有文档
db.users.deleteMany({ age: { $gt: 30 } });
db.collection.remove()
// 删除所有文档
db.users.remove({ });
// 删除符合条件的文档
db.users.remove({ name: "Bob" });
findOneAndDelete() 删除并返回按指定顺序排序的第一个匹配文档。
db.users.findOneAndDelete({ name: "Charlie" }, { sort: { age: 1 } });