当前位置: 首页 > news >正文

MongoDB 的基本使用

目录

数据库的创建和删除

创建数据库

查看数据库

删除数据库

集合的创建和删除

显示创建

查看

 删除集合

隐式创建

文档的插入和查询

单个文档的插入

insertOne

insertMany 

查询

嵌入式文档

查询数组

查询数组元素 

为数组元素指定多个条件 

通过对数组元素使用复合筛选条件查询数组

查询满足多个条件的数组元素

按数组索引位置查询元素

按数组长度查询数组

查询嵌入式文档数组

查询嵌套在数组中的文档

在文档数组中的字段上指定查询条件

在文档数组中嵌入的字段上指定查询条件

使用数组索引查询嵌入式文档中的字段

为文档数组指定多个条件

单个嵌套文档满足嵌套字段的多个查询条件

组合满足标准的元素

Update

更新或插入(upsert)选项

更新集合中的文档

更新单份文档

更新多个文档

替换文档

使用聚合管道进行更新 

使用 $set 的 updateOne

find() 和 find().pretty() 有什么区别

使用 $replaceRoot 和 $set 的 updateMany

使用 $set 的 updateMany

使用 $set 的 updateOne

使用 $addFields 的 updateMany

replaceOne 

删除

deleteOne

deleteMany

remove

WriteResul


参考: MongoDB CRUD 操作 - MongoDB 手册 v7.0

数据库的创建和删除

创建数据库

use database

数据库存在则使用(同 mysql 一样),没有则创建

查看数据库

test> show dbs
admin   40.00 KiB
config  12.00 KiB
local   40.00 KiB

注意:当我们创建出新的数据库之后再次 show dbs 并不会出现新增的数据库,这个就涉及到 mongodb 的存储机制的问题了, mongodb 的存储分为上下两个部分,分别是内存部分和磁盘部分,当使用 use 去创建数据库时,其实数据库这会还在内存当中,并没有初始化到磁盘中去,那什么时候回存在在磁盘当中呢,就是在数据库中存在至少一个集合的时候,这个数据库他就会帮你持久化到磁盘当中去

有一些数据库名是保留的,可以直接访问这些特殊作用的数据库

  • admin 从权限角度来看,这是 root 数据库,要是将一个用户添加到这个数据库当中,则这个用户会自动继承所有数据库的权限,一些特定的服务器命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器

  • local 这个数据库永远不会被复制,可以用来存储仅限于本地但要服务器的任意集合

  • config 当 mongodb 用于分片设置时,config 数据库在内部使用,用于保存分片的相关信息

删除数据库

adb> db.dropDatabase()
{ ok: 1, dropped: 'adb' }

集合的创建和删除

显示创建

adb> db.createCollection("wxw")
{ ok: 1 }

查看

adb> show collections
wxw

 删除集合

adb> db.wxw.drop()
true

隐式创建

 在接下来的文章中会有例子提及,还请耐心看完 ~~~~~~

文档的插入和查询

文档 (document) 的数据结构和 JSON 基本一样

所有存储在集合中的数据都是 BSON 格式

文档的插入

使用 install() 或者 save() 方法向集合中插入文档

单个文档的插入

参数说明

ParameterTypeDescription
documentdocument or array要插入到集合的文档或者文档数组(json 格式)
writeConcerndocument可选的。表达书面关注的文件。省略使用默认写关注点。参见写关注。不明确设置写关注在事务中运行的操作。使用写关注点关于事务,请参见事务和写关注点。
orderedboolean可选。如果为真,则按顺序插入数组中的文档,如果其中一个文档出现错误,MongoDB 将返回而不处理属猪中的其余文档。如果为假,则执行无序插入,如果其中一个文档出现错误,则继续处理数组中的主文档。在版本 2.6+ 中默认为 true

insertOne

将一个文档插入到集合中

_id 字段

如果文档没有指定_id字段,那么mongod将在插入之前添加_id字段并为文档分配唯一的ObjectId()。大多数驱动程序创建一个ObjectId并插入_id字段,但如果驱动程序或应用程序没有创建并填充_id,则mongod将创建并填充_id。
如果文档包含_id字段,则_id值在集合中必须是唯一的,以避免重复键错误。

像这种插入集合的情况,首先本地并没有创建过集合,而是创建集合和插入数据是一块执行的这种操作就是隐式创建 

try {db.products.insertOne( { item: "card", qty: 15 } );
} catch (e) {print (e);
};

返回这个则表示成功  

{acknowledged: true,insertedId: ObjectId('66fac15c5fb050d96a964039')
}

因为文档没有包含id,所以mongod创建并添加了id字段,并为其分配了唯一的ObjectId()值。

ObjectId值特定于操作运行时的机器和时间。因此,您的值可能与示例中的值不同。

插入指定_id字段的文档

在下面的示例中,传递给insertOne()方法的文档包含id字段。id的值在集合中必须是唯一的,以避免重复键错误。

try {db.products.insertOne( { _id: 10, item: "box", qty: 20 } );
} catch (e) {print (e);
}

