资讯专栏INFORMATION COLUMN

MongoDB(二):基础知识

kumfo / 860人阅读

摘要:数据库名必须是满足以下条件的字符不能是空字符串数据库名应该区分大小写,即便是在不区分大小写的系统也是如此。接下来的两个字节来自产生的进程的进程标识符。注意这种方法不能保护数据库免受恶意用户的攻击,只能预防自己的手误。

MongoDB的基本概念

文档是MongoDB中数据的基本单元,非常类似于关系型数据库管理中的行,但更具表现力。

集合可以看作是一个拥有动态模式的表。

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

每个文档都有一个特殊的键_id,这个键在文档所属的集合中是唯一的。

MongoDB自带了一个简单但功能强大的JavaScript shell,可用于管理MongoDB的实例或者数据操作。

文档

文档是MongoDB的核心概念。文档就是键值对的一个有序集。例如在 JavaScript 里面,文档就被表示为对象:

{"greeting": "Hello,World!"}

但是大多数的文档会被这个简单的例子复杂的多,通常会表现为多个键/值对:

{"greeting": "Hello,World!", "foo": 3}

从上面的例子可以看书,文档值可以是多种不同的数据类型。

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

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

.$具有特殊的意义,只能在特定的环境下使用。

而且MongoDB不但区分类型,而且区分大小写,下面的每组的两个文档都是不同的:

{"foo": 3}
{"foo": "3"}
{"foo": 3}
{"Foo": 3}

还有一个重要的事情需要注意,就是MongoDB的文档不能有重复的键,例如下面的就是违法的:

{"greenting": "Hello, World!", "greenting": "Hello, MongoDB!"}
集合 动态模式

集合是动态模式的,所以任何文档都可以存在同一个集合里面:

{"greenting": "Hello, World!"}
{"foo": 5}

既然集合里面可以放置任何文档,随之而来的一个问题就是,还有必要使用多个集合吗:

各种各样的文档放到一个集合里面,对于开发者和管理员来说不方便管理。

在一个集合里面查询特定类型的文档在速度上不划算,分开查询速度则快得多。

把同种类型的集合放到一个集合里面,数据会更加集中。

创建索引时,因为一个集合中只放入一种类型的文档,可以更加有效的对集合进行索引。

命名

集合名需要时满足下列条件的任意UTF-8字符串:

集合名不能是空字符串("")

集合名不能包含字符

集合名不能以system.开头

集合名中不能包含保留字符$

数据库

在MongoDB中,多个文档组成集合,多个集合可以组成数据库。
数据库名必须是满足以下条件的UTF-8字符:

不能是空字符串("")

数据库名应该区分大小写,即便是在不区分大小写的系统也是如此。简单起见,数据库名应该全部小写。

数据库名最多应为64字节。

因为数据库最终会变为文件系统里的文件,而数据库名则就是相应的文件名。这也是数据库名有这么多限制的原因。
但是一些数据库的名字是保留的,比如adminlocalconfig

启动MongoDB服务器
service mongod start

默认情况下,MongoDB的监听端口默认是27017。

启动Mongo客户端
mongo

但是这个你要确保你的恶服务器已经启动了。这样就会自动进行连接MongoDB服务器了。
这个 shell 工具其实是一个功能完备的 JavaScript 解释器。可以运行任意的 JS 程序。

基础命令
db # 查看当前选择的数据库
show dbs # 查看当前服务器的数据库列表
use footer # 选择数据库

当选定数据库之后,系统会将数据库连接赋值给全局变量db。这个变量就是通过 shell 访问 MongoDB 的主要入口点。
例如,通过db.baz可返回当前数据库的baz集合。

