首页 > 数据库 >MongoDB基础之文档DML操作

MongoDB基础之文档DML操作

时间:2022-11-05 19:59:14浏览次数:48  
标签:1.3 MongoDB db update 更新 DML 文档

目录

1 文档DML

主要讲解的是文档的创建,更新,删除等相关操作

1.1 定义

文档是一组键值(key-value)对(即 BSON)。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点

下表列出了 RDBMS 与 MongoDB 对应的术语:

RDBMS MongoDB
数据库 数据库
表格 集合
文档
字段
表联合 嵌入文档
主键 主键 (MongoDB 提供了 key 为 _id )

需要注意的是:

  • 文档中的键/值对是有序的。
  • 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
  • MongoDB区分类型和大小写。
  • MongoDB的文档不能有重复的键。
  • 文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。

文档键命名规范:

  • 键不能含有\0 (空字符)。这个字符用来表示键的结尾。
  • .$有特别的意义,只有在特定环境下才能使用。
  • 以下划线_开头的键是保留的(不是严格要求的)

1.2 插入文档

由于文档的数据结构和JSON基本一样。所有存储在集合中的数据都是 BSON 格式。BSON 是一种类似 JSON 的二进制形式的存储格式,是 Binary JSON 的简称。

MongoDB 使用 insert()save() 方法向集合中插入文档,语法如下:

db.COLLECTION_NAME.insert(document)
或
db.COLLECTION_NAME.insertOne(document) 
或
db.COLLECTION_NAME.insertMany(document) 
或
db.COLLECTION_NAME.save(document)
  • save():如果 _id 主键存在则更新数据,如果不存在就插入数据。该方法新版本中已废弃,可以使用 db.collection.insertOne()db.collection.replaceOne() 来代替。
    如果不指定 _id 字段 save() 方法类似于insert()方法。如果指定 _id 字段,则会更新该 _id 的数据
  • insert(): 若插入的数据主键已经存在,则会抛 org.springframework.dao.DuplicateKeyException异常,提示主键重复,不保存当前数据。3.2 版本之后新增了 db.collection.insertOne()db.collection.insertMany()
  • db.collection.insertOne() 用于向集合插入一个新文档
  • db.collection.insertMany() 用于向集合插入一个多个文档,语法格式如下:

插入语法格式:

db.collection.insertMany(
   [ <document 1> , <document 2>, ... ],
   {
      writeConcern: <document>,
      ordered: <boolean>
   }
)

参数说明:

  • document:要写入的文档。
  • writeConcern:写入策略,默认为 1,即要求确认写操作,0 是不要求。
  • ordered:指定是否按顺序写入,默认 true,按顺序写入。

实例
以下文档可以存储在 MongoDB 的 test数据库 的 col 集合中:

db.test.insert({title: 'MongoDB 教程', 
    description: 'MongoDB 是一个 Nosql 数据库',
    by: 'myself',
    url: 'http://www.test.com',
    tags: ['mongodb', 'database', 'NoSQL'],
    likes: 100
})

以上实例中 test是我们的集合名,如果该集合不在该数据库中, MongoDB 会自动创建该集合并插入文档。

我们也可以将数据定义为一个变量,如下所示:

document=({title: 'MongoDB 教程', 
    description: 'MongoDB 是一个 Nosql 数据库',
    by: 'myself',
    url: 'http://www.test.com',
    tags: ['mongodb', 'database', 'NoSQL'],
    likes: 100
});

执行后显示结果如下:

document=({title: 'MongoDB 教程', 
    description: 'MongoDB 是一个 Nosql 数据库',
    by: 'myself',
    url: 'http://www.test.com',
    tags: ['mongodb', 'database', 'NoSQL'],
    likes: 100
});

执行插入操作:

db.test.insert(document)
WriteResult({ "nInserted" : 1 })

1.3 更新文档

使用 update() save() 方法来更新集合中的文档。接下来让我们详细来看下两个函数的应用及其区别。

1.3.1 update() 方法

update() 方法用于更新已存在的文档。语法格式如下:

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

参数说明:

  • query : update的查询条件,类似sql update查询内where后面的。
  • update: update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
  • upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNewtrue为插入,默认是false,不插入。
  • multi : 可选,mongodb默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
  • writeConcern :可选,抛出异常的级别。
    WriteConcern.NONE:没有异常抛出
    WriteConcern.NORMAL:仅抛出网络错误异常,没有服务器错误异常
    WriteConcern.SAFE:抛出网络错误异常、服务器错误异常;并等待服务器完成写操作。
    WriteConcern.MAJORITY: 抛出网络错误异常、服务器错误异常;并等待一个主服务器完成写操作。
    WriteConcern.FSYNC_SAFE: 抛出网络错误异常、服务器错误异常;写操作等待服务器将数据刷新到磁盘。
    WriteConcern.JOURNAL_SAFE:抛出网络错误异常、服务器错误异常;写操作等待服务器提交到磁盘的日志文件。
    WriteConcern.REPLICAS_SAFE:抛出网络错误异常、服务器错误异常;等待至少2台服务器完成写操作

接着我们通过 update() 方法来更新标题(title):

