MongoDB学习笔记之文档操作

一、插入文档

新增单个文档

3.2版本后新增db.collection.insertOne()和db.collection.insertMany().

insertOne:支持writeConcern

db.collection.insertOne(

    <document>,
    {
        writeConcern: <document>

    }
)

writeConcern 决定一个写操作落到多少个节点上才算成功。

writeConcern 的取值包括:0:发起写操作,不关心是否成功

1:集群最大数据节点数:写操作需要被复制到指定节点数才算成功;

majority:写操作需要被复制到大多数节点才算成功。

insert: 若插入的数据主键已经存在,则会抛DuplicateKeyException异常,提示主键重复,不保存当前数据。

save:如果_id主键存在则更新数据,如果不存在则插入数据。

> use appdb
switched to db appdb
> db.emps.save({x:1})
WriteResult({ "nInserted" : 1 })
>db.emps.insert({x:2})
WriteResult({ "nInserted" : 1 })
>db.emps.insertOne({x:3})
{
    "acknowledged" : true,
    "insertedId" : ObjectId("565231212155ddfssssss11c")
}

批量新增文档

insertMany: 向指定集合中插入多条文档数据

db.collection.insertMany(

    [<document 1>,<document 2>,...],

    {
        writeConcern: <document>,
        ordered: <boolean>

    }


)

writeConcern: 写入策略,默认为1,即要求确认写操作,0是不要求。

ordered: 指定是否按顺序写入,默认为true,按顺序写入

insert和save也可以实现批量插入

> db.emps.insert({x:3},{y:5})
BulkWriteResult({
    "writeErrors" : [ ],
    "writeConcernErrors" : [ ],
    "nInserted" : 2,
    "nUpserted" : 0,
    "nMatched" : 0,
    "nModified" : 0,
    "nRemoved" : 0,
    "upserted" : [ ]
})

> db.emps.save([{x:3,y:0},{y:5,z:7}])
BulkWriteResult({
    "writeErrors" : [ ],
    "writeConcernErrors" : [ ],
    "nInserted" : 2,
    "nUpserted" : 0,
    "nMatched" : 0,
    "nModified" : 0,
    "nRemoved" : 0,
    "upserted" : [ ]
})

> db.emps.insertMany([{x:3,y:0},{y:5,z:7}])
{
    "acknowledged" : true,
    "insertedIds" : [
        ObjectId("61cfdfddfjkdfhdkss"),
        ObjectId("221212ddkfjdkfkkff")
    ]

}

测试插入30条随机数据

编辑脚本book.js

var tags = ["nosql","mongodb","document","popular","developer"];
var types = ["literature","novel","travel","sociality","technolgy"]; 
var books = [];
for(var i=0;i<50;i++){
    var typeIdx = Math.floor(Math.random()*types.length);
    var tagIdx = Math.floor(Math.random()*tags.length);
    var favCount = Math.floor(Math.random()*100);
    var book = {
        title : "book-"+i,
        type : types[typeIdx],
        tag : tags[tagIdx],
        favCount : favCount,
        author : "xxx"+i 
    };
    books.push(book);
}
db.books.insertMany(books);

进入mongo shell,执行

load("books.js");

二、查询文档

find查询集合中的若干文档。语法格式如下:

db.collection.find(query, projection)

query: 可选,使用查询操作符指定查询条件

projection: 可选,使用投影操作符指定返回的键。查询时返回文档中所有的键值,只需省略该参数即可(默认省略)。投影时,_id为1时,其他字段必须为1;_id是0的时候,其他字段可以是0;如果没有_id字段约束,多个其他字段必须同为0或同为1.

> db.books.find()

如果查询返回的条目数量较多,mongo shell则会自动实现分批显示。默认情况下每次只显示20条。可以输入it命令读取下一批。

findOne查询集合中的第一个文档。语法如下:

db.collection.findOne(query,projection)

如果你需要以易读的方式来读取数据,可以使用pretty()方法:

db.collection.find().pretty()

注意: pretty()方法以格式化的方式来显示所有文档。

三、条件查询

指定条件查询

#查询带有nosql标签的book文档
db.books.find({tag:"nosql"})
#按照id查询单个book文档
db.books.find({_id:ObjectId("6152455422115445551212122")})
#查询分类为"travel"、收藏数超过60个的book文档
db.books.find({type:"travel",favCount:{$gt:60}})

查询条件对照表
SQLMQL
a=1{a:1}
a<>1{a:{$ne:1}}
a>1{a:{$gt:1}}
a>=1{a:{$gte:1}}
a<1{a:{$lt:1}}
a<=1{a:{$lte:1}}
查询逻辑对照表
SQLMQL
a = 1 AND b = 1{a:1,b:1}或{$and:[{a: 1},{b: 1}]}
a = 1 OR b =1{$or:[{a: 1},{b: 1}]}
a IS NULL{a: {$exists: false}}
a IN (1,2,3){a: {$in: [1,2,3]}}