返回结果与上述同理

插入作为唯一索引一部分的任何键的重复值,例如id,会引发异常。下面的例子尝试插入一个已经存在的id值的文档:

try {db.products.insertOne( { _id: 10, "item" : "packing peanuts", "qty" : 200 } );
} catch (e) {print (e);
}

由于_id: 10已经存在,抛出以下异常:  

WriteError({"index" : 0,"code" : 11000,"errmsg" : "E11000 duplicate key error collection: inventory.products index: _id_ dup key: { : 10.0 }","op" : {"_id" : 10,"item" : "packing peanuts","qty" : 200}
})

insertMany 

将多个文档插入到集合中。

try {db.products.insertMany( [{ item: "card", qty: 15 },{ item: "envelope", qty: 20 },{ item: "stamps" , qty: 30 }] );
} catch (e) {print (e);
}

返回如下则表示成功

{"acknowledged" : true,"insertedIds" : [ObjectId("562a94d381cb9f1cd6eb0e1a"),ObjectId("562a94d381cb9f1cd6eb0e1b"),ObjectId("562a94d381cb9f1cd6eb0e1c")]
}

 这个 _id 还是上面的解释同理

try {db.products.insertMany( [{ _id: 10, item: "large box", qty: 20 },{ _id: 11, item: "small box", qty: 55 },{ _id: 12, item: "medium box", qty: 30 }] );
} catch (e) {print (e);
}

返回的结果也和上面大差不差

插入作为唯一索引一部分的任何键的重复值,例如_id,会引发异常。下面的例子尝试插入一个已经存在的_id值的文档:

try {db.products.insertMany( [{ _id: 13, item: "envelopes", qty: 60 },{ _id: 13, item: "stamps", qty: 110 },{ _id: 14, item: "packing tape", qty: 38 }] );
} catch (e) {print (e);
}

由于_id: 13已经存在,抛出以下异常:

BulkWriteError({"writeErrors" : [{"index" : 0,"code" : 11000,"errmsg" : "E11000 duplicate key error collection: inventory.products index: _id_ dup key: { : 13.0 }","op" : {"_id" : 13,"item" : "stamps","qty" : 110}}],"writeConcernErrors" : [ ],"nInserted" : 1,"nUpserted" : 0,"nMatched" : 0,"nModified" : 0,"nRemoved" : 0,"upserted" : [ ]
})

查询

嵌入式文档

使用inventory 集合。连接到 MongoDB 实例中的测试数据库,然后创建 inventory 集合:

 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'}]);

查看一下是否插入成功

adb> db.inventory.find()
[{_id: ObjectId('66faccfb5f8cb68228964033'),item: 'journal',qty: 25,size: { h: 14, w: 21, uom: 'cm' },status: 'A'},{_id: ObjectId('66faccfb5f8cb68228964034'),item: 'notebook',qty: 50,size: { h: 8.5, w: 11, uom: 'in' },status: 'A'},{_id: ObjectId('66faccfb5f8cb68228964035'),item: 'paper',qty: 100,size: { h: 8.5, w: 11, uom: 'in' },status: 'D'},{_id: ObjectId('66faccfb5f8cb68228964036'),item: 'planner',qty: 75,size: { h: 22.85, w: 30, uom: 'cm' },status: 'D'},{_id: ObjectId('66faccfb5f8cb68228964037'),item: 'postcard',qty: 45,size: { h: 10, w: 15.25, uom: 'cm' },status: 'A'}
]

查询数组

还是先插入一些数据

db.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]}
]);

匹配数组

db.inventory.find({tags: ['red', 'blank']
});

 相反,如果想查找同时包含 "red" 和 "blank" 元素的数组,而不考虑顺序或数组中的其他元素,则请使用 $all 运算符:

db.inventory.find({tags: { $all: ['red', 'blank'] }
});

查询数组元素 

要查询数组字段是否至少包含一个具有指定值的元素,请使用筛选器 { <field>: <value> },其中的 <value> 是元素值。

以下示例将查询所有文档,其中 tags 为包含字符串 "red" 以作为其元素之一的数组:

 db.inventory.find({tags: 'red'
});

要对数组字段中的元素指定条件,请在查询过滤器文档中使用查询运算符:

例如,以下操作将查询所有文档,其中数组 dim_cm 至少包含一个其值大于 25 的元素。 

db.inventory.find({dim_cm: { $gt: 25 }
});

为数组元素指定多个条件 

在用复合条件查询数组中的元素时,您可以设置查询语句,使单个数组元素满足查询条件或是任意数组元素的组合满足查询条件。

通过对数组元素使用复合筛选条件查询数组

以下示例将查询特定文档,其中 dim_cm 数组包含以某种组合形式可满足查询条件的元素;例如,一个元素可满足大于 15 的条件,而另一元素可满足小于 20 的条件,或是单个元素可同时满足这两个条件:

db.inventory.find({dim_cm: { $gt: 15, $lt: 20 }
});

查询满足多个条件的数组元素

使用 $elemMatch 运算符为数组的元素指定多个条件,以使至少一个数组元素满足所有指定的条件。