>db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })   # 输出信息

以上语句只会修改第一条发现的文档,如果你要修改多条相同的文档,则需要设置 multi 参数为 true

>db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}},{multi:true})

附:

  • db.collection.updateOne():向指定集合更新单个文档
  • db.collection.updateMany():向指定集合更新多个文档
  • 只更新第一条记录:
    db.col.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } );
  • 全部更新:
    db.col.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true );
  • 只添加第一条:
    db.col.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false );
  • 全部添加进去:
    db.col.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true );
  • 全部更新:
    db.col.update( { "count" : { $gt : 15 } } , { $inc : { "count" : 1} },false,true );
  • 只更新第一条记录:
    db.col.update( { "count" : { $gt : 10 } } , { $inc : { "count" : 1} },false,false );

1.3.2 save() 方法

save() 方法通过传入的文档来替换已有文档,_id 主键存在就更新,不存在就插入。语法格式如下:

db.collection.save(
   <document>,
   {
     writeConcern: <document>
   }
)

参数说明:

  • document : 文档数据。
  • writeConcern :可选,抛出异常的级别。
    实例
    以下实例中我们替换了_id56064f89ade2f21f36b03136 的文档数据:
db.col.save({
    "_id" : ObjectId("56064f89ade2f21f36b03136"),
    "title" : "MongoDB",
    "description" : "MongoDB 是一个 Nosql 数据库",
    "by" : "myself",
    "url" : "http://www.test.com",
    "tags" : [
            "mongodb",
            "NoSQL"
    ],
    "likes" : 110
})

1.3.3 原子操作命令

MongoDB原子操作常用命令,如:$set$unset$inc

  • $set
    用来指定一个键并更新键值,若键不存在并新增该字段
    { $set : { field : value } }
  • $unset
    指定key,用来删除一个键。值是多少都不影响。好像并非真的删除,只是把它置为null
    { $unset : { field : 1} }
  • $inc
    $inc可以对文档的某个值为数字型(只能为满足要求的数字)的键进行增减的操作。
    { $inc : { field : value } }
    db.test.update({hometown:"蒙古"},{$inc:{age:2}}) age字段自增2
  • $push
    数组末尾追加一个元素
    用法:{ $push : { field : value } },会把value追加到field里面去,field一定要是数组类型才行,如果field不存在,会新增一个数组类型加进去。
    db.test.update({hometown:"蒙古"},{$set:{list:[1,2,3,4,5]}}) 新增一个列表
    db.test.update({hometown:"蒙古"},{$push:{list:6}}) 追加元素
  • $pushAll
    $push,只是一次可以追加多个值到一个数组字段内。
    { $pushAll : { field : value_array } }
  • $pull
    从数组field内删除一个等于value值,如果有多个相同元素,会全都被删除
    db.test.update({hometown:"蒙古"},{$pull:{list:6}})
  • $addToSet
    增加一个值到数组内,而且只有当这个值不在数组内才增加。
  • $pop
    删除数组的第一个最后一个元素,值只能选1-1
  • $rename
    修改字段名称
    { $rename : { old_field_name : new_field_name } }
  • $bit
    位操作,integer类型
    {$bit : { field : {and : 5}}}

1.3.4 位置操作符

1.3.4.1 位置操作符$

位置操作符$,如果不知道数组中元素的位置,可以使用位置$操作符
位置$操作符充当更新文档查询中第一个匹配的占位符,即使用了multi:true也没用
$可以在不显示指定数组元素位置的情况下标识要更新的数组中的元素,$只是单个占位符
.$[].会更新数组内全部元素,可以多个。.$.只会更新符合查询条件的数组内的元素,有且只能有一个

先查询
t.find() 
 { "_id" : ObjectId("4b97e62bf1d8c7152c9ccb74"), "title" : "ABC", "comments" : [ { "by" : "joe", "votes" : 3 }, { "by" : "jane", "votes" : 7 } ] }
更新 
t.update( {'comments.by':'joe'}, {$inc:{'comments.$.votes':1}}, false, true )
再查询 
t.find() 
{ "_id" : ObjectId("4b97e62bf1d8c7152c9ccb74"), "title" : "ABC", "comments" : [ { "by" : "joe", "votes" : 4 }, { "by" : "jane", "votes" : 7 } ] }

1.3.4.2 位置操作符$[]

位置操作符$[],要更新数组中的所有元素
查询条件匹配的情况下,$[]会修改指定数组字段中的所有元素
因为$[]修改整个数组。所以无需在查询条件中指定数组
注:3.6版本后的新功能

语法格式如下:

db.collection.updateMany(
   { <query conditions> },
   { <update operator>: { "<array>.$[]" : value } }
)

案例:

插入
db.stu.insert({_id:1,grades:[80,85,90]})
db.stu.insert({_id:2,grades:[88,90,92]})
db.stu.insert({_id:3,grades:[85,100,90]})
更新:
db.stu.update({grades:85},{$set:{'grades.$[]':'修改'}},{multi:true})

1.3.4.3 位置操作符$[< identifier >]

