天天看點

MongoDB排序、索引、聚合

MongoDB 排序

在MongoDB中使用使用sort()方法對資料進行排序,sort()方法可以通過參數指定排序的字段,并使用 1 和 -1 來指定排序的方式,其中 1 為升序排列,而-1是用于降序排列。

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

col 集合中的資料如下:

以下執行個體示範了 col 集合中的資料按字段 likes 的降序排列:

MongoDB 索引

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

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

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

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

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

文法中 Key 值為你要建立的索引字段,1為指定按升序建立索引,如果你想按降序來建立索引指定為-1即可。

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

ensureIndex() 接收可選參數,可選參數清單如下:

<col>

Parameter

Type

Description

background

Boolean

建索引過程會阻塞其它資料庫操作,background可指定以背景方式建立索引,即增加 "background" 可選參數。 "background" 預設值為false。

unique

建立的索引是否唯一。指定為true建立唯一索引。預設值為false.

name

string

索引的名稱。如果未指定,MongoDB的通過連接配接索引的字段名和排序順序生成一個索引名稱。

dropDups

在建立唯一索引時是否删除重複記錄,指定 true 建立唯一索引。預設值為 false.

sparse

對文檔中不存在的字段資料不啟用索引;這個參數需要特别注意,如果設定為true的話,在索引字段中不會查詢出不包含對應字段的文檔.。預設值為 false.

expireAfterSeconds

integer

指定一個以秒為機關的數值,完成 TTL設定,設定集合的生存時間。

v

index version

索引的版本号。預設的索引版本取決于mongod建立索引時運作的版本。

weights

document

索引權重值,數值在 1 到 99,999 之間,表示該索引相對于其他索引字段的得分權重。

default_language

對于文本索引,該參數決定了停用詞及詞幹和詞器的規則的清單。 預設為英語

language_override

對于文本索引,該參數指定了包含在文檔中的字段名,語言覆寫預設的language,預設值為 language.

在背景建立索引:

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

MongoDB 聚合

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

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

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

集合中的資料如下:

現在我們通過以上集合計算每個作者所寫的文章數,使用aggregate()計算結果如下:

以上執行個體類似sql語句: select by_user, count(*) from mycol group by by_user

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

下表展示了一些聚合的表達式:

表達式

描述

執行個體

$sum

計算總和。

db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])

$avg

計算平均值

db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])

$min

擷取集合中所有文檔對應值得最小值。

db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])

$max

擷取集合中所有文檔對應值得最大值。

db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])

$push

在結果文檔中插入值到一個數組中。

db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])

$addToSet

在結果文檔中插入值到一個數組中,但不建立副本。

db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])

$first

根據資源文檔的排序擷取第一個文檔資料。

db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])

$last

根據資源文檔的排序擷取最後一個文檔資料

db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])

管道在Unix和Linux中一般用于将目前指令的輸出結果作為下一個指令的參數。

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

表達式:處理輸入文檔并輸出。表達式是無狀态的,隻能用于計算目前聚合管道的文檔,不能處理其它的文檔。

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

$project:修改輸入文檔的結構。可以用來重命名、增加或删除域,也可以用于建立計算結果以及嵌套文檔。

$match:用于過濾資料,隻輸出符合條件的文檔。$match使用MongoDB的标準查詢操作。

$limit:用來限制MongoDB聚合管道傳回的文檔數。

$skip:在聚合管道中跳過指定數量的文檔,并傳回餘下的文檔。

$unwind:将文檔中的某一個數組類型字段拆分成多條,每條包含數組中的一個值。

$group:将集合中的文檔分組,可用于統計結果。

$sort:将輸入文檔排序後輸出。

$geoNear:輸出接近某一地理位置的有序文檔。

1、$project執行個體

這樣的話結果中就隻還有_id,tilte和author三個字段了,預設情況下_id字段是被包含的,如果要想不包含_id話可以這樣:

2.$match執行個體

$match用于擷取分數大于70小于或等于90記錄,然後将符合條件的記錄送到下一階段$group管道操作符進行處理。

3.$skip執行個體

經過$skip管道操作符處理後,前五個文檔被"過濾"掉。

繼續閱讀