MongoDb基礎知識

剛接觸這類數據庫,個人收集體會!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術語/概念解釋/說明
databasedatabase數據庫
tablecollection數據庫表/集合
rowdocument數據記錄行/文檔
columnfield數據字段/域
indexindex索引
table joins 表連接,MongoDB不支持
primary keyprimary 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

參數參數值類型描述
backgroundBoolean建索引過程會阻塞其它數據庫操作,background可指定以後臺方式創建索引,即增加 "background" 可選參數。 "background" 默認值爲false。
uniqueBoolean建立的索引是否唯一。指定爲true創建唯一索引。默認值爲false.
namestring索引的名稱。如果未指定,MongoDB的通過連接索引的字段名和排序順序生成一個索引名稱。
dropDupsBoolean在建立唯一索引時是否刪除重複記錄,指定 true 創建唯一索引。默認值爲 false.
sparseBoolean對文檔中不存在的字段數據不啓用索引;這個參數需要特別注意,如果設置爲true的話,在索引字段中不會查詢出不包含對應字段的文檔.。默認值爲 false.
expireAfterSecondsinteger指定一個以秒爲單位的數值,完成 TTL設定,設定集合的生存時間。
vindex version索引的版本號。默認的索引版本取決於mongod創建索引時運行的版本。
weightsdocument索引權重值,數值在 1 到 99,999 之間,表示該索引相對於其他索引字段的得分權重。
default_languagestring對於文本索引,該參數決定了停用詞及詞幹和詞器的規則的列表。 默認爲英語
language_overridestring對於文本索引,該參數指定了包含在文檔中的字段名,語言覆蓋默認的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



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章