以下示例将查询特定文档,其中 dim_cm 数组至少包含一个大于 ($gt) 22 且小于 ($lt) 30 的元素:

db.inventory.find({dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } }
});

按数组索引位置查询元素

使用点符号,可以在数组的特定索引或位置为元素指定查询条件。该数组使用从零开始的索引。

以下示例将查询所有文档,其中数组 dim_cm 中的第二个元素大于 25

db.inventory.find({'dim_cm.1': { $gt: 25 }
});

按数组长度查询数组

使用 $size 操作符以便按元素个数来查询数组。例如,以下示例会选择数组 tags 有 3 个元素的文档。

db.inventory.find({tags: { $size: 3 }
});

查询嵌入式文档数组

db.inventory.insertMany([{item: 'journal',instock: [{ warehouse: 'A', qty: 5 },{ warehouse: 'C', qty: 15 }]},{item: 'notebook',instock: [{ warehouse: 'C', qty: 5 }]},{item: 'paper',instock: [{ warehouse: 'A', qty: 60 },{ warehouse: 'B', qty: 15 }]},{item: 'planner',instock: [{ warehouse: 'A', qty: 40 },{ warehouse: 'B', qty: 5 }]},{item: 'postcard',instock: [{ warehouse: 'B', qty: 15 },{ warehouse: 'C', qty: 35 }]}
]);

查询嵌套在数组中的文档

以下示例选择 instock 数组中的元素与指定文档匹配的所有文档:

db.inventory.find({instock: { warehouse: 'A', qty: 5 }
});

 整个嵌入式/嵌套文档的相等匹配要求与指定文档精确匹配,包括字段顺序。例如,以下查询不匹配 inventory 集合中的任何文档:

db.inventory.find({instock: { qty: 5, warehouse: 'A' }
});

在文档数组中的字段上指定查询条件

在文档数组中嵌入的字段上指定查询条件

如果您不知道嵌套在数组中的文档的索引位置,请使用点 (.) 来连接数组字段的名称以及嵌套文档中的字段名称。

以下示例选择满足下列条件的所有文档——instock 数组至少有一份嵌入式文档包含字段 qty 且其值小于或等于 20

db.inventory.find({'instock.qty': { $lte: 20 }
});

使用数组索引查询嵌入式文档中的字段

使用点符号,可以在数组的特定索引或位置为文档中的字段指定查询条件。该数组使用从零开始的索引。

注意

使用点符号查询时,字段和索引必须位于引号内。

以下示例选择所有满足如下条件的文档——instock 数组的第一个元素是包含值小于或等于 20 的 qty 字段的文档:

db.inventory.find({'instock.0.qty': { $lte: 20 }
});

为文档数组指定多个条件

对嵌套在文档数组中的多个字段指定条件时,可指定查询,以使单个文档满足这些条件,或使数组中任意文档(包括单个文档)的组合满足这些条件。

单个嵌套文档满足嵌套字段的多个查询条件

使用 $elemMatch 操作符在大量嵌入式文档中指定多个条件,以使至少一个嵌入式文档满足所有指定条件。

以下示例查询满足如下条件的文档——instock 数组至少有一份嵌入式文档,该文档同时包含等于 5 的字段 qty 和等于 A 的字段 warehouse

db.inventory.find({instock: { $elemMatch: { qty: 5, warehouse: 'A' } }
});

 以下示例将查询 instock 数组至少包含一个嵌入文档,且该文档包含大于 qty 且小于或等于 20 的字段 10

db.inventory.find({instock: { $elemMatch: { qty: { $gt: 10, $lte: 20 } } }
});

组合满足标准的元素

如果数组字段上的复合查询条件没有使用 $elemMatch 操作符,则查询会选择如下文档:数组中包含满足条件的任意元素的组合。

例如,以下查询匹配如下文档:嵌套在 instock 数组内的任何文档的 qty 字段大于 10 且该数组中的任何文档(不一定是同一份嵌入式文档)的 qty 字段小于或等于 20

db.inventory.find({'instock.qty': { $gt: 10, $lte: 20 }
});

以下示例查询符合以下条件的文档 — instock 数组至少有一个包含等于 5 的字段 qty 的嵌入式文档,以及至少一个包含等于 A 的字段 warehouse 的嵌入式文档(但不一定是同一个嵌入式文档):

db.inventory.find({'instock.qty': 5,'instock.warehouse': 'A'
});

Update

更新或插入(upsert)选项

使用inventory 集合。连接到 MongoDB 实例中的测试数据库,然后创建 inventory 集合:

db.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 )将创建该字段。有关详细信息,请参阅各个更新操作符参考文档。

更新单份文档

以下示例使用 Collection.updateOne()方法在 inventory 集合上更新第一个 item 等于 "paper" 的文档:

 db.inventory.updateOne({ item: 'paper' },{$set: { 'size.uom': 'cm', status: 'P' },$currentDate: { lastModified: true }}
);

