1. 程式人生 > >MongoDB資料庫操作和Pymongo

MongoDB資料庫操作和Pymongo

一、MongoDB介紹

MongoDB 是一個是一個基於分散式檔案儲存的資料庫,介於關係資料庫和非關係資料庫之間,是非關係資料庫當中功能最豐富,最像關係資料庫的。他支援的資料結構非常鬆散,是類似json的bson格式,因此可以儲存比較複雜的資料型別。Mongo最大的特點是他支援的查詢語言非常強大,其語法有點類似於面向物件的查詢語言,幾乎可以實現類似關係資料庫單表查詢的絕大部分功能,而且還支援對資料建立索引。

二、安裝MongoDB

MongoDB安裝很簡單,無需下載原始檔,可以直接用apt-get命令進行安裝。如果網速太差,並且已經下載MongoDB的安裝包時,可以離線方式安裝,參考Ubuntu下MongoDB安裝與使用教程(離線安裝方式)。推薦使用apt-get命令進行線上安裝,可以避免很多莫名其妙的問題。
以下命令

sudo apt-get install mongodb

可下載安裝MongoDB,預設安裝的版本是MongoDB 2.6.10,但目前MongoDB已經升級到3.2.8,這裡將指導讀者通過新增軟體源的方式來安裝3.2.8版本。
首先開啟終端,匯入公共key到包管理器,輸入以下命令:

Shell 命令:
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927   

建立MongoDB的檔案列表

#僅適用於Ubuntu14.04,輸入:
echo "deb http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.2 multiverse"
| sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list 更新包管理器,安裝MongoDB,輸入以下命令: sudo apt-get update sudo apt-get install -y mongodb-org

注意:如果執行“sudo apt-get update”命令後出現如下錯誤:

···
update completed, but some metadata was ignored due to errors.
E: 無法獲得鎖 /var/lib/dpkg/lockopen (11: 資源暫時不可用)
E: 無法鎖定管理目錄(/var/lib/dpkg/),是否有其他程序正佔用它?
···

請按照如下方法解決錯誤,也就是輸入以下三條命令:

sudo rm /var/cache/apt/archives/lock
sudo rm /var/lib/dpkg/lock
sudo apt-get update

執行上面三條命令以後,應該就可以順利完成apt-get update了。

安裝完成MongoDB以後,在終端輸入以下命令檢視MongoDB版本:

mongo -version

輸出版本資訊,表明安裝成功。

啟動和關閉mongodb命令如下:

sudo service mongodb start
sudo service mongodb stop

預設設定MongoDB是隨Ubuntu啟動自動啟動的。
輸入以下命令檢視是否啟動成功:

pgrep mongo -l   #注意:-l是英文字母l,不是阿拉伯數字1

檢視是否啟動成功

出現安裝錯誤的解決方案:
輸入“sudo service mongodb start”啟動mongodb的時候,如果報這個錯誤:Failed to start mongod.service: Unit not found
請按照如下步驟解決該錯誤:
(1)使用vim編輯器建立配置檔案

sudo vim /etc/systemd/system/mongodb.service

(2)在該配置檔案中新增如下內容:

[Unit]
Description=High-performance, schema-free document-oriented database
After=network.target

[Service]
User=mongodb
ExecStart=/usr/bin/mongod --quiet --config /etc/mongod.conf

[Install]
WantedBy=multi-user.target

儲存退出vim編輯器。
(3)輸入如下命令啟動mongodb:

sudo systemctl start mongodb
sudo systemctl status mongodb
Shell 命令
這時就可以啟動成功了。
以後,每次啟動和關閉MongoDB,就可以仍然使用如下命令:

sudo service mongodb start
sudo service mongodb stop

三、使用MongoDB

shell命令模式
輸入如下命令進入MongoDB的shell命令模式:

mongo
或者:sudo mongo

預設連線的資料庫是test資料庫,在此之前一定要確保你已經啟動了MongoDB,否則會出現錯誤,啟動之後執行成功,如下
mongo shell常用操作命令:

資料庫相關
show dbs:顯示資料庫列表
show collections:顯示當前資料庫中的集合(類似關係資料庫中的表tableshow users:顯示所有使用者
use yourDB:切換當前資料庫至yourDB
db.help() :顯示資料庫操作命令
db.yourCollection.help() :顯示集合操作命令,yourCollection是集合名

MongoDB沒有建立資料庫的命令,如果你想建立一個“School”的資料庫,先執行use School命令,之後做一些操作(如:建立聚集集合db.createCollection(‘teacher’)),這樣就可以建立一個名叫“School”的資料庫。
自動建立school資料庫
下面以一個School資料庫為例,在School資料庫中建立兩個集合teacher和student,並對student集合中的資料進行增刪改查基本操作(集合Collection相當於關係型資料庫中的表table)。

1、切換到School資料庫

use School #切換到School資料庫。MongoDB 無需預建立School資料庫,在使用時會自動建立

2、建立集合Collection

本章節我們為大家介紹如何使用 MongoDB 來建立集合。

MongoDB 中使用 createCollection() 方法來建立集合。

語法格式:

db.createCollection(name, options)
引數說明:
這裡寫圖片描述

name: 要建立的集合名稱
options: 可選引數, 指定有關記憶體大小及索引的選項
options 可以是如下引數:
在插入文件時,MongoDB 首先檢查固定集合的 size 欄位,然後檢查 max 欄位。

例項

在 test 資料庫中建立 runoob 集合:

> use test
switched to db test
> db.createCollection("runoob")
{ "ok" : 1 }
>
如果要檢視已有集合,可以使用 show collections 命令:

> show collections
runoob
system.indexes
下面是帶有幾個關鍵引數的 createCollection() 的用法:

建立固定集合 mycol,整個集合空間大小 6142800 KB, 文件最大個數為 10000 個。

> db.createCollection("mycol", { capped : true, autoIndexId : true, size :  6142800, max : 10000 } )
{ "ok" : 1 }
>
在 MongoDB 中,你不需要建立集合。當你插入一些文件時,MongoDB 會自動建立集合。

> db.mycol2.insert({"name" : "菜鳥教程"})
> show collections
mycol2
...
##建立一個聚集集合。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 字串都是 UTF-8 編碼。

時間戳
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)   

1、插入資料

與資料庫建立類似,插入資料時也會自動建立集合。
插入資料有兩種方式:insert和save。

db.student.insert({_id:1, sname: 'zhangsan', sage: 20}) #_id可選
db.student.save({_id:1, sname: 'zhangsan', sage: 22}) #_id可選

這兩種方式,其插入的資料中_id欄位均可不寫,會自動生成一個唯一的_id來標識本條資料。而insert和save不同之處在於:在手動插入_id欄位時,如果_id已經存在,insert不做操作,save做更新操作;如果不加_id欄位,兩者作用相同點都是插入資料。
insert和save新增的資料其結構是鬆散的,列屬性均不固定,根據新增的資料為準。先定義資料再插入,就可以一次性插入多條資料,
插入多條
執行完以上例子,student 已自動建立,這也說明 MongoDB 不需要預先定義 collection ,在第一次插入資料後,collection 會自動的建立。

2、查詢資料

MongoDB 查詢文件使用 find() 方法。

find() 方法以非結構化的方式來顯示所有文件。

語法
MongoDB 查詢資料的語法格式如下:

db.collection.find(query, projection)
query :可選,使用查詢操作符指定查詢條件
projection :可選,使用投影操作符指定返回的鍵。查詢時返回文件中所有鍵值, 只需省略該引數即可(預設省略)。
如果你需要以易讀的方式來讀取資料,可以使用 pretty() 方法,語法格式如下:

>db.col.find().pretty()
pretty() 方法以格式化的方式來顯示所有文件。

除了 find() 方法之外,還有一個 findOne() 方法,它只返回一個文件。

MongoDB 與 RDBMS Where 語句比較
如果你熟悉常規的 SQL 資料,通過下表可以更好的理解 MongoDB 的條件語句查詢:
這裡寫圖片描述
MongoDB AND 條件
MongoDB 的 find() 方法可以傳入多個鍵(key),每個鍵(key)以逗號隔開,即常規 SQL 的 AND 條件。
語法格式如下:

db.col.find({key1:value1, key2:value2}).pretty()

MongoDB OR 條件
MongoDB OR 條件語句使用了關鍵字 $or,語法格式如下:

db.col.find(
   {
      $or: [
         {key1: value1}, {key2:value2}
      ]
   }
).pretty()

AND 和 OR 聯合使用
以下例項演示了 AND 和 OR 聯合使用,類似常規 SQL 語句為: ‘where likes>50 AND (by = ‘菜鳥教程’ OR title = ‘MongoDB 教程’)’

db.col.find({"likes": {$gt:50}, $or: [{"by": "菜鳥教程"},{"title": "MongoDB 教程"}]}).pretty()

3、更新資料

MongoDB 更新文件
MongoDB 使用 update() 和 save() 方法來更新集合中的文件。接下來讓我們詳細來看下兩個函式的應用及其區別。

update() 方法
update() 方法用於更新已存在的文件。語法格式如下:

db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)

引數說明:

query : update的查詢條件,類似sql update查詢內where後面的。
update : update的物件和一些更新的操作符(如 s e t , inc…)等,也可以理解為sql update查詢內set後面的
upsert : 可選,這個引數的意思是,如果不存在update的記錄,是否插入objNew,true為插入,預設是false,不插入。
multi : 可選,mongodb 預設是false,只更新找到的第一條記錄,如果這個引數為true,就把按條件查出來多條記錄全部更新。
writeConcern :可選,丟擲異常的級別。
例項
我們在集合 col 中插入如下資料:

>db.col.insert({
    title: 'MongoDB 教程', 
    description: 'MongoDB 是一個 Nosql 資料庫',
    by: '菜鳥教程',
    url: 'http://www.runoob.com',
    tags: ['mongodb', 'database', 'NoSQL'],
    likes: 100
})

接著我們通過 update() 方法來更新標題(title):

>db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})     ##加$set 用處:僅修改目標行,否則不會保留其他行。
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })   # 輸出資訊
> db.col.find().pretty()
{
        "_id" : ObjectId("56064f89ade2f21f36b03136"),
        "title" : "MongoDB",
        "description" : "MongoDB 是一個 Nosql 資料庫",
        "by" : "菜鳥教程",
        "url" : "http://www.runoob.com",
        "tags" : [
                "mongodb",
                "database",
                "NoSQL"
        ],
        "likes" : 100
}
>
#可以看到標題(title)由原來的 "MongoDB 教程" 更新為了 "MongoDB"。

以上語句只會修改第一條發現的文件,如果你要修改多條相同的文件,則需要設定 multi 引數為 true。

>db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}},{multi:true})

save() 方法
save() 方法通過傳入的文件來替換已有文件。語法格式如下:

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

引數說明:
document : 文件資料。
writeConcern :可選,丟擲異常的級別。
例項
以下例項中我們替換了 _id 為 56064f89ade2f21f36b03136 的文件資料:

>db.col.save({
    "_id" : ObjectId("56064f89ade2f21f36b03136"),
    "title" : "MongoDB",
    "description" : "MongoDB 是一個 Nosql 資料庫",
    "by" : "Runoob",
    "url" : "http://www.runoob.com",
    "tags" : [
            "mongodb",
            "NoSQL"
    ],
    "likes" : 110
})
替換成功後,我們可以通過 find() 命令來檢視替換後的資料

>db.col.find().pretty()
{
        "_id" : ObjectId("56064f89ade2f21f36b03136"),
        "title" : "MongoDB",
        "description" : "MongoDB 是一個 Nosql 資料庫",
        "by" : "Runoob",
        "url" : "http://www.runoob.com",
        "tags" : [
                "mongodb",
                "NoSQL"
        ],
        "likes" : 110
}
> 

更多例項
只更新第一條記錄:

db.col.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } );

全部更新:

db.col.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true );

只新增第一條:

db.col.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false );

全部新增加進去:

db.col.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true );

全部更新:

db.col.update( { "count" : { $gt : 15 } } , { $inc : { "count" : 1} },false,true );