查询逻辑运算符

  1. $lt: 存在并小于
  2. $lte: 存在并小于等于
  3. $gt: 存在并大于
  4. $gte: 存在并大于等于
  5. $ne: 不存在或存在但不等于
  6. $in: 存在并在指定数组中
  7. $nin: 不存在或不在指定数组中
  8. $or: 匹配两个或多个条件中的一个
  9. $and: 匹配全部条件

四、排序&分页

指定排序:在MongoDB中使用sort()方法对数据进行排序

1为升序排列,而-1是用于降序排列

#指定按收藏数(favCount)降序返回
db.books.find({type:"travel"}).sort({favCount:-1})

 分页查询

skip用于指定跳过记录数,limit则用于限定返回结果数量。可以在执行find命令的同时指定skip、limit参数,依次实现分页的功能。比如,假定每页大小为8条,查询第3页的book文档;

db.books.find().skip(8).limit(4)

处理分页问题--巧分页

数据量大的时候,应该避免使用skip/limit形式的分页

替代方案:使用查询条件+唯一排序条件

例如:

第一页:db.posts.find({}).sort({_id:1}).limit(20);

第二页:   db.posts.find({_id:{$gt:<第一页最后一个_id>}}).sort({_id:1}).limit(20)

第三页:db.posts.find({_id:{$gt:<第二页最后一个_id>}}).sort({_id:1}).limit(20);

处理分页问题--避免使用count

尽可能不要计算总页数,,特别是数据量大和查询条件不能完整命中索引时。

考虑以下场景:假设集合总共有1000w条数据,在没有索引情况下考虑以下查询:

db.coll.find({x: 100}).limit(50);
db.coll.count({x:100});

前者只需要遍历前n条,直到找到50条x=100的文档即可结束。

后者需要遍历完1000w条找到所有符合要求的文档才能得到结果。为了计算总页数而进行的count()往往是拖慢页面整体加载速度的原因。

五、正则表达式匹配查询

MongoDB使用$regex操作符来设置匹配字符串的正则表达式。

//使用正则表达式查找type包含so字符串的book
db.books.find({type: {$regex:"so"}})
//或者
db.books.find({type:/so/})

六、更新文档命令

可以用update命令对指定的数据进行更新,命令格式如下:

db.collection.update(query,update,options)

1、query:描述更新的查询条件

2、update:描述更新的动作及新的内容;

3、options:描述更新的选项

(1)、upsert:可选,如果不存在update的记录,是否插入新的记录。默认false,不插入

(2)、multi:可选,是否按条件查询出的多条记录全部更新。默认false,只更新找到的第一条记录。

(3)、writeConcern:可选,决定一个写操作落到多少个节点上才算成功。

更新操作符

更新操作符命令
操作符格式描述
$set{$set:{field:value}}指定一个键并更新值,若键不存在则创建
$unset{$unset:{field:1}}删除一个键
$inc{$inc:{field:value}}对数值类型进行增减
$rename{$rename:{old_field_name:new_field_name}}修改字段名称
$push{$push:{field:value}}将数值追加到数组中,若数组不存在则会进行初始化
$pushAll{$pushAll:{field:value_array}}追加对个值到一个数组字段内
$pull${$pull:{field:_value}}从数组中删除指定的元素
$addToSet{$addToSet:{field:value}}添加元素到数组中,具有排重功能
$pop{$pop:{field:1}}删除数组的第一个或最后一个元素

更新单个文档

某个book文档被收藏了,则需要将该文档的favCount字段自增

db.books.update({_id:ObjectId("6125554666665123333")},{$inc:{favCount:1}})

更新多个文档

默认情况下,update命令只在更新第一个文档之后返回,如果需要更新多个文档,则可以使用multi选项。

将分类为"novel"的文档的增加发布时间(publishedDate)

db.books.update({type:"novel"},{$set:{publishedDate:new Date()}},{"multi":true})

multi:可选,mongodb默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。

 使用upsert命令

upsert是一种特殊的更新,则表现为如果目标文档不存在,则执行插入命令。

db.books.update(
    {title:"my book"},
    {$set:{tags:["nosql","mongodb"],type:"none",author:"fox"}},
    {upsert:true}
)

nMatched、nModified都为0,表示没有文档被匹配及更新,nUpserted=1提示执行了upsert动作

实现replace语义

update命令中的更新描述(update)通常由操作符描述,如果更新描述中不包含任何操作符,那么MongoDB会实现文档的replace语义

db.books.update(
    {title:"my book"},
    {justTitle:"my First book"}
)

findAndModify命令

findAndModify兼容了查询和修改指定文档文档的功能,findAndModify只能更新单个文档