更新操作:

  • 使用 $set 操作符将 size.uom 字段的值更新为 "cm",并将 status 字段的值更新为 "P",,

  • 使用 $currentDate 操作符将 lastModified 字段的值更新为当前日期。如果 lastModified 字段不存在,则 $currentDate 将创建该字段。有关详细信息,请参阅 $currentDate。

更新多个文档

如下示例使用 Collection.updateMany()方法(位于 inventory 集合上)更新 qty 小于 50 的所有文档:

db.inventory.updateMany({ qty: { $lt: 50 } },{$set: { 'size.uom': 'in', status: 'P' },$currentDate: { lastModified: true }}
);

更新操作:和上述操作一致

替换文档

要替换除 _id 字段之外的文档的所有内容,请将全新文档作为第二个参数传递给 Collection.replaceOne()。

替换文档时,替换文档必须仅包含字段/值对。替换文档不能包含更新操作符表达式。

替换文档可以具有与原始文档不同的字段。在替换文档中,您可以省略_id字段,因为_id字段不可变。但是,如果您确实包含_id字段,则它的值必须与当前值相同。

如下示例将替换 inventory 集合中的第一个文档,其中的 item: "paper"

db.inventory.replaceOne({ item: 'paper' },{item: 'paper',instock: [{ warehouse: 'A', qty: 60 },{ warehouse: 'B', qty: 40 }]}
);

使用聚合管道进行更新 

通过更新操作,聚合管道可以包含以下阶段:

  • $addFields

  • $set

  • $project

  • $unset

  • $replaceRoot

  • $replaceWith

使用聚合分析管道可以进行更具表现力的更新声明,例如基于当前字段值的Express条件更新或使用另一个字段的值更新一个字段。

使用 $set 的 updateOne

创建一个 students 示例集合(如果该集合当前不存在,插入操作则会创建该集合):

db.students.insertMany( [{ _id: 1, test1: 95, test2: 92, test3: 90, modified: new Date("01/05/2020") },{ _id: 2, test1: 98, test2: 100, test3: 102, modified: new Date("01/05/2020") },{ _id: 3, test1: 95, test2: 110, modified: new Date("01/04/2020") }
] )

若要验证,请查询集合:

db.students.find()

以下 db.collection.updateOne() 操作会使用某一聚合管道来更新 _id: 3 的文档:

db.students.updateOne( { _id: 3 }, [ { $set: { "test3": 98, modified: "$$NOW"} } ] )

具体来说,管道包含一个 $set 阶段,该阶段将 test3 字段(并将其值设置为 98)添加到文档中,并将 modified 字段设置为当前日期时间。该操作使用聚合变量 NOW 作为当前日期时间。要访问变量,请使用 $ 作为前缀,并用引号括起来。

若要验证更新,您可以查询集合:

db.students.find().pretty()

find() 和 find().pretty() 有什么区别

  1. db.collection.find()

    • 这是最基本的查询方法,它会返回一个游标(cursor),这个游标可以用来遍历查询结果集中的所有文档。
    • 返回的结果通常是以JSON格式的字符串形式显示,但这个格式是紧凑的,没有缩进和换行,可读性较差。
  2. db.collection.find().pretty()

    • .pretty() 是一个辅助函数,它的作用是美化(pretty-print)查询结果。
    • 当你调用 .pretty() 方法时,MongoDB会将查询结果格式化为更易于阅读的格式,包括缩进和换行,使得结果更加清晰和易于理解。

使用 $replaceRoot 和 $set 的 updateMany

创建一个 students2 示例集合(如果该集合当前不存在,插入操作则会创建该集合):

db.students2.insertMany( [{ "_id" : 1, quiz1: 8, test2: 100, quiz2: 9, modified: new Date("01/05/2020") },{ "_id" : 2, quiz2: 5, test1: 80, test2: 89, modified: new Date("01/05/2020") },
] )

以下 db.collection.updateMany() 操作会使用某一聚合管道来标准化此文档的字段(即,集合中的文档应具有相同字段)并更新 modified 字段:

db.students2.updateMany( {},[{ $replaceRoot: { newRoot:{ $mergeObjects: [ { quiz1: 0, quiz2: 0, test1: 0, test2: 0 }, "$$ROOT" ] }} },{ $set: { modified: "$$NOW"}  }]
)

具体而言,管道包括:

  • 附带 $mergeObjects 表达式的 $replaceRoot 阶段,以便为 quiz1、quiz2、test1 和 test2 字段设置默认值。聚合变量 ROOT 是指当前修改的文档。要访问此变量,请将 $ 用作前缀,并用引号括起来。当前文档字段将覆盖这些默认值。

  • $set 阶段,以便将 modified 字段更新为当前日期时间。此操作会将聚合变量 NOW 用作当前日期时间。要访问此变量,请将 $ 用作前缀,并用引号括起来。

使用 $set 的 updateMany

创建一个 students3 示例集合(如果该集合当前不存在,插入操作则会创建该集合):

