MongoDB由C/C++开发,是一种强大、灵活、可扩展的数据存储方式。它扩展了关系型数据库的众多有用功能,例如:辅助索引、范围查询和排序。MongoDB还内置了对MapReduce式聚合的支持,以及对地里空间索引的支持。
MongoDB容易上手,便于使用。
MongoDB是为快速开发互联网Web应用而设计的数据库系统。其数据模型和持久化策略就是为了构建高读、写吞吐量和高自动灾备伸缩性的系统。无论系统需要单个还是多个节点,MongoDB都可以提供高性能。
2007年由10gen的创业团队开发,最终形成了MongoDB项目,10gen公司也更名为MongoDB,Inc。
MongoDB的设计目标就是极简、灵活、作为Web应用栈的一部分。
MongoDB1.0发布于2009年11月。
MongoDB有以下几个特点:
MongoDB将数据记录存储为BSON文档,BSON文档是JSON文档的二进制表示,但它包含的数据类型多于JSON。
BSON文档是MongoDB中数据的基本单元,非常类似于关系型数据库管理系统中的行。同时也是MongoDB的核心概念。
多个键及其关联的值有序的放置在一起便是文档。每种编程语言表示文档的方法不太一样。
BSON文档的键有以下几条命名规则:
最大的BSON文档大小为16M。过大的文档,MongoDB提供了GridFS进行存储。
MongoDB在写操作之后保留文档字段的顺序,_id字段始终是文档中的第一个字段。更改字段名称可能会导致文档中字段的顺序重新排序。
2.6版本开始MongoDB主动保留文档中的字段顺序,2.6之前MongoDB没有主动保留文档中字段的顺序。
在MongoDB中,存储在集合中的每个文档都需要一个唯一的_id字段作为主键。如果插入的文档省略了该_id字段,MongoDB驱动程序会自动为该字段生成ObjectId类型作为其值。
_id字段具有以下功能:
_id常用的数据类型:
集合就是一组文档的合集。集合类似于关系型数据库中的表。
集合是无模式的,也就是说一个集合里面的文档可以是各式各样的。MongoDB对此没有做强制要求,让开发者更灵活。
没有模式的控制,那么设计文档以及集合,就成为一个重点。
我们应该将同类型的文档放在一个集合中,这样可以使数据更加集中,方便管理,同时方便创建索引。
MongoDB3.2版本开始加入了更新和插入操作期间强制执行集合的文档验证规则。
集合的命名有以下几点要求:
如果创建的集合中包含特殊字符,例如下划线、数字开头,那么要访问这个集合,要使用db.getCollection()方法。
集合命名空间的最大长度为120个字节。集合命名空间包含:数据库名称、点(.)分隔符和集合名称。
MongoDB3.6中增加了一个新功能,在featureCompatibilityVersion设置为3.6,可以为每个集合分配一个不可变的UUID,这个UUID在副本集的所有成员和分片集群张总的分片中保持一致。
MongoDB内部对集合的使用方式可以体现它的部分设计思想。
system.namespaces与system.indexes就属于系统集合。这两个都是标准的集合,但是MongoDB使用固定集合来做复制。
可以查询到当前数据库中定义的所有命名空间。
存储了当前数据库的所有索引定义。
组织集合的一种惯例是使用点(.)字符分开的按命名空间划分的子集合。
MongoDB中多个文档组成集合,同样多个集合可以组成数据库。一个MongoDB实例可以承载多个数据库,它们之间可视为完全独立的。每个数据库都有独立的权限控制,在磁盘上,不同的数据库会放置在不同的文件中。
把数据库的名字放到集合名前面,得到的就是集合的完全限定名,称为命名空间。
命名空间的长度不得超过121字节,在实际使用当中应该小于100字节。
数据库命名分两种情况,一种是Windows系统下,一种是Linux系统下。
MongoDB中的数据库名称不区分大小写,且长度要少于64个字符。
Windows系统下:
类Unix系统下:
注意:数据库名最终会变成文件系统里的文件名,这也就是有这些限制的原因。
有一些数据库是保留的,可以直接访问这些有特殊作用的数据库。
此数据库是权限数据库,也就是root数据库,将一个用户添加到这个数据库,那么这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
这个数据库永远不会被复制,可以用来存储限于本地单台服务器的任意集合。
当MongoDB用于分片设置时,config数据库在内部内部会使用,用于保存分片的相关信息。
在选择版本的时候要注意:
MongoDB的稳定版本用偶数次版本号来标记,例如:1.8、2.0和2.2这些是版本是稳定版本;1.9和2.1是开发版本,不应该在生产环境中使用。
参见博客:Windows下安装MongoDB
官方下载地址:https://www.mongodb.com/download-center/community
可以使用浏览器或者curl工具下载安装包:
curl https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.6.12.tgz mongo.tgz
tar –zxvf mongo.tgz
创建数据目录并授权:
mkdir –p /data/db/
chow `id –u` /data/db
/mongodbHome/bin/mongod
MongoDB默认使用27017端口,如果这个端口被占用,那么可以使用如下命令更改端口:
mongod --port 27018
注意命令中间是两个横杠。
指向存放数据文件的目录路径,默认是/data/db。每个mongod进程都需要独立的数据目录。
当mongod启动时,会在数据目录中创建mongod.lock文件,这个文件用于防止其他mongod进行使用该数据目录。如果使用同一个数据目录启动另一个MongoDB服务器,这会报错:
“Unable to acquire lock for lockfilepath:/data/db/mongod.lock.”
指向日志输出文件的路径。日志默认会输出在标准输出(stdout)里。
如果对文件夹有写权限的话,系统会在文件不存在时创建它。它会将已有文件覆盖掉,清除所有原来的日志记录。如果想要保留原来的日志,还需要使用--logappend选项。
将日志输出到日志文件中的模式,其值有true,表示追加输出,false表示覆盖输出,即每次都会将原有的日志文件删除,重新创建日志文件。
指定MongoDB监听端口,默认使用27017。
如果要运行多个mongod进程,则需要给每个进程指定不同的端口号,如果启动mongod时端口被占用,则报错:
“Address already in use for socket” 0.0.0.0:27017”
该标志将开启简单REST接口,增强服务器的默认Web控制台。Web控制台的默认端口号为mongodprot+1000,MongoDB使用了27017,那么Web控制台的端口则为28017。可以使用 http://localhost:28017 来获取数据库的管理信息。
(此项功能,本人暂时没有测试出来!)
关闭管理接口,和rest是相反选项。
让进程以守护进程方式运行。
指定启动要使用的配置文件,加载命令行未指定的额各种选项。
开启安全检查。开启之后,需要做安全相应的安全验证,才能对数据库进行操作。
指定mongod绑定的IP地址。
禁止服务端执行JavaScript代码。
以上配置信息也可以在配置文件中全部指定,创建一个新的文本文件:mongodb.conf,内容如下:
dbpath=/var/local/mongodb
logpath=/var/log/mongodb.log
port=27017
rest=true
fork=true
在启动mongod时,通过以下命令来使用配置文件:
mongod –f mongodb.conf
查看启动选项列表:
use admin
db.runCommand({getCmdLineOpts:1})
注意:
停止MongoDB服务有两种方式:
db.sutdownServer()
当mongod收到这两种操作的的指令时,会等到数据库当前运行的操作或者文件预分配完成,关闭所有打开的连接,将缓存的数据刷新到磁盘,最后才会停止服务。
注意:千万不要使用kill -9来强制关闭数据库,这样上述的稳妥关闭过程就不存在了,会导致数据丢失。
MongoDB Shell是一个基于JavaScript的工具,用于管理数据库和操作数据。
可执行文件mongo会加载Shell并连接到指定的mongod进程。MongoDB Shell的功能和MySQL Shell差不多,主要区别在于不使用SQL,大多数命令使用的是JavaScript表达式。
MongoDB JavaScript Shell能让你玩转数据,对文档、集合以及MongoDB的特殊查询语言有切实的体验。
启动Shell的命令如下:
mongo
shell会在启动时自动连接MongoDB服务器,所以在shell启动之前要保证mongod已经启动。如果启动时没有指定其他数据库,Shell会选择则名为test的默认数据库。
shell是一个功能完备的JavaScript解释器,可以运行任何JavaScript程序。也可以调用JavaScript的标准库,还可以定义和调用JavaScript函数。
例如:
#进行数学运算
>x = 200
200
>x / 5;
40
#调用标准库函数
>Math.sin(Math.PI / 2);
1
>new Date(“2019/8/21”);
ISODate("2019-08-20T16:00:00Z")
# 定义并调用函数
> function factorial (n) {
... if(n<=1) return 1;
... return n* factorial(n-1);
... }
> factorial(5);
120
注意:shell中可以使用多行命令,它会检测输入的JavaScript语句是否写完。
shell其实是一个独立的MongoDB客户端,开启的时候shell会连接到MongoDB服务器的test数据库,并将这个数据库了链接赋值给全局变量db,这个变量是通过shell访问MongoDB的主要入口点。
shell为了方便习惯于SQL shell的用户添加了一些语法糖,如下:
使用use命令切换或创建数据库。
use tutorial
在MongoDB中创建数据库并不是必须的操作,数据库与集合只有在第一次插入文档时才会被创建。这个行为与MongoDB对数据的动态处理方式是一致的;因为不用事先定义文档的结构,单独的集合和数据库可以在运行时被创建。
db变量此时就等于tutorial:
>db
tutorial
在shell中操作数据会用到4个基本操作:创建、读取、更新和删除(CRUD)。
MongoDB对文档的操作格式如下:
db.collcetion.method(操作符)
MongoDB中集合中存储的都是文档,文档需要使用JSON来表示,如下:
{username:”jones”}
该文档包含一个键值对,那么下面我们将它保存到users集合中:
>db.users.insert({username:”jones”})
#查看数据
> db.users.find()
{ "_id" : ObjectId("5ce51398177285a95d705d4f"), "username" : "jones" }
因为这是保存的第一个文档,所以insert()方法不仅保存了文档,而且还创建了users集合以及tutorial库,同时还给此文档添加了一个额外的键“_id”。这个字段可以认为是文档的主键。每个MongoDB文档都要求有一个_id,如果文档在创建时没有提供此字段,那么就会生成一个MongoDB对象ID并添加到文档里。这个字段全局唯一。
查看数据的方法是find(),如下:
> db.users.find()
{ "_id" : ObjectId("5ce51398177285a95d705d4f"), "username" : "jones" }
{ "_id" : ObjectId("5ce51477177285a95d705d50"), "username" : "smith", "country" : "Canada" }
find()方法会返回集合中所有的文档,findOne()方法只会返回一条文档:
> db.users.findOne();
{ "_id" : ObjectId("5ce51398177285a95d705d4f"), "username" : "jones" }
在使用find()方法时,shell自动显示最多20个匹配的文档。
所有更新文档的操作都要求至少有两个参数:第一个参数指明要更新的文档;第二个参数定义被选中的文档应该如何更新。
MongoDB中支持针对性更新(targeted modification),这是MongoDB独有特性中最具代表性的。这种更新操作默认只会更新一个文档。
例如:
#创建一个变量
> king = {username:"LongKing",
... age:21,
... gender:"man"}
{ "username" : "LongKing", "age" : 21, "gender" : "man" }
#将变量插入到集合中
> db.users.insert(king);
WriteResult({ "nInserted" : 1 })
#更改变量
> king.address = []
[ ]
#更新文档
> db.users.update({username:"LongKing"},king)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find();
{ "_id" : ObjectId("5ce51398177285a95d705d4f"), "username" : "jones" }
{ "_id" : ObjectId("5d5cb4bcbff45893172e233e"), "username" : "LongKing", "age" :
21, "gender" : "man", "address" : [ ] }
# 还可以进行如下的更新操作
> jones = db.users.findOne();
{ "_id" : ObjectId("5ce51398177285a95d705d4f"), "username" : "jones" }
> jones
{ "_id" : ObjectId("5ce51398177285a95d705d4f"), "username" : "jones" }
> jones.age = 18;
18
> jones
{
"_id" : ObjectId("5ce51398177285a95d705d4f"),
"username" : "jones",
"age" : 18
}
> db.users.update({username:"jones"},jones);
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find();
{ "_id" : ObjectId("5ce51398177285a95d705d4f"), "username" : "jones", "age" : 18 }
remove()方法用来从数据库中永久性地删除文档。该方法接受一个可选的查询选择器,只删除那些匹配选择器的文档。如果没有提供选择器,就删除集合中的所有文档。
例如:
db.users.remove({username:”jones”}) #删除名为jones的文档
db.users.remove() #清空集合
remove()方法此操作不会删除集合,它只是从集合中删除文档,哪怕是清空操作,也会保留集合。
shell本身内置了帮助文档,可以通过help命令查看。
> help
db.help() help on db methods
db.mycoll.help() help on collection methods
sh.help() sharding helpers
rs.help() replica set helpers
help admin administrative help
help connect connecting to a db help
help keys key shortcuts
help misc misc things to know
help mr mapreduce
show dbs show database names
show collections show collections in current database
show users show users in current database
show profile show most recent system.profile entries with time >= 1ms
show logs show the accessible logger names
show log [name] prints out the last segment of log in memory, 'global' is default
use <db_name> set current database
db.foo.find() list objects in collection foo
db.foo.find( { a : 1 } ) list objects in foo where a == 1
it result of the last line evaluated; use to further iterate
DBQuery.shellBatchSize = x set default number of items to display on shell
exit quit the mongo shell
>
使用db.help()可以查看数据库级别的命令帮助。
集合的相关帮助通过db.collectionName.help()来查看。
想要了解函数的功能,在输入的时候不要带括号,那样就会显示函数的JavaScript源代码。
例如:
db.users.update
使用db.集合名的方式来访问集合一般不会有文档,但如果集合名恰好是数据库类的一个属性就有问题了。
例如:要访问version这个集合,使用db.version就不行了,因为db.version是个数据库函数。
当JavaScript只有在db中找不到指定的属性时,才会将其作为集合返回,当有属性与目标集合同名时,可以使用getCollection()函数:
>db.getCollection(“version”);
test.version
所以在设计集合名时,要注意规避这些问题。
下一篇:
(adsbygoogle = window.adsbygoogle || []).push({});
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有