基本操作 创建
post = {"title": "My Blog Post", "content": "Here"s my blog post.", "data": new Date()}
db.blog.insert(post)

这个插入的数据是一个 JavaScript 对象。它有这么几个键:titlecontentdate。在查询的时候,我们会看到有一个额外的_id,这个会在下面进行解释。

查找

查找多个文档

db.blog.find()

查找单个文档

db.blog.findOne()

findfindOne都接受一个查询文档作为限定条件。使用find的时候,shell会自动显示最多20个匹配的文档。

更新

例如:给先前的数据增加一个comments键:

post.comment = []
db.blog.update({"title": "My Blog Post"}, post)

update至少接受两个参数,第一个参数是限定条件,用于匹配要更新的文档。第二个是要更新的文档。
然后我们在db.blog.find()就可以看到新的键

删除

使用remove()方法可以将文档从数据库中永久删除。但是如果没有指定任何条件,那么则会删除集合内的所有文档。也可以接受一个限定条件作为参数:

db.blog.remove({"title": "My Blog Post"})

现在集合又是空的了。

_idObejctId

MongoDB中存储的数据必须有一个_id键。这个键的值可以是任何类型的。默认是一个 Object 对象。在一个集合里面,每个文档都有一个唯一的_id,类似MySQL的自增ID。

ObejctId

在设计MongoDB的时候,初衷就是用作分布式数据库,所以能够在分片的环境中生成唯一的标识符就非常的重要。
ObejctId使用12字节的存储空间,是一个由24个十六进制数字组成的字符串。
ObjectId的12字节,按照如下方式生成:

前4个字节是从标准纪元开始的时间戳,单位为秒。因为使用的是当前时间,所以很担心是否要对服务器进行时钟同步。这确实是一个好主意。但是时间戳的实际值并不重要,因为只要它总是不停的增加就好了。

接下来的3个字节是所在主机的唯一标识符。通常是机器主机名的散列值。这样可以确保不同主机生成不同的ObjectId。不产生冲突。

接下来的两个字节来自产生ObjectId的进程的进程标识符(PID)。

前9个字节保证了同一秒钟不同机器不同进程产生的ObjectId是唯一的。最后3字节是一个自动增加的计数器。确保相同进程同一秒产生的ObjectId也是不一样的。

自动生成_id

如果插入文档时没有_id键,系统会帮你自动创建一个。可以由服务器来做这种事情。但是通过会在客户端由驱动程序完成。这样则减轻了数据库扩展的负担。

使用MongoDB shell

使用下面的方式连接到其他的任何MongoDB实例

mongo host:port/db

这样就连接到host(IP地址),端口是port上的db(此处可以更换为你要连接的数据库)了。

这样启用之后,就不会连接到任何数据库

mongo --nodb

在启动之后,可以使用new Mongo(hostname)命令来选择想要连接到的Mongod了。

conn = new Mongo(host:port)
db = conn.getDB("db")

执行这些命令之后,就可以像平常一样使用db了。

我们可以通过下面的功能来查看帮助手册

help

如果想要知道一个函数是做什么用的,可以直接在shell中输入函数名,但是不要加括号

db.foo.update
使用shell执行脚本

比如:

mongo script1.js script2.js script3.js

亦或者:

mongo --quiet host:port/db script1.js script2.js script3.js

--quiet 命令则是让mongo不要打印"MongoDB shell version ……"的提示了。

或者在交互式shell中运行脚本

load("script1.js")

然而在脚本中,shell辅助函数则是不能使用的。所以我们需要使用辅助函数对应的JS函数:

辅助函数 等价函数
use foo db.getSisterDB("foo")
show dbs db.getMongo().getDBs()
show collections db.getCollectionNames()
创建.mongorc.js文件

这个文件会在启动 shell 时自动运行。一般来说创建此脚本的作用是创建一些自己需要的全局变量,或者为太长的名字创建比较比较短的别名,或者重写内置函数,最常见则是移除一些比较“危险”的 shell 内置函数。注意这种方法不能保护数据库免受恶意用户的攻击,只能预防自己的手误。启动 mongo时指定--norc参数,就可以禁止加载.mongorc.js

var no = function(){
    print("Not on my watch");
};
db.dropDatabase = DB.prototype.dropDatabase = no; //禁止删除数据库
DBCollection.prototype.drop = no; //禁止删除集合
DBCollection.prototype.dropIndex = no; //禁止删除索引

当需要编辑大块的代码或者对象的时候,我们可以指定编辑器,然后我们可以在编辑器内进行编辑:

// .mongorc.js
EDITOR = "/usr/bin/vim";

比如在 mongo shell 中:

>var wap = db.books.findOne({title: "War and Peace"})
>edit wap

修改完成之后,保存并退出编辑器。变量就会重新解析然后加载回 shell。

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

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

相关文章

  • 《聊聊mongodb》系列 mongoDB存储结构以及基础的shell命令

    摘要:进入数据库,然后查看拥有的集合查看当前操作的数据库,以及数据库版本,连接及端口号以下部分为创建数据库,我们刚创建的数据库并不在数据库的列表中,要显示它,我们需要向数据库插入一些数据。 跟着上一节,我们简单了解了下,什么是mongoDB? 这一节,我们简单的了解下mongodb的存储结构以及基础的shell命令。 一、mongodb的存储结构 接触mongodb之前,我们使用的都是关系型...

    Jacendfeng 评论0 收藏0
  • 两年了,我写了这些干货!

    摘要:开公众号差不多两年了,有不少原创教程,当原创越来越多时,大家搜索起来就很不方便,因此做了一个索引帮助大家快速找到需要的文章系列处理登录请求前后端分离一使用完美处理权限问题前后端分离二使用完美处理权限问题前后端分离三中密码加盐与中异常统一处理 开公众号差不多两年了,有不少原创教程,当原创越来越多时,大家搜索起来就很不方便,因此做了一个索引帮助大家快速找到需要的文章! Spring Boo...

    huayeluoliuhen 评论0 收藏0
  • Docker入门()在docker使用MongoDB

    摘要:本文将介绍如何在中使用。如果你是一名的初学者,那么你入门的第一件事就是安装,但是安装又不是一件简单的事情,还需要自己配置一些服务。这时候,就能帮上大忙,它能够让你不需要本地安装就能使用。下面让我们来看看这是怎么实现的。   本文将介绍如何在docker中使用MongoDB。  如果你是一名MongoDB的初学者,那么你入门MongoDB的第一件事就是安装MongoDB,但是安装Mong...

    gaomysion 评论0 收藏0
  • 《聊聊mongodb》系列三 了解一下MongoDB插入文档的操作~

    摘要:布尔类型,表示文档是否按照有序或者无序插入,默认是返回参数返回了含有操作状态的对象插入文档成功返回如下对象字段指明了插入文档的总数如果该操作遇到了错误对象将包含该错误信息例子四其它可以向集合中添加文档的方法和选项一起使用的。 上一节介绍了MongoDB的基本的命令,以及结构的了解,这一节的主题是介绍一下MongoDB的插入文档的操作的基础命令的使用,MongoDB当中文档的数据结构和j...

    ityouknow 评论0 收藏0

发表评论

0条评论

kumfo

|高级讲师

TA的文章

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