资讯专栏INFORMATION COLUMN

MongoDB权威指南读书笔记(一)

sixleaves / 433人阅读

摘要:如果没有找到找到符合条件的文档,就会以这个条件和更新文档为基础新建一个新的文档。使用它可以快速方便的对文档进行更新。更新多个文档默认情况下,文档的更新只针对第一个匹配到的文档,多个条件符合时,其它文档不会改变。

what is MongoDB ?
面向文档的数据库

不再有行的概念,不再有预定义模式

易于拓展

丰富的功能

索引

聚合

特殊的集合类型

文件存储

高性能

可以一个示实例拥有多个相互独立的数据库,每个数据库拥有自己的集合

文档(document)
数据的基本单元,键值对的有序集

文档格式:
{ "foo" : "3" }

每个文档都有一个特殊的键 "_id" ,这个键在文档中是唯一的

文档的值可以是不同的类型,使用类似 json 的语法来存储数据

文档的键是字符串,除了少数情况,键可以使用任意 UTF-8 字符

键不能含有 (空字符),这个符号用来表示键的结尾

.$有特殊含义,只能在特定情况下使用

MongoDB不但区分·类别,而且区分大小写

文档中不能有重复的键

文档的键值对是有序的,但通常字段顺序·不重要

集合(collection)
一组文档的集合,可以看做有动态模式的表
动态模式

具有动态的模式的集合中,文档可以是各式各样的

例如下面两个文档可以存储在同一个集合里面:
{ "greeting" : "Hello, world" } , { "foo" : 5 }

把同类型的文档放在一个集合里,数据会更加集中

在集合中只放入一种类型的文档,可以更有效地对集合进行索引

命名
集合使用命名进行标识,集合名可以是以下任意UTF-8字符串

集合名不能为空字符串""

集合名不能包含字符,它表示集合名的结束

集合名不能以stystem.开头,这是因为它是系统保留的前缀

集合名不能包含$符号,因为系统生成的集合中包含$

子集合

使用.分隔命名空间的子集合,用来高效、简洁的组织数据

数据库

MongoDB中,一个实例可以承载多个数据库,每个数据库可以有零个或多个集合

每个数据库拥有独立权限,不同的数据库存储在不同的文件中

数据库名区分大小写,简单起见,数据库名全部小写,其它与集合命名方式类似

MongoDB的保留数据库名:

admin
用户权限,特定服务端命令

local
不可复制,用于储存服务器本地集合

config
用于分片设置

启动MongoDB
$ mongod --dbpath E:mongodb

终止 在shell中按下 Ctrl + C

MongoDB shell 运行
$ mongo
连接其他计算机上的mongod实例
$ mongo host:30000/myDB
不连接到任何mongod实例
$ mongo --nodb

shell可以运行绝大多数的JavaScript程序

多行输入时会进入未输入完成的状态,连续三次回车强制退出

MongoDB客户端

MongoDB shell是一个独立运行的MongoDB客户端

启动时,shell连接到test数据库,并将数据库连接赋值给全局变量db

显示当前数据库
> db
test
显示所有数据库
> show databases
使用数据库user
> use user
shell的基本操作 创建
> post = {
    "content":"here is my blog",
    "date":new Date()
}
增加
> post = { "content":"here is my blog",  "date":new Date() }
> db.blog.insert(post)
查找

所有

> db.blog.find() 

第一个

> db.blog.findOne() 
更新
> db.blog.update({"content":"here is my blog"},"here")
删除
> db.blog.remove({"content":"here"})
基本数据结构

null
null 用于表示空值或者不存在的字段

布尔型
布尔型有两个值true和false

数值

shell默认使用64浮点数值

整型数值可以使用NumberInt()(4字节带符号整型)或者NumberLog()(8字节带符号整型)

字符型
UTF-8字符串

日期
新纪元以来的毫秒数,不存储时区

正则表达式
和JavaScript正则语法相同

数组

内嵌文档

{"x":{"foo":"bar"}}

对象id

{"x":ObjectId()}

二进制数据

代码

{"x":function(){}}

_id 和 ObjectId _id