db.students3.insertMany( [{ "_id" : 1, "tests" : [ 95, 92, 90 ], "modified" : ISODate("2019-01-01T00:00:00Z") },{ "_id" : 2, "tests" : [ 94, 88, 90 ], "modified" : ISODate("2019-01-01T00:00:00Z") },{ "_id" : 3, "tests" : [ 70, 75, 82 ], "modified" : ISODate("2019-01-01T00:00:00Z") }
] );

以下 db.collection.updateMany() 操作使用某一聚合管道来更新具有计算得出的平均成绩和字母成绩的文档。

db.students3.updateMany({ },[{ $set: { average : { $trunc: [ { $avg: "$tests" }, 0 ] }, modified: "$$NOW" } },{ $set: { grade: { $switch: {branches: [{ case: { $gte: [ "$average", 90 ] }, then: "A" },{ case: { $gte: [ "$average", 80 ] }, then: "B" },{ case: { $gte: [ "$average", 70 ] }, then: "C" },{ case: { $gte: [ "$average", 60 ] }, then: "D" }],default: "F"} } } }]
)

具体而言,管道包括:

  • $set 阶段,以便计算 tests 数组元素的截断后的平均值并将 modified 字段更新为当前日期时间。为计算截断后的平均值,此阶段会使用 $avg 和 $trunc 表达式。该操作使用聚合变量 NOW 作为当前日期时间。 要访问变量,请使用 $ 作为前缀,并用引号括起来。

  • $set 阶段,以便使用 $switch 表达式并根据 average 来添加 grade 字段。

使用 $set 的 updateOne

创建一个 students4 示例集合(如果该集合当前不存在,插入操作则会创建该集合):

db.students4.insertMany( [{ "_id" : 1, "quizzes" : [ 4, 6, 7 ] },{ "_id" : 2, "quizzes" : [ 5 ] },{ "_id" : 3, "quizzes" : [ 10, 10, 10 ] }
] )

以下 db.collection.updateOne() 操作使用聚合管道向具有 _id: 2 的文档添加测验分数:

db.students4.updateOne( { _id: 2 },[ { $set: { quizzes: { $concatArrays: [ "$quizzes", [ 8, 6 ]  ] } } } ]
)

使用 $addFields 的 updateMany

创建一个包含摄氏度温度的 temperatures 示例集合(如果该集合当前不存在,插入操作将创建该集合):

db.temperatures.insertMany( [{ "_id" : 1, "date" : ISODate("2019-06-23"), "tempsC" : [ 4, 12, 17 ] },{ "_id" : 2, "date" : ISODate("2019-07-07"), "tempsC" : [ 14, 24, 11 ] },{ "_id" : 3, "date" : ISODate("2019-10-30"), "tempsC" : [ 18, 6, 8 ] }
] )

 以下 db.collection.updateMany() 操作使用聚合管道以相应的华氏度温度更新文档:

db.temperatures.updateMany( { },[{ $addFields: { "tempsF": {$map: {input: "$tempsC",as: "celsius",in: { $add: [ { $multiply: ["$$celsius", 9/5 ] }, 32 ] }}} } }]
)

具体来说,此管道包含 $addFields阶段,它可用于添加包含华氏温度的新数组字段 tempsF。要将 tempsC 数组中的每个摄氏温度转换为华氏温度,此阶段会使用 $map、$add 和 $multiply 表达式。 

replaceOne 

基于筛选器替换集合中的单个文档。

replaceOne()使用替换文档替换集合中与过滤器匹配的第一个匹配文档。

举例子

餐厅收藏包含以下文件:

{ "_id" : 1, "name" : "Central Perk Cafe", "Borough" : "Manhattan" },
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "Borough" : "Queens", "violations" : 2 },
{ "_id" : 3, "name" : "Empire State Pub", "Borough" : "Brooklyn", "violations" : 0 }

下面的操作替换名称为:"Central Perk Cafe"的单个文档:

try {db.restaurant.replaceOne({ "name" : "Central Perk Cafe" },{ "name" : "Central Pork Cafe", "Borough" : "Manhattan" });
} catch (e){print(e);
}

 如果没有找到匹配项,则返回:

{ "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0 }

设置upsert: true将在没有找到匹配项时插入文档。参见“替换” 

用Upsert代替

餐厅收藏包含以下文件:

{ "_id" : 1, "name" : "Central Perk Cafe", "Borough" : "Manhattan",  "violations" : 3 },
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "Borough" : "Queens", "violations" : 2 },
{ "_id" : 3, "name" : "Empire State Pub", "Borough" : "Brooklyn", "violations" : 0 }

下面的操作尝试用名称:“Pizza Rat's Pizzaria”替换文档,upsert: true:

try {db.restaurant.replaceOne({ "name" : "Pizza Rat's Pizzaria" },{ "_id": 4, "name" : "Pizza Rat's Pizzaria", "Borough" : "Manhattan", "violations" : 8 },{ upsert: true });
} catch (e){print(e);
}

 由于upsert: true,文档是基于替换文档插入的。

{"acknowledged" : true,"matchedCount" : 0,"modifiedCount" : 0,"upsertedId" : 4
}

该集合现在包含以下文档:

{ "_id" : 1, "name" : "Central Perk Cafe", "Borough" : "Manhattan", "violations" : 3 },
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "Borough" : "Queens", "violations" : 2 },
{ "_id" : 3, "name" : "Empire State Pub", "Borough" : "Brooklyn", "violations" : 0 },
{ "_id" : 4, "name" : "Pizza Rat's Pizzaria", "Borough" : "Manhattan", "violations" : 8 }

替换为写关注点

给定一个包含三个成员的副本集,下面的操作指定w为majority, wtimeout为100: 

try {db.restaurant.replaceOne({ "name" : "Pizza Rat's Pizzaria" },{ "name" : "Pizza Rat's Pub", "Borough" : "Manhattan", "violations" : 3 },{ w: "majority", wtimeout: 100 });
} catch (e) {print(e);
}

如果确认时间超过wtimeout限制,则抛出以下异常:

WriteConcernError({"code" : 64,"errmsg" : "waiting for replication timed out","errInfo" : {"wtimeout" : true,"writeConcern" : {"w" : "majority","wtimeout" : 100,"provenance" : "getLastErrorDefaults"}}
})

删除

deleteOne

从集合中删除单个文档。

举例

删除单个文档

订单集合具有以下结构的文档:

db.orders.insertOne({_id: ObjectId("563237a41a4d68582c2509da"),stock: "Brent Crude Futures",qty: 250,type: "buy-limit",limit: 48.90,creationts: ISODate("2015-11-01T12:30:15Z"),expiryts: ISODate("2015-11-01T12:35:15Z"),client: "Crude Traders Inc."}
)

删除id为ObjectId("563237a41a4d68582c2509da")的订单。

try {db.orders.deleteOne( { _id: ObjectId("563237a41a4d68582c2509da") } );
} catch (e) {print(e);
}

下面的操作删除第一个过期日期大于ISODate("2015-11-01T12:40:15Z")的文档

try {db.orders.deleteOne( { expiryts: { $lt: ISODate("2015-11-01T12:40:15Z") } } );
} catch (e) {print(e);
}

deleteMany

从集合中删除与筛选器匹配的所有文档。

举例

删除多个文档

订单集合具有以下结构的文档:

db.orders.insertOne({_id: ObjectId("563237a41a4d68582c2509da"),stock: "Brent Crude Futures",qty: 250,type: "buy-limit",limit: 48.90,creationts: ISODate("2015-11-01T12:30:15Z"),expiryts: ISODate("2015-11-01T12:35:15Z"),client: "Crude Traders Inc."}
)

下面的操作删除客户:“Crude Traders Inc.”的所有文档:

try {db.orders.deleteMany( { "client" : "Crude Traders Inc." } );
} catch (e) {print (e);
}

下面的操作删除所有文档: "Brent Crude Futures" 且极限值大于48.88;

try {db.orders.deleteMany( { "stock" : "Brent Crude Futures", "limit" : { $gt : 48.88 } } );
} catch (e) {print (e);
}

remove

从集合中删除文档。

以下是 remove() 方法的示例。

db.bios.remove( { } )

此操作不等同于 drop() 方法。

要从集合中删除所有文档,更高效的做法是使用 drop()  方法删除整个集合(包括索引),然后重新创建该集合并重建索引。

以下操作会删除集合 products 中 qty 大于 20 的所有文档:

db.products.remove( { qty: { $gt: 20 } } )

WriteResult

remove() 会返回一个包含操作状态的 WriteResult() 对象。成功后,WriteResult() 对象将包含被删除文档数量的信息。

WriteResult({ "nRemoved" : 4 })

相关文章:

MongoDB 的基本使用

目录 数据库的创建和删除 创建数据库 查看数据库 删除数据库 集合的创建和删除 显示创建 查看 删除集合 隐式创建 文档的插入和查询 单个文档的插入 insertOne insertMany 查询 嵌入式文档 查询数组 查询数组元素 为数组元素指定多个条件 通过对数组元素使…...

数据揭秘:分类与预测技术在商业洞察中的应用与实践

分类与预测&#xff1a;数据挖掘中的关键任务 在数据挖掘的广阔天地中&#xff0c;分类与预测就像是一对互补的探险家&#xff0c;它们携手深入数据的丛 林&#xff0c;揭示隐藏的宝藏。 一、分类&#xff1a;数据的归类大师 分类是一种将数据点按照特定的属性或特征划分到不…...

学MybatisPlus

1.设置MySql的数据库 spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mp?useUnicodetrue&characterEncodingUTF-8&autoReconnecttrue&serverTimezoneAsia/Shanghaidriver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: MySQL123 logging:l…...

如何使用工具删除 iPhone 上的图片背景

在 iPhone 上删除背景图像变得简单易行。感谢最近 iOS 更新中引入的新功能。如今&#xff0c;iOS 用户现在可以毫不费力地删除背景&#xff0c;而无需复杂的应用程序。在这篇文章中&#xff0c;您将学习如何使用各种方法去除 iPhone 上的背景。这可确保您可以选择最适合您偏好的…...

