mongodb应用

时间:2023-12-19 12:08:14

一.概述

NoSQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。NoSQL用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。

MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。

在高负载的情况下,添加更多的节点,可以保证服务器性能。

MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。

MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。

github:https://github.com/mongodb/mongo

官网:https://www.mongodb.com/

二.安装

在Ubuntu下可直接安装,官网推荐安装mongodb-org:

sudo apt-get install -y mongodb-org

也可在官网下载tar包后安装https://www.mongodb.com/download-center#community

curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.6.tgz    # 下载

tar -zxvf mongodb-linux-x86_64-3.0..tgz                                # 解压

mv  mongodb-linux-x86_64-3.0./ /usr/local/mongodb    # 将解压包拷贝到指定目录

export PATH=<mongodb-install-directory>/bin:$PATH

创建数据库目录

MongoDB的数据存储在data目录的db目录下,但是这个目录在安装过程不会自动创建,所以你需要手动创建data目录,并在data目录中创建db目录。

注意:/data/db 是 MongoDB 默认的启动的数据库路径(--dbpath)。

mkdir -p /data/db

MongoDB后台管理shell
mongo是MongoDB自带的交互式JavaScript shell,用来对MongoDB进行操作和管理的交互式环境。

MongoDBDB允许远程访问

需要增加参数--bind_ip_all。

mongod --dbpath ./db --bind_ip_all

mongodb web用户界面

MongoDB 提供了简单的 HTTP 用户界面。 如果你想启用该功能,需要在启动的时候指定参数 --rest 。注意:该功能只适用于 MongoDB 3.2 及之前的早期版本。

$ ./mongod --dbpath=/data/db --rest

MongoDB 的 Web 界面访问端口比服务的端口多1000。如果你的MongoDB运行端口使用默认的27017,你可以在端口号为28017访问web用户界面,即地址为:http://localhost:28017。

三.基础概念

mongodb应用

1.数据库

一个mongodb中可以建立多个数据库。MongoDB的单个实例可以容纳多个独立的数据库,每一个都有自己的集合和权限,不同的数据库也放置在不同的文件中。

show dbs:显示数据库列表
db:显示当前操作的数据库
use <db_name>:连接一个指定的数据库

数据库命名规则:满足以下条件的任意UTF-8字符串。

>>不能是空字符串(“”)。
>>不能含有空格、点号、$、/、\和\(空字符)
>>应全部小写
>>最多64字节

有些数据库名时保留的,可以直接访问这些有特殊作用的数据库:

>>admin: 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。

>>local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合

>>config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。

2.文档(Document):行

文档是一组键值(key-value)对(即 BSON)。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型。

{"site":"www.runoob.com", "name":"菜鸟教程"}

文档中的键/值对是有序的。

文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。

MongoDB区分类型和大小写。

MongoDB的文档不能有重复的键。

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

文档键命名规范:

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

3.  集合(collection):table

集合就是 MongoDB 文档组,类似于 RDBMS (关系数据库管理系统:Relational Database Management System)中的表格。

集合存在于数据库中,集合没有固定的结构,这意味着你在对集合可以插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性。

当第一个文档插入时,集合才会被创建。

合法的集合名

>>集合名不能是空字符串""。
>>集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
>>集合名不能以"system."开头,这是为系统集合保留的前缀。
>>用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$。

capped collections

Capped collections 就是固定大小的collection。Capped collections 是高性能自动的维护对象的插入顺序。它非常适合类似记录日志的功能。和标准的 collection 不同,你必须要显式的创建一个capped collection,指定一个 collection 的大小,单位是字节。collection 的数据存储空间值提前分配的。

Capped collections 可以按照文档的插入顺序保存到集合中,而且这些文档在磁盘上存放位置也是按照插入顺序来保存的,所以当我们更新Capped collections 中文档的时候,更新后的文档不可以超过之前文档的大小,这样话就可以确保所有文档在磁盘上的位置一直保持不变。

由于 Capped collection 是按照文档的插入顺序而不是使用索引确定插入位置,这样的话可以提高增添数据的效率。MongoDB 的操作日志文件 oplog.rs 就是利用 Capped Collection 来实现的。

db.createCollection("mycoll", {capped:true, size:})

要注意的是指定的存储大小包含了数据库的头信息。

>>在 capped collection 中,你能添加新的对象。
>>能进行更新,然而,对象不会增加存储空间。如果增加,更新就会失败 。
>>使用 Capped Collection 不能删除一个文档,可以使用 drop() 方法删除 collection 所有的行。
>>删除之后,你必须显式的重新创建这个 collection。
>>在32bit机器中,capped collection 最大存储为 1e9( 1X109)个字节。

4. 元数据

数据库的信息是存储在集合中。它们使用了系统的命名空间:dbname.system.*
在MongoDB数据库中名字空间<dbname>.system.*是包含多种系统信息的特殊集合(Collection),如下:

dbname.system.namespaces    列出所有名字空间。
dbname.system.indexes 列出所有索引。
dbname.system.profile 包含数据库概要(profile)信息。
dbname.system.users 列出所有可访问数据库的用户。
dbname.local.sources 包含复制对端(slave)的服务器信息和状态。

对于修改系统集合中的对象有如下限制:

在{{system.indexes}}插入数据,可以创建索引。但除此之外该表信息是不可变的(特殊的drop index命令将自动更新相关信息)。
{{system.users}}是可修改的。 {{system.profile}}是可删除的。

5.数据类型

mongodb应用

几个重要的数据类型说明如下:

ObjectId

ObjectId类似唯一主键,可以很快的去生成和排序,包含 12 bytes,含义是:

前  个字节表示创建 unix 时间戳,格林尼治时间 UTC 时间,比北京时间晚了  个小时
接下来的 个字节是机器标识码
紧接的两个字节由进程 id 组成 PID
最后三个字节是随机数

MongoDB 中存储的文档必须有一个 _id 键。这个键的值可以是任何类型的,默认是个 ObjectId 对象。由于 ObjectId 中保存了创建的时间戳,所以你不需要为你的文档保存时间戳字段,你可以通过 getTimestamp 函数来获取文档的创建时间:

> var newObject = ObjectId()
>newObject.getTimestamp()
ISODate("2017-11-25T07:21:10Z")

ObjectId 转为字符串:

>newObject.str
5a1919e63df83ce79df8b38f

时间戳

BSON 有一个特殊的时间戳类型用于 MongoDB 内部使用,与普通的 日期 类型不相关。 时间戳值是一个 64 位的值,其中:

前32位是一个 time_t 值(与Unix新纪元相差的秒数)
后32位是在某秒中操作的一个递增的序数

在单个 mongod 实例中,时间戳值通常是唯一的。
在复制集中, oplog 有一个 ts 字段。这个字段中的值使用BSON时间戳表示了操作时间。
注:BSON 时间戳类型主要用于 MongoDB 内部使用。在大多数情况下的应用开发中,你可以使用 BSON 日期类型。

日期

表示当前距离 Unix新纪元(1970年1月1日)的毫秒数。日期类型是有符号的, 负数表示 1970 年之前的日期。

> var mydate1 = new Date()     //格林尼治时间
> mydate1
ISODate("2018-03-04T14:58:51.233Z")
>typeof mydate1
object
> var mydate2 = ISODate() //格林尼治时间
> mydate2
ISODate("2018-03-04T15:00:45.479Z")
>typeof mydate2
object

这样创建的时间是日期类型,可以使用 JS 中的 Date 类型的方法。
返回一个时间类型的字符串:

> var mydate1str = mydate1.toString()
> mydate1str
Sun Mar :: GMT+ (UTC)
>typeof mydate1str
string

或者

>Date()
Sun Mar :: GMT+ (UTC)

6.数据库操作

连接数据库

可以使用 MongoDB shell 或PHP 来连接 MongoDB,如下通过mongo命令行连接数据库。
标准 URI 连接语法:

mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]

• mongodb:// 这是固定的格式,必须要指定。
• username:password@ 可选项,如果设置,在连接数据库服务器之后,驱动都会尝试登陆这个数据库
• host1 必须的指定至少一个host, host1 是这个URI唯一要填写的。它指定了要连接服务器的地址。如果要连接复制集,请指定多个主机地址。
• portX 可选的指定端口,如果不填,默认为27017
• /database 如果指定username:password@,连接并验证登陆指定数据库。若不指定,默认打开 test 数据库。
• ?options 是连接选项。如果不使用/database,则前面需要加上/。所有连接选项都是键值对name=value,键值对之间通过&或;(分号)隔开

linux下可直接用mongo连接数据库(上述方法测试不适用):

usage: mongo [options] [db address] [file names (ending in .js)]
db address can be:
foo foo database on local machine
192.168.0.5/foo foo database on 192.168.0.5 machine
192.168.0.5:/foo foo database on 192.168.0.5 machine on port
192.168.0.5: database on 192.168.0.5 machine on port

mongo命令行的js文件有语法要求,一个已知为不能使用“use db"命令切换数据库,应使用"db.getSiblingDB('db')"。