MongoDB文档必须有一个"_id"键,这个键可以是任意类型,默认是一个ObjectId对象

每个文档都有一个唯一的"_id"作为它的标识,同一个集合中的"_id"不能相同

ObjectId

由24个16位进制数字组成的字符串

前四位-时间戳 五到八-机器码 七和八位-进程标识符(PID) 九到十一-计数器

集合命名注意事项

db.version 是 db 的一个方法,用来返回当前服务器的版本

访问version数据库必须使用db.getCollection("version");

可以使用对象访问特殊命名集合或数据库

例如 db.blog[collection_name] db[db_name].find()

删除更新、和删除文档 插入新的文档
> db.foo.insertOne({"bar":"baz"})

这个操作会新建一个文档,自动新增"_id"键,然后保存到MongoDB中

批量插入
> db.foo.insert({"_id":1},{"_id":2},{"_id":3})

如果其中有一个文档插入失败,这个文档及其之后的所有文档失败,之前的文档依旧插入

批量文档
> db.foo.remove({})

option中可以传入条件,符合条件的数据将会被删除

删除集合
> db.foo.drop()

删除集合比删除所有文档的速度更快

文档替换

一个常见的问题:
查询条件匹配到了多个文档然后更新于第二个参数的存在就产生重复的_id值,数据库会抛出异常,所有文档都不会更新

正确的更新方法:

> db.people.update( { "_id" : ObjectId("4b3b9f67a1f631733d917a7c") } , joe )
使用文档修改器

$set修改器

设定一个键不存在就创建它,存在更新键对应的值,它还可以改变值的类型

$inc修改器

增加已有键的值,键不存在就创建一个

必须是数字类型,不能增加其它类型的值,修改其它类型请使用$set或者数值修改器

$unset修改器

删除一个键使用它

数值修改器

$push已有数组末尾加入一个元素,没有就创建一个新数组

$slice的值必须是负数,它会限制数组最多有多少元素

$addToSet可以避免重复插入值

删除数组中的元素
特定元素

> db.foo.insert({"arr":["a","b"]})
> db.foo.update({},{"$pull":{"arr":"a"}})

$each批量更新数组