软件工程-数据流图

数据流图(Data Flow Diagram&#xff0c;DFD)是一种图形化技术&#xff0c;它描绘信息流和数据从输入移动到输出的过程中所经受的变换。 数据流图的设计原则 数据守恒原则&#xff0c;对于任何一个加工来说&#xff0c;其所有输出数据流中的数据必须能从该加工的输入数据流中…...

链式前向星(最通俗易懂的讲解)

链式前向新&#xff1a;用于存储图的 边集 数组 前言 当我们存储图的时候&#xff0c;往往会使用 邻接矩阵 或是 邻接表。 邻接矩阵 好写&#xff0c;但太浪费空间&#xff0c;节点一多就存不下&#xff1b; 邻接表 效率高&#xff0c;但涉及指 &#xff0c;不好写容易出错…...

【C++设计模式】(四)创建型模式:简单工厂模式,工厂方法模式,抽象工厂模式

文章目录 &#xff08;四&#xff09;创建型模式&#xff1a;简单工厂模式&#xff0c;工厂方法模式&#xff0c;抽象工厂模式简单工厂模式工厂方法模式抽象工厂模式 &#xff08;四&#xff09;创建型模式&#xff1a;简单工厂模式&#xff0c;工厂方法模式&#xff0c;抽象工…...

浅析Golang的Context

文章目录 1. 简介2. 常见用法2.1 控制goroutine的生命周期&#xff08;cancel&#xff09;2.2 传递超时&#xff08;Timeout&#xff09;信息2.3 传递截止时间&#xff08;Deadline&#xff09;2.4 传递请求范围内的全局数据 &#xff08;value&#xff09; 3 特点3.1 上下文的…...

生日礼物C++代码

#include<bits/stdc.h> using namespace std; string s; int a,b; int main(){cout<<" 生日之地"<<\n;cout<<" 1.开始游戏"<<" 2.不想开始"<<\n;cin>>a;if(a1||a2){if(a2)cout<<…...

使用python基于DeepLabv3实现对图片进行语义分割

DeepLabv3 介绍 DeepLabv3 是一种先进的语义分割模型&#xff0c;由 Google Research 团队提出。它在 DeepLab 系列模型的基础上进行了改进&#xff0c;旨在提高图像中像素级分类的准确性。以下是 DeepLabv3 的详细介绍&#xff1a; 概述DeepLabv3 是 DeepLab 系列中的第三代…...

【漏洞复现】泛微OA E-Office do_excel.php 任意文件写入漏洞

》》》产品描述《《《 泛微0-0fice是一款标准化的协同 OA办公软件&#xff0c;泛微协同办公产品系列成员之一,实行通用化产品设计&#xff0c;充分贴合企业管理需求&#xff0c;本着简洁易用、高效智能的原则&#xff0c;为企业快速打造移动化、无纸化、数字化的办公平台。 》》…...

算法(食物链)

240. 食物链 题目 动物王国中有三类动物 A,B,C&#x1d434;,&#x1d435;,&#x1d436;&#xff0c;这三类动物的食物链构成了有趣的环形。 A&#x1d434; 吃 B&#x1d435;&#xff0c;B&#x1d435; 吃 C&#x1d436;&#xff0c;C&#x1d436; 吃 A&#x1d434;。…...

ubuntu20.04系统安装zookeeper简单教程

Ubuntu系统中安装和配置Zookeeper的完整指南 Apache Zookeeper是一个开源的分布式协调服务&#xff0c;广泛用于分布式应用程序中管理配置、提供命名服务、分布式同步以及组服务等。在本教程中&#xff0c;我们将详细介绍如何在Ubuntu系统中安装Zookeeper&#xff0c;并进行相关…...

.NET Core 高性能并发编程

一、高性能大并发架构设计 .NET Core 是一个高性能、可扩展的开发框架&#xff0c;可以用于构建各种类型的应用程序&#xff0c;包括高性能大并发应用程序。为了设计和开发高性能大并发 .NET Core 应用程序&#xff0c;需要考虑以下几个方面&#xff1a; 1. 异步编程 异步编程…...

B 私域模式升级:开源技术助力传统经销体系转型

一、引言 1.1 研究背景 随着市场竞争加剧&#xff0c;传统经销代理体系面临挑战。同时&#xff0c;开源技术发展迅速&#xff0c;为 B 私域升级带来新机遇。在当今数字化时代&#xff0c;企业面临着日益激烈的市场竞争。传统的经销代理体系由于管理效率低下、渠道局限、库存压…...

vue之vuex的使用及举例

Vuex是专门为Vue.js设计的集中式状态管理架构&#xff0c;它允许你将所有的组件共享状态存储在一个单独的地方&#xff0c;即“store”&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化。以下是Vuex的基本使用方法&#xff1a; 一、安装Vuex 对于Vue 2项目&…...

使用 vite 快速初始化 shadcn-vue 项目

Vite 1. 创建项目 使用 vite 创建一个新的 vue 项目。 如果你正在使用 JS 模板&#xff0c;需要存在 jsconfig.json 文件才能正确运行 CLI。 # npm 6.x npm create vitelatest my-vue-app --template vue-ts# npm 7, extra double-dash is needed: npm create vitelatest m…...

微信小程序:一个小程序跳转至另一个小程序

一、微信小程序支持一个小程序跳转至另一个小程序吗&#xff1f; 支持。 1.1、目标小程序需开放被跳转&#xff1a;目标小程序需要在其 app.json 文件中配置 navigateToMiniProgramAppIdList&#xff0c;将源小程序的 AppID 加入其中。 1.2、用户授权&#xff1a;用户需要授…...

Java第二阶段---10方法带参---第二节 方法重载(Overloading)

1.概念 在同一个类中&#xff0c;方法名相同&#xff0c;参数列表不同的多个方法构造成方法重载 2.示例 public class Calculator{public int sum(int a,int b){return ab;}public int sum(int a,int b,int c){return abc;} } 3.误区 下面的方法是否属于方法重载&#xff…...

Java Web 之 Session 详解

在 JavaWeb 开发中&#xff0c;Session 就像网站的专属记忆管家&#xff0c;为每个用户保管着重要的信息和状态&#xff0c;确保用户在网站的旅程顺畅无阻。 场景一&#xff1a; 想象你去一家大型超市购物&#xff0c;推着购物车挑选商品。这个购物车就如同 Session&#xff…...

63.5 注意力提示_by《李沐:动手学深度学习v2》pytorch版

系列文章目录 文章目录 系列文章目录注意力提示生物学中的注意力提示查询、键和值注意力的可视化使用 show_heatmaps 显示注意力权重代码示例 代码解析结果 小结练习 注意力提示 &#x1f3f7;sec_attention-cues 感谢读者对本书的关注&#xff0c;因为读者的注意力是一种稀缺…...

vscode 的terminal 输出打印行数限制设置

修改 VSCODE 的 settings.json文件 "terminal.integrated.scrollback": 100000, {"extensions.ignoreRecommendations": true,"workbench.colorTheme": "Monokai","explorer.confirmDelete": false,"editor.fontSize…...

深入挖掘C++中的特性之一 — 继承

目录 1.继承的概念 2.举个继承的例子 3.继承基类成员访问方式的变化 1.父类成员的访问限定符对在子类中访问父类成员的影响 2.父类成员的访问限定符子类的继承方式对在两个类外访问子类中父类成员的影响 4.继承类模版&#xff08;注意事项&#xff09; 5.父类与子类间的转…...

Linux 下 poll 详解

在Linux系统编程中&#xff0c;poll 是一个强大的多路复用&#xff08;I/O 多路复用&#xff09;函数&#xff0c;用于同时监控多个文件描述符的事件&#xff0c;特别是在处理网络套接字或其他I/O设备时。相比于select&#xff0c;poll 支持监控更多的文件描述符&#xff0c;并…...

virtualbox配置为NAT模式后物理机和虚拟机互通

virtualbox配置为 NAT模式后&#xff0c;虚拟机分配到的 IP地址一般是 10.xx网段的&#xff0c;虚拟机可以通过网络地址转换访问物理机所在的网络&#xff0c;但若不做任何配置&#xff0c;则物理机无法直接访问虚拟机。 virtualbox在提供 NAT配置模式时&#xff0c;也提供了端…...

工程机械车辆挖掘机自卸卡车轮式装载机检测数据集VOC+YOLO格式2644张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2644 标注数量(xml文件个数)&#xff1a;2644 标注数量(txt文件个数)&#xff1a;2644 标注…...

[Notepad++] 文本编辑器的下载及详细安装使用过程(附有下载文件)

程序员常用的文本编辑器Notepad&#xff0c;用于修改配置文件等 下载链接在文末 下载压缩包后解压 &#xff01;&#xff01;安装路径不要有中文 解压文件&#xff0c;得到 双击exe文件 选择简体中文&#xff0c;点击OK 点击下一步 点击“我接受” 更改安装目录&#xff0c;不…...

深入浅出Java多线程(六):Java内存模型

引言 大家好&#xff0c;我是你们的老伙计秀才&#xff01;今天带来的是[深入浅出Java多线程]系列的第六篇内容&#xff1a;Java内存模型。大家觉得有用请点赞&#xff0c;喜欢请关注&#xff01;秀才在此谢过大家了&#xff01;&#xff01;&#xff01; 在并发编程中&#xf…...

注册了个小趴菜999#it#com

注册了个 999#it#com 拿着玩玩吧 现在二级域名竟然也让注册了 不过cn.com的二级似乎早就可以了...

UE4 材质学习笔记02(数据类型/扭曲着色器)

一.什么是数据类型 首先为啥理解数据类型是很重要的。一些节点的接口插槽只接受特定类型的数据&#xff0c;如果连接了不匹配的数据就会出现错误&#xff0c;有些接口可以接受任何数据类型&#xff0c;但是实际上只会使用到其中的一些。并且有时可以将多个数据流合并成一个来编…...