会使用一个或多个数组作为过滤条件进行匹配
在monodb3.6版本后才可使用
过滤后的位置运算符$[<identifier>]标识与arrayFilters条件匹配的数组元素来进行更新操作。
位置$[identifier]运算符充当数组字段中arrayFilters中指定条件匹配的所有元素的占位符

语法:

db.collection.update(
{ <update operator>: { "<array>.$[<identifier>]" : value } },
{ arrayFilters: [ { <identifier>: <condition> } ] }
)
或者:
db.collection.update(
   { <query selector> },
   { <update operator>: { "array.$[<identifier>].field" : value } },
   { arrayFilters: [ { <identifier>: <condition> } } ] }
)

注意:在<identifier>必须以小写字母开头,并且只包含字母数字字符

1.3.4.4 $elemMatch()

位置操作符$能够更新第一个匹配的数组元素,但是通过$elemMatch()操作符匹配多个内嵌文档的查询条件
考虑如下的stu集合文档grades字段是一个嵌套字段的文档

{
  _id: 4,
  grades: [
     { grade: 80, mean: 75, std: 8 },
     { grade: 85, mean: 90, std: 5 },
     { grade: 90, mean: 85, std: 3 }
  ]
}

如下语句会更新嵌套文档中的std值为6,条件是文档的主键是4,字段grades的嵌套文档字段grade字段值小于等于90mean字段值大于80

db.students.update(
   {
     _id: 4,
     grades: { $elemMatch: { grade: { $lte: 90 }, mean: { $gt: 80 } } }
   },
   { $set: { "grades.$.std" : 6 } }
)

1.4 MongoDB 删除文档

MongoDB remove() 函数是用来移除集合中的数据。
MongoDB 数据更新可以使用 update() 函数。在执行 remove() 函数前先执行 find() 命令来判断执行的条件是否正确

db.collection.remove(
   <query>,
   <justOne>
)

参数说明:

  • query :(可选)删除的文档的条件。
  • justOne : (可选)如果设为 true1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。

但是remove()方法已经过时了,现在官方推荐使用 deleteOne()deleteMany() 方法。

删除集合下全部文档:
db.test.deleteMany({})

删除 status 等于 A 的全部文档:
db.test.deleteMany({ status : "A" })

删除 status 等于 D 的一个文档:
db.test.deleteOne( { status: "D" } )

标签:1.3,MongoDB,db,update,更新,DML,文档
From: https://www.cnblogs.com/jingzh/p/16860934.html

相关文章

  • MongoDB基础之查询文档操作
    目录1查询操作1.1定义1.2查询操作1.2.1pretty1.2.2MongoDB与RDBMSWhere语句比较1.2.3MongoDBANDOR条件1.2.3.1AND条件1.2.3.2OR条件1.2.3.3AND和OR联合......
  • MongoDB基础之分组聚合函数讲解
    目录1分组聚合1.1概念定义1.2聚合操作1.2.1$match筛选1.2.2$project映射1.2.2.1自定义字段1.2.2.2起别名1.2.2.3引用原字段:$字段名1.2.2.4使用算术表达式1.2.2.5......
  • MongoDB基础之索引分析
    目录1索引1.1定义1.2创建索引1.3查看删除索引1.4查询分析1.4.1索引分析explain1.4.2强制使用索引hint1.5嵌套索引1.5.1索引数组字段1.5.2索引子文档字段1.6全......
  • PyTorch笔记:Modules官方文档
    来自https://pytorch.org/docs/stable/notes/modules.htmlASimpleCustomModuleimporttorchfromtorchimportnnclassMyLinear(nn.Module):def__init__(se......
  • 如何设计良好的技术项目文档结构
    转载:https://www.cnblogs.com/imyalost/p/16010362.html思维导图一般来说技术项目可以分为四大阶段,本篇文章我会从四个阶段分别来介绍,在不同阶段需要设计哪些项目文档。......
  • robotframework自动化测试框架实战教程:测试数据文档工具(Testdoc)
    生成文档的数据源可以是单个文件,单个目录,也可以是多个文件和目录.所有这些情况,最后那个参数都必须是最终文档输出要写入的文件.基本用法python-mrobot.testdoc......
  • linux kernel相关文档
    https://www.kernel.org/doc/html/latest/index.htmlhttps://docs.kernel.org/index.html上面两个网站都指向同个网页......
  • mongodb 导出操作
    我的是备份数据库,链接到数据库服务器来备份的终端shell命令实现远程连接服务器:mongo-host10.202.***.**-port27017--authenticationDatabasexz**导出远程服......
  • Spring Data MongoDB--MongoTemplate查询数据--方法/实例
    简介说明        本文用示例介绍SpringDataMongoDB(MongoTemplate)查询数据的方法。查询方法分类mongoTemplate.find //返回listmongoTemplate.findOne //返回1......
  • Java MySQL Spring Struts Hibernate 动漫论坛的设计与实现文档 毕设实训实验
    JavaMySQLSpringStrutsHibernate动漫论坛的设计与实现文档实训实验能满足学习和二次开发可以作为熟悉Java的学习,作为老师阶段性学习的一个成功检验不再是单调的理解......