> db.foo.update({"_id":ObjectId("5bf7f5ab1fcca531779d012d")},{"$push":{"hourly":{"$each":[5,2,3,4]}}} 

修改器速度

将文档插入数据库中时,依次插入的文档在磁盘上的位置是相邻的。
因此如果一个文档变大了,原来的位置放不下这个文档时,它会被移动到集合的另一个位置。
当MongoDB不得不移动一个文档时,它会创建一个,它会修改集合的填充因子(padding factor)
填充因子: MongoDB为每个新文档预留的增长位置

查看填充因子

> db.coll.stats()

注意:
删除、修改、增加都要使用$修改器,否则会将整个文档替换,例子:

> db.people.update( criteria , { "foo" : "bar" } )

这会使整个文档用{"foo":"bar"}替换

提高磁盘复用率

如果你的集合在进行插入和删除时会进行大量的移动或者是经常打乱数据,可以实用usePowerOf2Sizes选项提高磁盘复用率。

> db.runCommand({"collMod":collectionName,"usePowerOf2Sizes":true})

这个选项会导致之后所有的空间分配都是2的幂,使得空间分配不再这么高效。

upsert

​ 如果没有找到找到符合条件的文档,就会以这个条件和更新文档为基础新建一个新的文档。如果找到了匹配的文档,则正常更新。不必预置集合,同一个代码既可以创建文档又可以更新文档。

> db.foo.update({ "url" : "/blog"}, {"$inc" : { "pageviews" : 1 }}, true)

update的第三个参数就是个upsert

$setOnInsert

创建文档同时创建字段为它赋值,之后所有的更新操作这个字段的值不再改变。

> db.foo.update({}, {"$setOnInsert" : { "createdAt" : new Date() }}, true)

​ 通常不需要保留createAt创建时间这样的字段,因为ObjectId中包含了创建时的时间戳,但是在预置或者初始化计数器时或者不使用ObjectId的集合来说,$setOnInsert是非常有用的

save shell

​ 若文档不存在创建,存在更新。它只有一个参数:文档,如果包含_id键,save会调用upsert,否则会调用insert。使用它可以快速、方便的对文档进行更新。

> var x = db.foo.findOne()
> x.num = 42
> db.foo.save()
更新多个文档

​ 默认情况下,文档的更新只针对第一个匹配到的文档,多个条件符合时,其它文档不会改变。若想同时跟新多个文档可以将update的第四个参数设为true

> db.users.update({"birthday":"10/13/1988"},{"$set":{"gift":"Happy Brithday!"}}, false , true)

这样就给所有生日是1998年10月13的用户添加了礼物gift

如果想获得跟新了多少文档可以运行getLastError命令

> db.runCommand(getLastError:1)
{
    "err" : null,
    "updatedExisting" : true,
    "n" : 5,
    "ok" : true
}
返回被更新的文档
> db.runCommand("findAndModify ": "processes", "query" : {"status" : "READY"}, "sort":{"priority" : -1}, "update":{"$set" : "RUNNING"})
{
    "ok" : 1,
    "value" : {
       "_id" : ObjectId("4b3e7a18005cab32be6291f7"),
       "priority" : 1,
       "status" : "READY",
    }
}

返回的文档是更新前的值,但实际的文档依旧更新

写入安全机制

应答式写入

数据库会给出响应,告诉你写入操作是否成功执行

非应答式写入

不返回任何响应,无法得知写入是否成功

手动强制shell中进行检查,检查最后一次操作中的错误

> db.getLastError()
引用

[1] MongoDB权威指南

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/17840.html

相关文章

  • MongoDB权威指南读书笔记

    摘要:如果没有找到找到符合条件的文档,就会以这个条件和更新文档为基础新建一个新的文档。使用它可以快速方便的对文档进行更新。更新多个文档默认情况下,文档的更新只针对第一个匹配到的文档,多个条件符合时,其它文档不会改变。 what is MongoDB ? 面向文档的数据库 不再有行的概念,不再有预定义模式 易于拓展 丰富的功能 索引 聚合 特殊的集合类型 文件存储 高性能 可以一个示...

    forrest23 评论0 收藏0
  • MongoDB权威指南读书笔记

    摘要:如果没有找到找到符合条件的文档,就会以这个条件和更新文档为基础新建一个新的文档。使用它可以快速方便的对文档进行更新。更新多个文档默认情况下,文档的更新只针对第一个匹配到的文档,多个条件符合时,其它文档不会改变。 what is MongoDB ? 面向文档的数据库 不再有行的概念,不再有预定义模式 易于拓展 丰富的功能 索引 聚合 特殊的集合类型 文件存储 高性能 可以一个示...

    Barrior 评论0 收藏0
  • 《JavaScript 权威指南读书笔记 1 - 简介

    摘要:原文第一章主要介绍的大概情况基本语法。通过和来引用对象属性或数组元素的值就构成一个表达式。 原文:https://keelii.github.io/2016/06/16/javascript-definitive-guide-note-0/ 第一章 主要介绍 JavaScript 的大概情况、基本语法。之前没有 JavaScript 基础的看不懂也没关系,后续章节会有进一步的详细说明...

    sydMobile 评论0 收藏0
  • 从小白程序员路晋升为大厂高级技术专家我看过哪些书籍?(建议收藏)

    摘要:大家好,我是冰河有句话叫做投资啥都不如投资自己的回报率高。马上就十一国庆假期了,给小伙伴们分享下,从小白程序员到大厂高级技术专家我看过哪些技术类书籍。 大家好,我是...

    sf_wangchong 评论0 收藏0
  • 读书笔记:编写高质量javascript的68个方法

    摘要:第条尽量少使用全局对象避免声明全局变量尽量声明局部变量避免对全局变量增加属性第条始终声明局部变量第条避免使用语句第条熟练使用闭包的函数值包含了比调用他们时执行所需要的代码还要更多的信息。那些在其所涵盖的作用域内跟踪变量的函数称为闭包。 书还没看完。一遍看,一遍写读书笔记。 这本书的序是JavaScript之父Brendan Eich写的,作者是JavaScript标准化委员会专家。可想...

    Vicky 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<