一个示例参考:https://github.com/edgexfoundry/docker-edgex-mongo/blob/master/init_mongo.js

db=db.getSiblingDB('authorization')
db.createUser({ user: "admin",pwd: "password",roles: [ { role: "readWrite", db: "authorization" } ]});

创建数据库

db

显示当前使用的数据库

show dbs

显示所有数据库

use datebase_name

如果数据库不存在,则创建数据库,否则切换到指定数据库。

若此时执行showdbs看不到刚创建的数据库,要显示它,需要向数据库插入一些数据。

> use gateway
switched to db gateway
>db
gateway
> show dbs
admin .000GB
config .000GB
local .000GB
>db.gateway.insert({"name":"chinamobile"})
WriteResult({ "nInserted" : })
> show dbs
admin .000GB
config .000GB
gateway .000GB
local .000GB

MongoDB 中默认的数据库为 test,如果你没有创建新的数据库,集合将存放在 test 数据库中。注意: 在 MongoDB 中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。

删除数据库

db.dropDatabase()

删除当前数据库,默认为 test,你可以使用db命令查看当前数据库名。

7. 集合操作

创建集合

db.createCollection(name, options)

参数说明:
• name: 要创建的集合名称
• options: 可选参数, 指定有关内存大小及索引的选项
mongodb应用
在插入文档时,MongoDB 首先检查固定集合的 size 字段,然后检查 max 字段。
创建固定集合mycol,整个集合空间大小 6142800 KB, 文档最大个数为 10000 个。

>db.createCollection("mycol", { capped : true, autoIndexId : true, size : , max :  } )
{ "ok" : }

当插入一些文档时,MongoDB 会自动创建集合。

>db.gateway.insert({"name":"chinamobile"})
WriteResult({ "nInserted" : })
>db
gateway
> show collections
gateway

显示集合

show collections

删除集合

db.collection_name.drop()

无参数;如果成功删除选定集合,则 drop() 方法返回 true,否则返回 false。

8. 文档操作

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

插入

db.COLLECTION_NAME.insert(document)

也可将数据定义为一个变量,如下:

> doc1=({"title":"wang","date":""})
{ "title" : "wang", "date" : "" }
>db.gateway.insert(doc1)
WriteResult({ "nInserted" : })

插入文档你也可以使用db.col.save(document) 命令。如果不指定 _id 字段 save() 方法类似于 insert() 方法。如果指定 _id 字段,则会更新该 _id 的数据。

更新

MongoDB 使用 update() 和 save() 方法来更新集合中的文档。
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的记录,是否插入objNew,true为插入,默认是false,不插入。
• multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
• writeConcern :可选,抛出异常的级别。
通过update()方法更新标题(title):

>db.gateway.update({"title":"wang"},{$set:{"title":"cm"}})
WriteResult({ "nMatched" : , "nUpserted" : , "nModified" : })

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

>db.col.update({'title':'wang'},{$set:{'title':'cm'}},{multi:true})

save() 方法通过传入的文档来替换已有文档。语法格式如下:

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

参数说明:

•document : 文档数据。

•writeConcern :可选,抛出异常的级别。

删除

db.collection.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)

参数说明:

•query :(可选)删除的文档的条件。

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

•writeConcern :(可选)抛出异常的级别。

如果你只想删除第一条找到的记录可以设置 justOne 为 1,如下所示:

>db.COLLECTION_NAME.remove(DELETION_CRITERIA,)

如果你想删除所有数据,可以使用以下方式(类似常规 SQL 的 truncate 命令):

>db.col.remove({})

查询

MongoDB 查询文档使用 find() 方法。find() 方法以非结构化的方式来显示所有文档。

db.collection.find(query, projection)

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

•projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值,只需省略该参数即可(默认省略)。

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

>db.col.find().pretty()

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

 >db.col.update({'title':'wang'},{$set:{'title':'cm'}},{multi:true})

四. 交叉编译mongodb

mongodb设计为大数据存储使用,目前支持arm-64,但不支持arm,网络上有介绍编译的方法,但目前多次测试均未成功(一运行均出现段错误)。

http://facat.github.io/cross-compile-mongodb-for-arm.html  Cross compile mongodb for arm

http://pansila.github.io/posts/ae66dec5/   Cross compile mongodb for 32bit arm

https://github.com/mattlord/mongo-embedded-sample

https://github.com/Barryrowe/mongo-arm

参考:

1. https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/

2. http://www.runoob.com/mongodb/mongodb-linux-install.html runoob