前言
前言
这一篇主要讲mongodb 的文档相关操作
一、Mongo 文档操作
1. 文档增删改查
命令操作 | 作用 |
db.collection.insert() | db.collection.insert()将单个文档或多个文档插入到集合 中 |
db.collection.insertOne() | 插入文档,3.2 版中的新功能 |
db.collection.insertMany() | 插入多个文档,3.2 版中的新功能 |
db.collection.update() | 更新或替换与指定过滤器匹配的单个文档,或更新与指 定 过 滤 器 匹 配 的 所 有 文 档 。 默 认 情 况 下 , db.collection.update()方法更新单个文档。要更新多 个文档,请使用 multi 选项。 |
db.collection.updateOne() | 即使多个文档可能与指定的过滤器匹配,最多更新与指 定的过滤器匹配的单个文档。 3.2 版中的新功能 |
db.collection.updateMany() | 更新所有与指定过滤器匹配的文档。 3.2 版中的新功能 |
db.collection.replaceOne() | 即使多个文档可能与指定过滤器匹配,也最多替换一个 与指定过滤器匹配的文档。 |
db.collection.remove() | 删除单个文档或与指定过滤器匹配的所有文档 |
db.collection.deleteOne() | 即使多个文档可能与指定过滤器匹配,也最多删除一个 与指定过滤器匹配的文档。 3.2 版中的新功能 |
db.collection.deleteMany() | 删除所有与指定过滤器匹配的文档。 3.2 版中的新功能 |
db.collection.find(query, projection) | 查询文档 |
db.collection.findOne() | 查询文档只返回一个 |
二、插入文档
db.collection.insertOne() 将单个文档插入到集合中。
> db.student.insertOne({"name":"test", "age":23});
{
"acknowledged" : true,
"insertedId" : ObjectId("61d18c7549bcb487f58eb491")
}
db.collection.insertMany()将多个文件插入集合中。
> db.student.insertMany([{"name":"test1","age":20}, {"name":"test2", "age":21}]);
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("61d18d0a49bcb487f58eb492"),
ObjectId("61d18d0a49bcb487f58eb493")
]
}
db.collection.insert()将单个文档或多个文档插入到集合中。
> db.student.insert([{"name":"test3","age":21}, {"name":"test4", "age":22}]);
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 2,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
三、更新文档
案例使用insertMany集合
初始化集合数据:
db.inventory.insertMany( [
{ item: "canvas", qty: 100, size: { h: 28, w: 35.5, uom: "cm" }, status: "A" },
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "mat", qty: 85, size: { h: 27.9, w: 35.5, uom: "cm" }, status: "A" },
{ item: "mousepad", qty: 25, size: { h: 19, w: 22.85, uom: "cm" }, status: "P" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "P" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" },
{ item: "sketchbook", qty: 80, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "sketch pad", qty: 95, size: { h: 22.85, w: 30.5, uom: "cm" }, status:"A" }
] );
为了更新文档,MongoDB 提供了更新操作符(例如$set)来修改字段值。 要使用更新运算符,请将以下形式的更新文档传递给更新方法: { : { : , ... }, : { : , ... }, ... } 如果字段不存在,则某些更新操作符(例如$set)将创建该字段。
更新单个文档
db.inventory.updateOne(
{ item: "paper" },
{
$set: { "size.uom": "cm", status: "P" },
$currentDate: { lastModified: true }
}
)
> db.inventory.findOne({item:"paper"});
{
"_id" : ObjectId("61d18e3049bcb487f58eb49d"),
"item" : "paper",
"qty" : 100,
"size" : {
"h" : 8.5,
"w" : 11,
"uom" : "cm"
},
"status" : "P",
"lastModified" : ISODate("2022-01-02T11:39:59.035Z")
}
• 使用$set 运算符将 size.uom 字段的值更新为“ cm”,将状态字段的值更新为“ P”, • 使用$currentDate 运算符将 lastModified 字段的值更新为当前日期。 如果 lastModified 字段不存在,则$currentDate 将创建该字段。
更新多个文档
> db.inventory.updateMany(
... { "qty": { $lt: 50 } },
... {
... $set: { "size.uom": "in", status: "P" },
... $currentDate: { lastModified: true }
... }
... );
{ "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }
使用$set 运算符将 size.uom 字段的值更新为“ in”,将状态字段的值更新为“ P”.
使用 $currentDate 运算符将 lastModified 字段的值更新为当前日期。如果 lastModified 字段
不存在,则$currentDate 将创建该字段。
更换文档
要替换_id 字段以外的文档的全部内容, 请将一个全新的文档作为第二个参数传递给 db.collection.replaceOne()。 当替换一个文档时,替换文档必须只包含字段/值对;即不包括更新操作符表达式。 替换文档可以具有与原始文档不同的字段。在替换文档中,由于_id 字段是不可变的,因此可以省 略_id 字段。但是,如果您确实包含_id 字段,则它必须与当前值具有相同的值。 下面的示例替换了 inventory 集合中的第一个文件,其中项为"paper":
> db.inventory.replaceOne(
... { item: "paper" },
... { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty:
... 40 } ] }
... );
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
四、查询文档
MongoDB 查询文档使用 find() 方法。find() 方法以非结构化的方式来显示所有文档。 MongoDB 查询数据的语法格式如下:
db.collection.find(query, projection)
⚫ query :可选,使用查询操作符指定查询条件
⚫ projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该 参数即可(默认省略)。
> db.inventory.findOne({item:"paper"}, {_id:0,item:1,instock:1});
{
"item" : "paper",
"instock" : [
{
"warehouse" : "A",
"qty" : 60
},
{
"warehouse" : "B",
"qty" : 40
}
]
}
如果你需要以易读的方式来读取数据,可以使用 pretty() 方法。 db.demo.find() 返回数据时,每一条会占取一行,不便于阅读;而使用 db.find().pretty()方法时显示美 观,便于阅读。
除了 find() 方法之外,还有一个 findOne() 方法,它只返回一个文档。
重新初始化inventory集合
db.inventory.remove({});
db.inventory.insertMany([
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status:"A" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status:"A" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status:"D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status:"D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status:"A" }
]);
选择集合中的所有文档
要选择集合中的所有文档,请将空文档作为查询过滤器参数传递给 find 方法。
查询 过滤器参数确定选择条件:
db.inventory.find( {} )
此操作对应于以下 SQL 语句:
SELECT * FROM inventory
指定平等条件
要指定相等条件,请在查询筛选文档使用:表达式:
{ <field1>:<value1>,... }
下面的示例从 inventory 中选择状态等于" D"的所有文档:
db.inventory.find( { status: "D" }).pretty();
此操作对应于以下 SQL 语句:
SELECT * FROM inventory WHERE status = "D"
使用查询运算符指定条件 or
查询过滤器文档可以使用查询运算符以以下形式指定条件:
{<field1>:{<operator1>:<value1>},...}
下面的例子从状态等于" A"或" D"的 inventory 集合中检索所有文档:
db.inventory.find({status:{$in:["A","D"]}}).pretty();
Note:尽管可以使用$or 操作符表示此查询,但在对同一字段执行相等性检查时,请 使用 $in 操作符而不是$or 操作符。
该操作对应于以下 SQL 语句:
SELECT * FROM inventory WHERE status in ("A", "D")
指定和条件 and
复合查询可以为集合文档中的多个字段指定条件。逻辑和连词隐式地连接复合查询的 子句,以便查询在集合中选择符合所有条件的文档。 下面的示例 inventory 状态为"A"且数量小于($lt) 30 的库存集合中的所有文档:
db.inventory.find( { status: "A", qty: { $lt: 30 } } ).pretty();
该操作对应于以下 SQL 语句:
SELECT * FROM inventory WHERE status = "A" AND qty < 30
指定或条件
使用$or 操作符,可以指定一个复合查询,用逻辑 OR 连词连接每个子句,以便查询在 集合中选择至少匹配一个条件的文档。
下面的示例 status 状态为“A”或 qty 小于($lt)30 的集合中的所有文档:
db.inventory.find({$or:[{status:"A"},{qty:{$lt:30}}]}).pretty();
该操作对应于以下 SQL 语句:
SELECT * FROM inventory WHERE status = "A" OR qty < 30
指定和以及或条件
在下面的例子中,复合查询文档选择状态为“A”且 qty 小于($lt) 30 或 item 以字符 p 开头的集合中的所有文档:
db.inventory.find({status:"A",$or:[{qty:{$lt:30}},{item:/^p/}]}).pretty();
该操作对应于以下 SQL 语句:
SELECT * FROM inventory WHERE status = "A" AND ( qty < 30 OR item LIKE "p%")
MongoDB 支持正则表达式$regex 查询来执行字符串模式匹配。
$type 操作符
类型匹配用。
$type 操作符是基于 BSON 类型来检 索集合中匹配的数据类型,并返回结果。MongoDB 中可以使用的类型如下表所示:
类型 | 数字 | 备注 |
double | 1 | |
string | 2 | |
object | 3 | |
array | 4 | |
binary data | 5 | |
undefined | 6 | 已废弃。 |
object id | 7 | |
boolean | 8 | |
date | 9 | |
null | 10 | |
Regular Expression | 11 | |
JavaScript | 13 | |
Symbol | 14 | |
JavaScript (with scope) | 15 | |
32-bit integer | 16 | NumberInt() |
Timestamp | 17 | |
64-bit integer | 18 | NumberLong() |
Min key | 255 | Query with -1. |
Max key | 127 | |
MongoDB 操作符 - $type 实例
查询inventory中item为String的数据
> db.inventory.insertOne({"item":1});
{
"acknowledged" : true,
"insertedId" : ObjectId("61d1a56f49bcb487f58eb4ac")
}
> db.inventory.find();
{ "_id" : ObjectId("61d19e4e49bcb487f58eb4a8"), "item" : "notebook", "qty" : 50, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "P" }
{ "_id" : ObjectId("61d19e4e49bcb487f58eb4aa"), "item" : "planner", "qty" : 75, "size" : { "h" : 22.85, "w" : 30, "uom" : "cm" }, "status" : "D" }
{ "_id" : ObjectId("61d1a56f49bcb487f58eb4ac"), "item" : 1 }
> db.inventory.find({item:{$type:2}});
{ "_id" : ObjectId("61d19e4e49bcb487f58eb4a8"), "item" : "notebook", "qty" : 50, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "P" }
{ "_id" : ObjectId("61d19e4e49bcb487f58eb4aa"), "item" : "planner", "qty" : 75, "size" : { "h" : 22.85, "w" : 30, "uom" : "cm" }, "status" : "D" }
MongoDB Limit,Skip,Sort
MongoDB Limit() 方法
如果你需要在 MongoDB 中读取指定数量的数据记录,可以使用 MongoDB 的 Limit 方法,limit()方法 接受一个数字参数,该参数指定从 MongoDB 中读取的记录条数。
limit()方法基本语法如下所示:
>db.COLLECTION_NAME.find().limit(NUMBER)
例如
> db.inventory.find().limit(1);
{ "_id" : ObjectId("61d19e4e49bcb487f58eb4a8"), "item" : "notebook", "qty" : 50, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "P" }
MongoDB Skip() 方法
我们除了可以使用 limit()方法来读取指定数量的数据外,还可以使用 skip()方法来跳过指定数量的数 据,skip 方法同样接受一个数字参数作为跳过的记录条数。
skip() 方法脚本语法格式如下:
> db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
> db.inventory.find().limit(3).skip(2);
{ "_id" : ObjectId("61d1a56f49bcb487f58eb4ac"), "item" : 1 }
MongoDB sort() 方法
在 MongoDB 中使用 sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使 用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。
> db.inventory.find().sort({qty:1});
{ "_id" : ObjectId("61d1a56f49bcb487f58eb4ac"), "item" : 1, "qty" : 1 }
{ "_id" : ObjectId("61d19e4e49bcb487f58eb4a8"), "item" : "notebook", "qty" : 50, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "P" }
{ "_id" : ObjectId("61d19e4e49bcb487f58eb4aa"), "item" : "planner", "qty" : 75, "size" : { "h" : 22.85, "w" : 30, "uom" : "cm" }, "status" : "D" }
MongoDB 条件语句查询与 RDBMS Where 语句比
操作 | 格式 | 范例 | RDMS中类似语句 |
等于 | {field:value} | db.inventory.find({item:"paper"}).pretty() | where item='paper' |
小于 | {<key>:{$lt:<value>}} | db.inventory.find({qty:{$lt:70}}).pretty(); | where qty<70 |
小于或 等于 | {<key>:{$lte:<value>}} | db.inventory.find({qty:{$lte:70}}).pretty(); | where qty<=70 |
大于 | {<key>:{$gt:<value>}} | db.inventory.find({qty:{$gt:70}}).pretty(); | where qty>70 |
大于或 等于 | {<key>:{$gte:<value>}} | db.inventory.find({qty:{$gte:70}}).pretty(); | where qty>=70 |
不等于 | {<key>:{$ne:<value>}} | db.inventory.find({qty:{$ne:70}}).pretty(); | where qte<>70 |
附加查询教程
• Query on Embedded/Nested Documents
https://docs.mongodb.com/manual/tutorial/query-embedded-documents/
• Query an Array
https://docs.mongodb.com/manual/tutorial/query-arrays/
• Query an Array of Embedded Documents
https://docs.mongodb.com/manual/tutorial/query-array-of-documents/
• Project Fields to Return from Query
https://docs.mongodb.com/manual/tutorial/project-fields-from-query-results/
• Query for Null or Missing Fields
https://docs.mongodb.com/manual/tutorial/query-for-null-fields/
note:
db.collection.findOne()方法还执行读取操作以返回单个文档。在内部, db.collection.findOne()方法是 db.collection.find() 方法,限制为 1 (db.inventory.find( {} ).limit(1))。
五、删除文档
MongoDB remove()函数是用来移除集合中的数据。MongoDB 数 据更新可以使用 update()函数。在执行 remove()函数前先执行 find()命令来判断执行的条件是否正确, 这是一个比较好的习惯。
语法格式如下:
db.collection.remove( , { justOne: , writeConcern: } )
参数说明:
• query :(可选)删除的文档的条件。
• justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 fal se,则删除所有匹配条件的文档。
• writeConcern :(可选)抛出异常的级别。
删除item 是paper的文档
> db.inventory.remove({item:"paper"});
WriteResult({ "nRemoved" : 1 })
如果你想删除所有数据,可以使用以下方式(类似常规 SQL 的 truncate 命令):
db.inventory.remove({});
重新初始化inventory集合
db.inventory.deleteMany({});
db.inventory.insertMany( [
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status:"A" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status:"P" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status:"D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" },status: "D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" },status: "A" },
] );
删除所有文档
db.inventory.deleteMany({});
删除所有符合条件的文档
您可以指定标准或过滤器,以标识要删除的文档。 filter 使用与读取操作相同的语 法。
要指定相等条件,请在查询过滤器文档:中使用<field>:<value>表达式:
{<field1>:<value1>,...}
查询过滤器文档可以使用查询操作符 以以下形式指定条件:
{<field1>:{<operator1>:<valu1>},...}
要删除所有符合删除条件的文档,请将 filter 参数传递给 deleteMany()方法。
以下示例从状态字段等于“ A”的 inventory 集合中删除所有文档:
db.inventory.deleteMany({ status : "A" })
仅删除一个符合条件的文档
要删除最多一个与指定过滤器匹配的文档(即使多个文档可以与指定过滤器匹配),请 使用 db.collection.deleteOne()方法。
下面的示例删除状态为“ D”的第一个文档:
db.inventory.deleteOne( { status: "D" } )
删除行为
索引
即使从集合中删除所有文档,删除操作也不会删除索引。
原子性
MongoDB 中的所有写操作都是单个文档级别的原子操作。
总结
学习了mongodb的文档相关操作
技术参考