//将某个book文档的收藏数(favCount)加1
db.books.findAndModify({
        query:{_id:Object("6112322122")},
        update:{$inc:{favCount:1}}
})

该操作会返回符合查询条件的文档数据,并完成对文档的修改

 默认情况下,findAndModify会返回修改前的“旧”数据。如果希望返回修改后的数据,则可以指定new选项

db.books.findAndModify({
    query:{_id:ObjectId("6123225551122333355211222")},
    update:{$inc:{favCount:1}},
    new: true
})

与findAndModify语义相近的命令如下:

1、findOneAndUpdate:更新单个文档并返回更新前(或更新后)的文档

2、findOneAndReplace:替换单个文档并返回替换前(或替换后)的文档

七、删除文档

使用remove删除文档

1、remove 命令需要配合查询条件使用

2、匹配查询条件的文档会被删除

3、指定一个空文档条件会删除所有文档

示例:

db.user.remove({age:28})//删除age,等于28的记录
db.user.remove({age:{$lt:25}})//删除age小于25的记录
db.user.remove({ })//删除所有记录
db.user.remove()//报错

remove命令会删除匹配条件的全部文档,如果希望明确限定只删除一个文档,则需要指定justOne参数,命令格式如下:

db.collection.remove(query,justOne)

例如:删除满足type:novel条件的首条记录

db.books.remove({type:"novel"},true)

使用delete删除文档

官方推荐使用deleteOne()和deleteMany()方法删除文档

db.books.deleteMany({})//删除集合下全部文档
db.books.deleteMany({type:"novel"})//删除type等于novel的全部文档
db.books.deleteOne({type:"novel"})//删除type等于novel的一个文档

注意:remove、deleteMany等命令需要对查询范围内的文档逐个删除,如果希望删除整个集合,则使用drop命令会更高效

返回被删除的文档

remove、deleteOne等命令在删除文档后只会返回确认性的信息,如果希望获得被删除的文档,则可以使用findOneAndDelete命令

db.books.findOndAndDelete({type:"novel"})

除了在结果中返回删除文档,findOneAndDelete命令还允许定义“删除的顺序”,即按照指定顺序删除找到的第一个文档

db.books.findOneAndDelete({type:"novel"},{sort:{favCount:1})

remove、deleteOne等命令只能按照顺序删除,利用这个特性,findOneAndDelete可以实现队列的先进先出。

文档操作的最佳实践:

关于文档结构

1、防止使用太长的字段名(浪费空间)

2、防止使用太深的数组嵌套(超过2层操作比较复杂)

3、不使用中文,标点符号等非拉丁字母作为字段名

关于写操作

1、update语句里只包括需要更新的字段

2、尽可能使用批量插入来提升写入性能

3、使用TTL自动过期日志类型的数据

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
大家这么喜欢,我就不要资源分了,改成0分了,我为我一己私利感到抱歉…… MongoDB学习手册 ......................................................................................................................... 1 说明.......................................................................................................................................... 2 一、 Mongodb简介 .......................................................................................................... 4 二、 MongoDB特性 ......................................................................................................... 5 适用场景: ....................................................................................................................... 5 不适用场景: ................................................................................................................... 6 三、 MongoDB的工作方式.............................................................................................. 6 四、 MongoDB的下载 ..................................................................................................... 8 五、 MongoDB的安装 ..................................................................................................... 9 六、 MongoDB数据类型................................................................................................ 12 1. Timestamp类型 ...................................................................................................... 12 2. ObjectId类型 .......................................................................................................... 12 3. 数据库关联 ............................................................................................................. 14 七、 GridFS文件系统 ..................................................................................................... 15 八、 索引 ......................................................................................................................... 16 九、 主(Master)/从(slave)数据库同步 ................................................................ 20 1. 建立主/从服务器 ................................................................................................... 20 2. 相关参数说明 ......................................................................................................... 21 3. Slave顶替Master ................................................................................................... 22 4. 切换Master/Slave角色 ......................................................................................... 22 5. 更新主服务器位置 ................................................................................................. 22 十、 MongoDB分片和集群............................................................................................ 24 1. 简单分片实例 ......................................................................................................... 24 2. 高级分片实例 ......................................................................................................... 29 十一、 数据库基本操作:增查删改 ............................................................................. 37 1. Insert ....................................................................................................................... 37 2. Query ....................................................................................................................... 38 3. Remove.................................................................................................................... 52 4. Update ..................................................................................................................... 53 十二、 Shell控制台 ........................................................................................................ 62 1. 执行.js文件 ............................................................................................................ 62 2. –eval ........................................................................................................................ 62 3. 脚本和互动的区别 ................................................................................................. 62 十三、 安全与认证 ......................................................................................................... 63 1) 开启安全认证 ......................................................................................................... 63 2) 添加用户 ................................................................................................................. 64 3) 认证 ......................................................................................................................... 64

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

30岁老阿姨

支持一下哦!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值