只更新第一條記錄:

db.col.update( { "count" : { $gt : 10 } } , { $inc : { "count" : 1} },false,false );

4、刪除資料

在前面的幾個章節中我們已經學習了MongoDB中如何為集合新增資料和更新資料。在本章節中我們將繼續學習MongoDB集合的刪除。

MongoDB remove()函式是用來移除集合中的資料。

MongoDB資料更新可以使用update()函式。在執行remove()函式前先執行find()命令來判斷執行的條件是否正確,這是一個比較好的習慣。

語法
remove() 方法的基本語法格式如下所示:

db.collection.remove(
   <query>,
   <justOne>
)

如果你的 MongoDB 是 2.6 版本以後的,語法格式如下:

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

引數說明:
query :(可選)刪除的文件的條件。
justOne : (可選)如果設為 true 或 1,則只刪除一個文件。
writeConcern :(可選)丟擲異常的級別。
例項
以下文件我們執行兩次插入操作:

>db.col.insert({title: 'MongoDB 教程', 
    description: 'MongoDB 是一個 Nosql 資料庫',
    by: '菜鳥教程',
    url: 'http://www.runoob.com',
    tags: ['mongodb', 'database', 'NoSQL'],
    likes: 100
})

使用 find() 函式查詢資料:

> db.col.find()
{ "_id" : ObjectId("56066169ade2f21f36b03137"), "title" : "MongoDB 教程", "description" : "MongoDB 是一個 Nosql 資料庫", "by" : "菜鳥教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
{ "_id" : ObjectId("5606616dade2f21f36b03138"), "title" : "MongoDB 教程", "description" : "MongoDB 是一個 Nosql 資料庫", "by" : "菜鳥教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
接下來我們移除 title 為 'MongoDB 教程' 的文件:

>db.col.remove({'title':'MongoDB 教程'})
WriteResult({ "nRemoved" : 2 })           # 刪除了兩條資料
>db.col.find()
……                                        # 沒有資料
如果你只想刪除第一條找到的記錄可以設定 justOne 為 1,如下所示:

>db.COLLECTION_NAME.remove(DELETION_CRITERIA,1)
如果你想刪除所有資料,可以使用以下方式(類似常規 SQL 的 truncate 命令):

>db.col.remove({})
>db.col.find()
>

5、條件運算子

條件操作符用於比較兩個表示式並從mongoDB集合中獲取資料。
MongoDB中條件操作符有:

(>) 大於 - $gt
(<) 小於 - $lt
(>=) 大於等於 - $gte
(<= ) 小於等於 - $lte

我們使用的資料庫名稱為”runoob” 我們的集合名稱為”col”,以下為我們插入的資料。

為了方便測試,我們可以先使用以下命令清空集合 “col” 的資料:

db.col.remove({})
插入以下資料

>db.col.insert({
    title: 'PHP 教程', 
    description: 'PHP 是一種建立動態互動性站點的強有力的伺服器端指令碼語言。',
    by: '菜鳥教程',
    url: 'http://www.runoob.com',
    tags: ['php'],
    likes: 200
})
>db.col.insert({title: 'Java 教程', 
    description: 'Java 是由Sun Microsystems公司於1995年5月推出的高階程式設計語言。',
    by: '菜鳥教程',
    url: 'http://www.runoob.com',
    tags: ['java'],
    likes: 150
})
>db.col.insert({title: 'MongoDB 教程', 
    description: 'MongoDB 是一個 Nosql 資料庫',
    by: '菜鳥教程',
    url: 'http://www.runoob.com',
    tags: ['mongodb'],
    likes: 100
})

使用find()命令檢視資料:

db.col.find()

MongoDB (>) 大於操作符 - $gt
如果你想獲取 “col” 集合中 “likes” 大於 100 的資料,你可以使用以下命令:

db.col.find({"likes" : {$gt : 100}})
類似於SQL語句:
Select * from col where likes > 100;
輸出結果:

> db.col.find({"likes" : {$gt : 100}})
{ "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一種建立動態互動性站點的強有力的伺服器端指令碼語言。", "by" : "菜鳥教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 }
{ "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司於1995年5月推出的高階程式設計語言。", "by" : "菜鳥教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 }
> 
MongoDB(>=)大於等於操作符 - $gte
如果你想獲取"col"集合中 "likes" 大於等於 100 的資料,你可以使用以下命令:

db.col.find({likes : {$gte : 100}})
類似於SQL語句:

Select * from col where likes >=100;
輸出結果:

> db.col.find({likes : {$gte : 100}})
{ "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一種建立動態互動性站點的強有力的伺服器端指令碼語言。", "by" : "菜鳥教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 }
{ "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司於1995年5月推出的高階程式設計語言。", "by" : "菜鳥教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 }
{ "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一個 Nosql 資料庫", "by" : "菜鳥教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }
> 
MongoDB (<) 小於操作符 - $lt
如果你想獲取"col"集合中 "likes" 小於 150 的資料,你可以使用以下命令:

db.col.find({likes : {$lt : 150}})
類似於SQL語句:

Select * from col where likes < 150;
輸出結果:

> db.col.find({likes : {$lt : 150}})
{ "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一個 Nosql 資料庫", "by" : "菜鳥教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }
MongoDB (<=) 小於操作符 - $lte
如果你想獲取"col"集合中 "likes" 小於等於 150 的資料,你可以使用以下命令:

db.col.find({likes : {$lte : 150}})
類似於SQL語句:

Select * from col where likes <= 150;
輸出結果:

> db.col.find({likes : {$lte : 150}})
{ "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司於1995年5月推出的高階程式設計語言。", "by" : "菜鳥教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 }
{ "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一個 Nosql 資料庫", "by" : "菜鳥教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }
MongoDB 使用 (<) 和 (>) 查詢 - $lt 和 $gt
如果你想獲取"col"集合中 "likes" 大於100,小於 200 的資料,你可以使用以下命令:

db.col.find({likes : {$lt :200, $gt : 100}})
類似於SQL語句:

Select * from col where likes>100 AND  likes<200;
輸出結果:

> db.col.find({likes : {$lt :200, $gt : 100}})
{ "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司於1995年5月推出的高階程式設計語言。", "by" : "菜鳥教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 }
> 

6、MongoDB Limit與Skip方法

MongoDB Limit() 方法
如果你需要在MongoDB中讀取指定數量的資料記錄,可以使用MongoDB的Limit方法,limit()方法接受一個數字引數,該引數指定從MongoDB中讀取的記錄條數。

語法
limit()方法基本語法如下所示:

db.COLLECTION_NAME.find().limit(NUMBER)

例項
集合 col 中的資料如下:

 db.col.find({},{"title":1,_id:0}).limit(2)      #  _id:0(投影1:表示顯示0:表示隱藏)
{ "title" : "PHP 教程" }
{ "title" : "Java 教程" }

注:如果你們沒有指定limit()方法中的引數則顯示集合中的所有資料。

MongoDB Skip() 方法
我們除了可以使用limit()方法來讀取指定數量的資料外,還可以使用skip()方法來跳過指定數量的資料,skip方法同樣接受一個數字引數作為跳過的記錄條數。

語法
skip() 方法指令碼語法格式如下:

>db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
例項
以下例項只會顯示第二條文件資料

>db.col.find({},{"title":1,_id:0}).limit(1).skip(1)
{ "title" : "Java 教程" }
>
注:skip()方法預設引數為 0

7.MongoDB排序

MongoDB sort()方法
在MongoDB中使用使用sort()方法對資料進行排序,sort()方法可以通過引數指定排序的欄位,並使用 1 和 -1 來指定排序的方式,其中 1 為升序排列,而-1是用於降序排列。

語法
sort()方法基本語法如下所示:

>db.COLLECTION_NAME.find().sort({KEY:1})
例項
col 集合中的資料如下:

{ "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一種建立動態互動性站點的強有力的伺服器端指令碼語言。", "by" : "菜鳥教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 }
{ "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司於1995年5月推出的高階程式設計語言。", "by" : "菜鳥教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 }
{ "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一個 Nosql 資料庫", "by" : "菜鳥教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }
以下例項演示了 col 集合中的資料按欄位 likes 的降序排列:

>db.col.find({},{"title":1,_id:0}).sort({"likes":-1})
{ "title" : "PHP 教程" }
{ "title" : "Java 教程" }
{ "title" : "MongoDB 教程" }
>

8.MongoDB索引

索引通常能夠極大的提高查詢的效率,如果沒有索引,MongoDB在讀取資料時必須掃描集合中的每個檔案並選取那些符合查詢條件的記錄。

這種掃描全集合的查詢效率是非常低的,特別在處理大量的資料時,查詢可以要花費幾十秒甚至幾分鐘,這對網站的效能是非常致命的。

索引是特殊的資料結構,索引儲存在一個易於遍歷讀取的資料集合中,索引是對資料庫表中一列或多列的值進行排序的一種結構

ensureIndex() 方法
MongoDB使用 ensureIndex() 方法來建立索引。

語法
ensureIndex()方法基本語法格式如下所示:

db.COLLECTION_NAME.ensureIndex({KEY:1})
語法中 Key 值為你要建立的索引欄位,1為指定按升序建立索引,如果你想按降序來建立索引指定為-1即可。

例項

db.col.ensureIndex({"title":1})

ensureIndex() 方法中你也可以設定使用多個欄位建立索引(關係型資料庫中稱作複合索引)。

db.col.ensureIndex({"title":1,"description":-1})

ensureIndex() 接收可選引數,可選引數列表如下:
這裡寫圖片描述
例項在後臺建立索引:

db.values.ensureIndex({open: 1, close: 1}, {background: true})

通過在建立索引時加background:true 的選項,讓建立工作在後臺執行

8.MongoDB 聚合

MongoDB中聚合(aggregate)主要用於處理資料(諸如統計平均值,求和等),並返回計算後的資料結果。有點類似sql語句中的 count(*)。

aggregate() 方法
MongoDB中聚合的方法使用aggregate()。

語法
aggregate() 方法的基本語法格式如下所示:

db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)

例項

集合中的資料如下:

{
   _id: ObjectId(7df78ad8902c)
   title: 'MongoDB Overview', 
   description: 'MongoDB is no sql database',
   by_user: 'runoob.com',
   url: 'http://www.runoob.com',
   tags: ['mongodb', 'database', 'NoSQL'],
   likes: 100
},
{
   _id: ObjectId(7df78ad8902d)
   title: 'NoSQL Overview', 
   description: 'No sql database is very fast',
   by_user: 'runoob.com',
   url: 'http://www.runoob.com',
   tags: ['mongodb', 'database', 'NoSQL'],
   likes: 10
},
{
   _id: ObjectId(7df78ad8902e)
   title: 'Neo4j Overview', 
   description: 'Neo4j is no sql database',
   by_user: 'Neo4j',
   url: 'http://www.neo4j.com',
   tags: ['neo4j', 'database', 'NoSQL'],
   likes: 750
},
現在我們通過以上集合計算每個作者所寫的文章數,使用aggregate()計算結果如下:
## _id 指定根據那個屬性分組
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
{
   "result" : [
      {
         "_id" : "runoob.com",
         "num_tutorial" : 2
      },
      {
         "_id" : "Neo4j",
         "num_tutorial" : 1
      }
   ],
   "ok" : 1
}

以上例項類似sql語句: select by_user, count(*) from mycol group by by_user

在上面的例子中,我們通過欄位by_user欄位對資料進行分組,並計算by_user欄位相同值的總和。

下表展示了一些聚合的表示式:
這裡寫圖片描述
管道的概念
管道在Unix和Linux中一般用於將當前命令的輸出結果作為下一個命令的引數。

MongoDB的聚合管道將MongoDB文件在一個管道處理完畢後將結果傳遞給下一個管道處理。管道操作是可以重複的。

表示式:處理輸入文件並輸出。表示式是無狀態的,只能用於計算當前聚合管道的文件,不能處理其它的文件。

這裡我們介紹一下聚合框架中常用的幾個操作: