剛接觸這類數據庫,個人收集體會!MongoDB基礎知識
1. MongoDB的基本概念
文檔是MongoDB中數據的基本單元,類似於關係型數據庫管理系統中的行。
集合可以看做是一個擁有動態模式的表。
MongoDB的一個實例可以擁有多個相互獨立的數據庫,每一個數據庫擁有自己的集合。
每一個文檔有一個特殊的鍵“_id”,這個鍵在文檔所屬的集合中是唯一的。
MongoDB自帶一個簡單卻功能強大的JavaScript shell,可用於管理MongoDB的實例或數據操作。
2. 文檔
文檔就是鍵值對的一個有序集。
在JavaScript裏面,文檔被表示爲對象:
{“greeting” : "hello world !"}
- 1
文檔的鍵是字符串,除少數例外情況,鍵可以使用任意UTF-8字符。
鍵不能含有\0(空字符串),這個字符串用於表示鍵的結尾。
. 和$有特殊的意義,只能在特定環境下使用,通常情況下這兩個字符是被保留的。
MongoDB區分類型和大小寫,且MongoDB的文檔不能有重複的鍵,文檔中的鍵/值對也是有序的。
3. 集合
集合是一組文檔,MongoDB中的文檔相當於關係型數據庫的一行,那麼集合就相當於一張表。
集合是動態模式的,也就是說,一個集合裏面的文檔可以是各式各樣的。
集合使用名稱進行標識,集合名可以是滿足下列條件的任意UTF-8 字符串:
命名不能是空字符串(“”)。
命名不能包含\0字符(空字符)。
命名不能以”system.”開頭,這是爲系統結合保留的前綴。
用戶創建的集合不能在集合名中包含保留字符”$”。
4. 數據庫
在MongoDB中,多個文檔組成集合,而多個集合組成數據庫。
一個MongoDB實例可以承載多個數據庫,每個數據庫擁有0個或多個集合。
數據庫通過名稱進行標識,數據庫名可以是滿足下列條件的任意UTF-8 字符串:
命名不能是空字符串(“”)。
不能含有/, , ., “, *, <, >, :, |, ?, $(一個空格), \0(空字符),基本上只能使用ASCII中的字母和數字。
數據庫名稱區分大小寫,即便是在區分大小寫的文件系統也是如此,簡單起見,數據庫名應全部小寫。
數據庫名稱最多爲64字節。
保留的數據庫名:
(1) admin , 從身份驗證角度講這是”root”數據庫,如果將一個用戶添加到admin數據庫,這個用戶將自動獲得所有數據庫的權限,且一些特定的服務器端命令也只能從admin數據庫運行。
(2) local ,這個數據庫永遠都不可以複製,且一臺服務器上的所有本地集合都可以存儲在這個數據庫中.
(3) config , MongoDB用於分片設置時,分片信息會存儲在config數據庫中。
把數據庫名添加到集合名前,得到集合的完全限定名,即命名空間(namespace),命名空間的長度不得超過121字節,且在實際使用中應小於100字節。
5. MongoDB一些基本命令
$ mongod
啓動數據庫連接,mongod在沒有參數的情況下,會使用默認數據目錄/data/db,在Window系統中爲C:\data\db,如果數據目錄不存在或不可寫,服務器啓動會失敗,在默認情況下,MongoDB監聽27017端口,如果端口被佔用,啓動也會失敗。
mongod還會啓動一個非常基本的HTTP服務器,監聽數字比端口號高1000的端口,默認也就是28017端口,也就是說,通過瀏覽器訪問:http://localhost:28017,就能獲取數據庫的管理信息。
$ mongo
運行mongo啓動shell,啓動時,shell將自動連接MongoDB服務器,須確保mongod已啓動,shell是一個功能完備的JavaScript解釋器,可以運行任意JavaScript程序。
shell是一個獨立的MongoDB客戶端,啓動時,shell會連接到MongoDB服務器的的test數據庫,並將數據庫連接賦值給全局變量db,這個變量是通過shell訪問MongoDB的主要入口點。
>db
查看db當前指向哪個數據庫。
6. shell中的基本操作
在shell中查看或操作數據庫的4個基本操作:創建,讀取,更新,刪除,即CRUD。
創建: insert函數可將一個文檔添加到集合中。
讀取: find和findOne方法可以用於查詢集合裏的文檔,find和findOne可以接受一個查詢文檔作爲限定條件。
更新: 使用update更新,update至少要接受2個參數,第一個參數:限定條件,用於匹配更新的文檔。 第二個參數:新的文檔。
刪除: 使用remove方法可將文檔從數據庫中永久刪除。
運行環境
- CentOS Linux release 7.2.1511 (Core)
安裝
- wget
https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.2.9.tgz
- tar -zxvf mongodb-linux-x86_64-rhel70-3.2.9.tgz
- mv mongodb-linux-x86_64-rhel70-3.2.9 /usr/local/mongodb
- 添加到環境變量
vi ~/.bashrc
加入:export PATH=/usr/local/mongodb/bin:$PATH
使環境變量生效source ~/.bashrc
- 啓動
啓動前先創建數據庫默認存儲路徑,否則會報錯。mkdir -p /data/db
[root@localhost bin]# mongod
2016-08-19T22:14:07.426+0800 I CONTROL [initandlisten] MongoDB starting : pid=6611 port=27017 dbpath=/data/db 64-bit host=localhost.localdomain
2016-08-19T22:14:07.427+0800 I CONTROL [initandlisten] db version v3.2.9
2016-08-19T22:14:07.427+0800 I CONTROL [initandlisten] git version: 22ec9e93b40c85fc7cae7d56e7d6a02fd811088c
2016-08-19T22:14:07.427+0800 I CONTROL [initandlisten] OpenSSL version: OpenSSL 1.0.1e-fips 11 Feb 2013
2016-08-19T22:14:07.428+0800 I CONTROL [initandlisten] allocator: tcmalloc
2016-08-19T22:14:07.428+0800 I CONTROL [initandlisten] modules: none
2016-08-19T22:14:07.428+0800 I CONTROL [initandlisten] build environment:
2016-08-19T22:14:07.428+0800 I CONTROL [initandlisten] distmod: rhel70
2016-08-19T22:14:07.429+0800 I CONTROL [initandlisten] distarch: x86_64
2016-08-19T22:14:07.429+0800 I CONTROL [initandlisten] target_arch: x86_64
2016-08-19T22:14:07.429+0800 I CONTROL [initandlisten] options: {}
2016-08-19T22:14:07.470+0800 I STORAGE [initandlisten] exception in initAndListen: 29 Data directory /data/db not found., terminating
2016-08-19T22:14:07.471+0800 I CONTROL [initandlisten] dbexit: rc: 100
[root@localhost bin]# mkdir -p /data/db
啓動:mongod
概念區分
SQL術語/概念 | MongoDB術語/概念 | 解釋/說明 |
---|---|---|
database | database | 數據庫 |
table | collection | 數據庫表/集合 |
row | document | 數據記錄行/文檔 |
column | field | 數據字段/域 |
index | index | 索引 |
table joins | 表連接,MongoDB不支持 | |
primary key | primary key | 主鍵,MongoDB自動將_id字段設置爲主鍵 |
- 數據庫
MongoDB的默認數據庫爲"db",該數據庫存儲在data目錄中
MongoDB的單個實例可以容納多個獨立的數據庫,每一個都有自己的集合和權限,不同的數據庫也放置在不同的文件中。
- 顯示所有數據的列表(數據庫爲空時不顯示):
show dbs
- 連接數據庫
mongo
或 mongodb://username:password@IP/
- 顯示當前數據庫和集合
db
- 鏈接或創建數據庫
use dbname
- 刪除數據庫
use 數據庫名
db.dropDatabase()
實例:
> use testdb
switched to db testdb
> db.dropDatabase()
{ "dropped" : "testdb", "ok" : 1 }
>
文檔(表、集合)
- 插入數據
db.集合名稱.insert()
或db.集合名稱.save()
db.集合名稱.insert({"name":"database name"})
- 刪除集合
db.集合名稱.drop()
- 查詢數據(pretty() 方法以格式化的方式來顯示所有文檔。)
db.集合名稱.find()
db.集合名稱.find().pretty()
操作符
操作 | 格式 | 例子 |
---|---|---|
等於 | {key : value} | db.col.find({"name":"title"}).pretty() |
小於 | {key:{$lt : value}} | db.col.find({"likes":{$lt:50}}).pretty() |
小於等於 | {key:{$lte : value}} | db.col.find({"likes":{$lte:50}}).pretty() |
大於 | {key:{$gt: value}} | db.col.find({"likes":{$gt:50}}).pretty() |
大於等於 | {key:{$gte: value}} | db.col.find({"likes":{$gte:50}}).pretty() |
不等於 | {key:{$ne: value}} | db.col.find({"likes":{$ne:50}}).pretty() |
AND 條件
MongoDB 的 find() 方法可以傳入多個鍵(key),每個鍵(key)以逗號隔開,及常規 SQL 的 AND 條件。
語法格式如下:
>db.col.find({key1:value1, key2:value2}).pretty()
> db.col.insert({name:"name", value:"value"})
WriteResult({ "nInserted" : 1 })
> db.col.find({name:"name", value:"value"})
{ "_id" : ObjectId("57b72c84e046f1574e641799"), "name" : "name", "value" : "value" }
OR 條件
使用關鍵字$or
>db.col.find(
{
$or: [
{key1: value1}, {key2:value2}
]
}
).pretty()
> db.col.find()
{ "_id" : ObjectId("57b725e6e046f1574e641797"), "name" : "update title2" }
{ "_id" : ObjectId("57b72c84e046f1574e641799"), "name" : "name", "value" : "value" }
{ "_id" : ObjectId("57b72ce7e046f1574e64179a"), "name" : "testname", "value" : "test" }
>
> db.col.find({$or:[{name:"name"}, {value:"test"}]})
{ "_id" : ObjectId("57b72c84e046f1574e641799"), "name" : "name", "value" : "value" }
{ "_id" : ObjectId("57b72ce7e046f1574e64179a"), "name" : "testname", "value" : "test" }
>
AND 和 OR 聯合使用
> db.col.find()
{ "_id" : ObjectId("57b725e6e046f1574e641797"), "name" : "update title2" }
{ "_id" : ObjectId("57b72c84e046f1574e641799"), "name" : "name", "value" : "value" }
{ "_id" : ObjectId("57b72ce7e046f1574e64179a"), "name" : "testname", "value" : "test" }
{ "_id" : ObjectId("57b72e50e046f1574e64179b"), "name" : "name", "value" : "test", "number" : 100 }
{ "_id" : ObjectId("57b72e6de046f1574e64179c"), "name" : "name", "value" : "test", "number" : 200 }
{ "_id" : ObjectId("57b72e70e046f1574e64179d"), "name" : "name", "value" : "test", "number" : 100 }
>
>
> db.col.find({number: {$eq : 100}, $or : [{name:"name"}, {value:"test"}]})
{ "_id" : ObjectId("57b72e50e046f1574e64179b"), "name" : "name", "value" : "test", "number" : 100 }
{ "_id" : ObjectId("57b72e70e046f1574e64179d"), "name" : "name", "value" : "test", "number" : 100 }
>
$type 操作符
$type
操作符是基於BSON類型來檢索集合中匹配的數據類型,並返回結果。
limit和skip的用法
limit
限制返回的條數
skip
跳過指定數量的數據
> db.col.find();
{ "_id" : ObjectId("57b725e6e046f1574e641797"), "name" : "update title2" }
{ "_id" : ObjectId("57b72c84e046f1574e641799"), "name" : "name", "value" : "value" }
{ "_id" : ObjectId("57b72ce7e046f1574e64179a"), "name" : "testname", "value" : "test" }
{ "_id" : ObjectId("57b72e50e046f1574e64179b"), "name" : "name", "value" : "test", "number" : 100 }
{ "_id" : ObjectId("57b72e6de046f1574e64179c"), "name" : "name", "value" : "test", "number" : 200 }
{ "_id" : ObjectId("57b72e70e046f1574e64179d"), "name" : "name", "value" : "test", "number" : 100 }
>
> db.col.find().limit(2)
{ "_id" : ObjectId("57b725e6e046f1574e641797"), "name" : "update title2" }
{ "_id" : ObjectId("57b72c84e046f1574e641799"), "name" : "name", "value" : "value" }
>
> db.col.find().limit(2).skip(2)
{ "_id" : ObjectId("57b72ce7e046f1574e64179a"), "name" : "testname", "value" : "test" }
{ "_id" : ObjectId("57b72e50e046f1574e64179b"), "name" : "name", "value" : "test", "number" : 100 }
- 文檔排序
使用sort()
方法並通過參數指定排序的字段,並使用 1
和 -1
來指定排序的方式,其中 1
爲升序
排列,而-1
是用於降序
排列。
格式:db.集合名稱.find().sort({KEY:1})
> db.col.find()
{ "_id" : ObjectId("57b725e6e046f1574e641797"), "name" : "update title2" }
{ "_id" : ObjectId("57b72c84e046f1574e641799"), "name" : "name", "value" : "value" }
{ "_id" : ObjectId("57b72ce7e046f1574e64179a"), "name" : "testname", "value" : "test" }
{ "_id" : ObjectId("57b72e50e046f1574e64179b"), "name" : "name", "value" : "test", "number" : 100 }
{ "_id" : ObjectId("57b72e6de046f1574e64179c"), "name" : "name", "value" : "test", "number" : 200 }
{ "_id" : ObjectId("57b72e70e046f1574e64179d"), "name" : "name", "value" : "test", "number" : 100 }
>
> db.col.find().sort({name:1})
{ "_id" : ObjectId("57b72c84e046f1574e641799"), "name" : "name", "value" : "value" }
{ "_id" : ObjectId("57b72e50e046f1574e64179b"), "name" : "name", "value" : "test", "number" : 100 }
{ "_id" : ObjectId("57b72e6de046f1574e64179c"), "name" : "name", "value" : "test", "number" : 200 }
{ "_id" : ObjectId("57b72e70e046f1574e64179d"), "name" : "name", "value" : "test", "number" : 100 }
{ "_id" : ObjectId("57b72ce7e046f1574e64179a"), "name" : "testname", "value" : "test" }
{ "_id" : ObjectId("57b725e6e046f1574e641797"), "name" : "update title2" }
>
> db.col.find().sort({name:-1})
{ "_id" : ObjectId("57b725e6e046f1574e641797"), "name" : "update title2" }
{ "_id" : ObjectId("57b72ce7e046f1574e64179a"), "name" : "testname", "value" : "test" }
{ "_id" : ObjectId("57b72c84e046f1574e641799"), "name" : "name", "value" : "value" }
{ "_id" : ObjectId("57b72e50e046f1574e64179b"), "name" : "name", "value" : "test", "number" : 100 }
{ "_id" : ObjectId("57b72e6de046f1574e64179c"), "name" : "name", "value" : "test", "number" : 200 }
{ "_id" : ObjectId("57b72e70e046f1574e64179d"), "name" : "name", "value" : "test", "number" : 100 }
>
- 更新文檔(
update
或者save
來更新文檔)
update方式
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
- query : update的查詢條件,類似sql update查詢內where後面的。
- update : update的對象和一些更新的操作符(如
$set
,$inc
...)等,也可以理解爲sql update查詢內set後面的- upsert : 可選,這個參數的意思是,如果不存在update的記錄,是否插入objNew,true爲插入,默認是false,不插入。
- multi : 可選,mongodb
默認是false
,只更新找到的第一條記錄
,如果這個參數爲true
,就把按條件查出來多條記錄全部更新
。- writeConcern :可選,拋出異常的級別。
例子:
> db.col.find()
>
>
> db.col.insert({"name" : "value"})
WriteResult({ "nInserted" : 1 })
> db.col.insert({"name" : "title"})
WriteResult({ "nInserted" : 1 })
> db.col.find()
{ "_id" : ObjectId("57b725e6e046f1574e641797"), "name" : "value" }
{ "_id" : ObjectId("57b725eee046f1574e641798"), "name" : "title" }
> db.col.update({"name" : "title"}, {$set:{"name" : "update title"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.col.find()
{ "_id" : ObjectId("57b725e6e046f1574e641797"), "name" : "value" }
{ "_id" : ObjectId("57b725eee046f1574e641798"), "name" : "update title" }
>
save方式
save() 方法
save() 方法通過傳入的文檔來替換已有文檔。語法格式如下:
db.collection.save(
<document>,
{
writeConcern: <document>
}
)
參數說明:
- document : 文檔數據。
- writeConcern :可選,拋出異常的級別。
- 刪除文檔
db.collection.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)
參數說明:
- query :(可選)刪除的文檔的條件。
justOne : (可選)如果設爲 true 或 1,則只刪除一個文檔。
- writeConcern :(可選)拋出異常的級別。
> db.col.remove({name:"update title"})
WriteResult({ "nRemoved" : 1 })
如果想清空表(truncate)
db.col.remove({})
索引
使用 ensureIndex()
方法來創建索引
db.集合名稱.ensureIndex({KEY:1})
升序:1,降序:-1
參數 | 參數值類型 | 描述 |
---|---|---|
background | Boolean | 建索引過程會阻塞其它數據庫操作,background可指定以後臺方式創建索引,即增加 "background" 可選參數。 "background" 默認值爲false。 |
unique | Boolean | 建立的索引是否唯一。指定爲true創建唯一索引。默認值爲false. |
name | string | 索引的名稱。如果未指定,MongoDB的通過連接索引的字段名和排序順序生成一個索引名稱。 |
dropDups | Boolean | 在建立唯一索引時是否刪除重複記錄,指定 true 創建唯一索引。默認值爲 false. |
sparse | Boolean | 對文檔中不存在的字段數據不啓用索引;這個參數需要特別注意,如果設置爲true的話,在索引字段中不會查詢出不包含對應字段的文檔.。默認值爲 false. |
expireAfterSeconds | integer | 指定一個以秒爲單位的數值,完成 TTL設定,設定集合的生存時間。 |
v | index version | 索引的版本號。默認的索引版本取決於mongod創建索引時運行的版本。 |
weights | document | 索引權重值,數值在 1 到 99,999 之間,表示該索引相對於其他索引字段的得分權重。 |
default_language | string | 對於文本索引,該參數決定了停用詞及詞幹和詞器的規則的列表。 默認爲英語 |
language_override | string | 對於文本索引,該參數指定了包含在文檔中的字段名,語言覆蓋默認的language,默認值爲 language. |
聚合統計
主要用於處理數據(諸如統計平均值,求和等),並返回計算後的數據結果。有點類似sql語句中的 count(*)
- 語法
db.集合名稱.aggregate(AGGREGATE_OPERATION)
表達式 | 描述 | 實例 |
---|---|---|
$sum | 計算總和。 | db.mycol.aggregate([{$group : {_id : "$聚合字段", num_tutorial : {$sum : "$統計字段"}}}]) |
$avg | 計算平均值 | db.mycol.aggregate([{$group : {_id : "$聚合字段", num_tutorial : {$avg : "$likes"}}}]) |
$min | 獲取集合中所有文檔對應值得最小值。 | db.mycol.aggregate([{$group : {_id : "$聚合字段", num_tutorial : {$min : "$統計字段"}}}]) |
$max | 獲取集合中所有文檔對應值得最大值。 | db.mycol.aggregate([{$group : {_id : "$聚合字段", num_tutorial : {$max : "$統計字段"}}}]) |
$push | 在結果文檔中插入值到一個數組中。 | db.mycol.aggregate([{$group : {_id : "$聚合字段", url : {$push: "$統計字段"}}}]) |
$addToSet | 在結果文檔中插入值到一個數組中,但不創建副本。 | db.mycol.aggregate([{$group : {_id : "$聚合字段", url : {$addToSet : "$統計字段"}}}]) |
$first | 根據資源文檔的排序獲取第一個文檔數據。 | db.mycol.aggregate([{$group : {_id : "$聚合字段", first_url : {$first : "$統計字段"}}}]) |
$last | 根據資源文檔的排序獲取最後一個文檔數據 | db.mycol.aggregate([{$group : {_id : "$聚合字段", last_url : {$last : "$統計字段"}}}]) |
聚合過程中常用的幾個操作:
- $project:修改輸入文檔的結構。可以用來重命名、增加或刪除域,也可以用於創建計算結果以及嵌套文檔。
- $match:用於過濾數據,只輸出符合條件的文檔。$match使用MongoDB的標準查詢操作。
- $limit:用來限制MongoDB聚合管道返回的文檔數。
- $skip:在聚合管道中跳過指定數量的文檔,並返回餘下的文檔。
- $unwind:將文檔中的某一個數組類型字段拆分成多條,每條包含數組中的一個值。
- $group:將集合中的文檔分組,可用於統計結果。
- $sort:將輸入文檔排序後輸出。
- $geoNear:輸出接近某一地理位置的有序文檔。
主從配置
1、主服務器啓動時指定端口和replSet
選項
mongod --port "PORT" --dbpath "YOUR_DB_DATA_PATH" --replSet "REPLICA_SET_INSTANCE_NAME"
如:
mongod --port 27017 --dbpath "/data/db" --replSet rs0
注意:
- 啓動後需要通過
rs.initiate()
來啓動一個新的副本,使設置生效- 可以使用
rs.conf()
查看配置和rs.status()
查看狀態
2、從服務器配置
>rs.add(HOST_NAME:PORT)
如:
>rs.add(192.168.1.100:27017)
分片
備份與恢復
備份命令:
mongodump -h 服務器地址 -d 數據庫名稱 -o 備份存放目錄
恢復命令:
mongorestore -h 服務器地址 -d 數據庫名稱 --directoryperdb 備份存放目錄
監控
- 狀態檢查:
mongostat
命令 - 讀取、寫入、鎖等耗時狀況:
mongotop
命令
mongodb關係
mongodb中文檔與文檔之間的關係,可以通過嵌入式關係
和引用式關係
進行表示。
嵌入式關係:
"_id":ObjectId("52ffc33cd85242f436000001"),
"contact": "987654321",
"dob": "01-01-1991",
"name": "Tom Benzamin",
"address": [
{
"building": "22 A, Indiana Apt",
"pincode": 123456,
"city": "Los Angeles",
"state": "California"
},
{
"building": "170 A, Acropolis Apt",
"pincode": 456789,
"city": "Chicago",
"state": "Illinois"
}]
}
引用式關係:
{
"_id":ObjectId("52ffc33cd85242f436000001"),
"contact": "987654321",
"dob": "01-01-1991",
"name": "Tom Benzamin",
"address_ids": [
ObjectId("52ffc4a5d85242602e000000"),
ObjectId("52ffc4a5d85242602e000001")
]
}
MongoDB 數據庫引用
手動引用
DBRefs
DBRefs
引用格式:
{ $ref : , $id : , $db : }
- $ref:集合名稱
- $id:引用的id
- $db:數據庫名稱,可選參數
{
"_id":ObjectId("53402597d852426020000002"),
"address": {
"$ref": "address_home",
"$id": ObjectId("534009e4d852427820000002"),
"$db": "w3cschoolcc"},
"contact": "987654321",
"dob": "01-01-1991",
"name": "Tom Benzamin"
}
查詢分析
使用 explain()
db.users.ensureIndex({gender:1,user_name:1})
db.users.find({gender:"M"},{user_name:1,_id:0}).explain()
{
"cursor" : "BtreeCursor gender_1_user_name_1",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 0,
"nscanned" : 1,
"nscannedObjectsAllPlans" : 0,
"nscannedAllPlans" : 1,
"scanAndOrder" : false,
"indexOnly" : true,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"gender" : [
[
"M",
"M"
]
],
"user_name" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
}
}
- indexOnly: 字段爲 true ,表示我們使用了索引。
- cursor:因爲這個查詢使用了索引,MongoDB中索引存儲在B樹結構中,所以這是也使用了BtreeCursor類型的遊標。如果沒有使用索引,遊標的類型是BasicCursor。這個鍵還會給出你所使用的索引的名稱,你通過這個名稱可以查看當前數據庫下的system.indexes集合(系統自動創建,由於存儲索引信息,這個稍微會提到)來得到索引的詳細信息。
- n:當前查詢返回的文檔數量。
- nscanned/nscannedObjects:表明當前這次查詢一共掃描了集合中多少個文檔,我們的目的是,讓這個數值和返回文檔的數量越接近越好。
- millis:當前查詢所需時間,毫秒數。
- indexBounds:當前查詢具體使用的索引。
使用 hint()
強制mongodb使用某個索引。
db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1})
mongodb 原子操作
mongodb不支持事務
,所以,在你的項目中應用時,要注意這點。無論什麼設計,都不要要求mongodb保證數據的完整性。
但是mongodb提供了許多原子操作,比如文檔的保存,修改,刪除等,都是原子操作。
所謂原子操作就是要麼這個文檔保存到Mongodb,要麼沒有保存到Mongodb,不會出現查詢到的文檔沒有保存完整的情況。
原子操作常用命令
$set
:存在時更新,不存在時新增
{ $set : { field : value } }
$unset
:刪除一個鍵
{ $unset : { field : 1} }
$inc
:對數值類型的鍵進行增加和減少操作
{ $inc : { field : value } }
$push
:把value追加到field數組裏去,如果數組不存在則新增。
{ $push : { field : value } }
$pushAll
:功能和$push
類似;追加多個值到一個數組字段內
{ $pushAll : { field : value_array } }
$pull
:從數組field內刪除一個等於value值的文檔。
{ $pull : { field : _value } }
$addToSet
:增加一個唯一值到數組內,不存在時增加,存在時忽略。$pop
:刪除數組的第一個或最後一個元素
{ $pop : { field : 1 } }
$rename
:修改字段名稱
{ $rename : { old_field_name : new_field_name } }
$bit
:位操作,integer類型
{$bit : { field : {and : 5}}}
mongodb 高級索引
- 索引數組字段
如:
{
"address": {
"city": "Los Angeles",
"state": "California",
"pincode": "123"
},
"tags": [
"music",
"cricket",
"blogs"
],
"name": "Tom Benzamin"
}
建立索引:
db.users.ensureIndex({"tags":1})
使用索引:
db.users.find({tags:"cricket"}).explain()
- 索引子文檔字段
db.users.ensureIndex({"address.city":1,"address.state":1,"address.pincode":1})
記住查詢表達式必須遵循指定的索引的順序。
查詢限制
索引不能被以下的查詢使用:
- 正則表達式及非操作符,如
$nin
,$not
, 等。- 算術運算符,如
$mod
, 等。$where
子句
- 索引鍵限制
從2.6版本開始,如果現有的索引字段的值超過索引鍵的限制,MongoDB中不會創建索引。
- 插入文檔超過索引鍵限制
如果文檔的索引字段值超過了索引鍵的限制,MongoDB不會將任何文檔轉換成索引的集合。與mongorestore和mongoimport工具類似。
- 最大範圍
- 集合中索引不能超過64個
- 索引名的長度不能超過125個字符
- 一個複合索引最多可以有31個字段
MongoDB ObjectId
ObjectId 是一個12字節 BSON 類型數據,有以下格式:
- 前4個字節表示時間戳
- 接下來的3個字節是機器標識碼
- 緊接的兩個字節由進程id組成(PID)
- 最後三個字節是隨機數。
- 創建新的ObjectId
ObjectId()
- 獲取創建文檔的時間戳
ObjectId("5349b4ddd2781d08c09890f4").getTimestamp()
- ObjectId 轉換爲字符串
> ObjectId().str
57bb019f1b9653f34d858a03