天天看點

mongodb應用

一.概述

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.6.tgz                                # 解壓

mv  mongodb-linux-x86_64-3.0.6/ /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字元串。

>>不能是空字元串(“”)。
>>不能含有空格、點号、$、/、\和\0(空字元)
>>應全部小寫
>>最多64位元組      

有些資料庫名時保留的,可以直接通路這些有特殊作用的資料庫:

>>admin: 從權限的角度來看,這是"root"資料庫。要是将一個使用者添加到這個資料庫,這個使用者自動繼承所有資料庫的權限。一些特定的伺服器端指令也隻能從這個資料庫運作,比如列出所有的資料庫或者關閉伺服器。

>>local: 這個資料永遠不會被複制,可以用來存儲限于本地單台伺服器的任意集合

>>config: 當Mongo用于分片設定時,config資料庫在内部使用,用于儲存分片的相關資訊。

2.文檔(Document):行

文檔是一組鍵值(key-value)對(即 BSON)。MongoDB 的文檔不需要設定相同的字段,并且相同的字段不需要相同的資料類型。

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

文檔中的鍵/值對是有序的。

文檔中的值不僅可以是在雙引号裡面的字元串,還可以是其他幾種資料類型(甚至可以是整個嵌入的文檔)。

MongoDB區分類型和大小寫。

MongoDB的文檔不能有重複的鍵。

文檔的鍵是字元串。除了少數例外情況,鍵可以使用任意UTF-8字元。

文檔鍵命名規範:

>>鍵不能含有\0 (空字元)。這個字元用來表示鍵的結尾。
>>.和$有特别的意義,隻有在特定環境下才能使用。
>>以下劃線"_"開頭的鍵是保留的(不是嚴格要求的)。      

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:100000})      

要注意的是指定的存儲大小包含了資料庫的頭資訊。

>>在 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,含義是:

前 4 個位元組表示建立 unix 時間戳,格林尼治時間 UTC 時間,比中原標準時間晚了 8 個小時
接下來的 3 個位元組是機器辨別碼
緊接的兩個位元組由程序 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 04 2018 14:58:51 GMT+0000 (UTC) 
>typeof mydate1str
string      

或者

>Date()
Sun Mar 04 2018 15:02:59 GMT+0000 (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:9999/foo  foo database on 192.168.0.5 machine on port 9999
  192.168.0.5:9999   database on 192.168.0.5 machine on port 9999      

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   0.000GB
config  0.000GB
local   0.000GB
>db.gateway.insert({"name":"chinamobile"})
WriteResult({ "nInserted" : 1 })
> show dbs
admin    0.000GB
config   0.000GB
gateway  0.000GB
local    0.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 : 6142800, max : 10000 } )
{ "ok" : 1 }      

當插入一些文檔時,MongoDB 會自動建立集合。

>db.gateway.insert({"name":"chinamobile"})
WriteResult({ "nInserted" : 1 })
>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":"20190508"})
{ "title" : "wang", "date" : "20190508" }
>db.gateway.insert(doc1)
WriteResult({ "nInserted" : 1 })      

插入文檔你也可以使用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" : 1, "nUpserted" : 0, "nModified" : 1 })      

以上語句隻會修改第一條發現的文檔,如果你要修改多條相同的文檔,則需要設定 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,1)      

如果你想删除所有資料,可以使用以下方式(類似正常 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