005.MongoDB索引及聚合

一 MongoDB 索引

索引一般可以極大的提升查詢的效率,若是沒有索引,MongoDB在讀取數據時必須掃描集合中的每一個文件並選取那些符合查詢條件的記錄。
這種掃描全集合的查詢效率是很是低的,特別在處理大量的數據時,查詢能夠要花費幾十秒甚至幾分鐘,這對網站的性能是很是致命的。
索引是特殊的數據結構,索引存儲在一個易於遍歷讀取的數據集合中,索引是對數據庫表中一列或多列的值進行排序的一種結構。

1.1 createIndex() 方法

MongoDB使用 createIndex() 方法來建立索引。
語法格式:
  1 > db.collection.createIndex(keys, options)
參數說明:
  • Key :key值爲你要建立的索引字段;
  • options:options爲1 表示按升序建立索引,爲-1表示按降序來建立索引。
  1 [root@uhost ~]# mongo --host 172.24.9.225 --port 27017 -u useradmin -p useradmin
  2 > use mydb
  3 > db.age01.createIndex({age: 1})
  4 {
  5         "createdCollectionAutomatically" : false,
  6         "numIndexesBefore" : 1,
  7         "numIndexesAfter" : 2,
  8         "ok" : 1
  9 }
 
createIndex() 方法中你也能夠設置使用多個字段建立索引(關係型數據庫中稱做複合索引)。
  1 > db.age01.createIndex({age: 1, tel: -1})
  2 {
  3         "createdCollectionAutomatically" : false,
  4         "numIndexesBefore" : 2,
  5         "numIndexesAfter" : 3,
  6         "ok" : 1
  7 }
 

1.2 createIndex() 可選參數

可選參數列表以下:
Parameter
Type
Description
background
Boolean
建索引過程會阻塞其它數據庫操做,background可指定之後臺方式建立索引,即增長 "background" 可選參數。 "background" 默認值爲false。
unique
Boolean
創建的索引是否惟一。指定爲true建立惟一索引。默認值爲false.
name
string
索引的名稱。若是未指定,MongoDB的經過鏈接索引的字段名和排序順序生成一個索引名稱。
sparse
Boolean
對文檔中不存在的字段數據不啓用索引;這個參數須要特別注意,若是設置爲true的話,在索引字段中不會查詢出不包含對應字段的文檔.。默認值爲 false.
expireAfterSeconds
integer
指定一個以秒爲單位的數值,完成 TTL設定,設定集合的生存時間。
v
index version
索引的版本號。默認的索引版本取決於mongod建立索引時運行的版本。
weights
document
索引權重值,數值在 1 到 99,999 之間,表示該索引相對於其餘索引字段的得分權重。
default_language
string
對於文本索引,該參數決定了停用詞及詞幹和詞器的規則的列表。 默認爲英語
language_override
string
對於文本索引,該參數指定了包含在文檔中的字段名,語言覆蓋默認的language,默認值爲 language.
  1 > db.age01.createIndex({age: 1, tel: -1},{background: 'true'})
  2 {
  3         "numIndexesBefore" : 3,
  4         "numIndexesAfter" : 3,
  5         "note" : "all indexes already exist",
  6         "ok" : 1
  7 }
 

1.3 查看索引

  1 > db.age01.getIndexes()

1.4 查看集合索引大小

  1 > db.age01.totalIndexSize()

1.5 刪除指定集合

  1 > db.age01.dropIndex('age_1_tel_-1')
  2 { "nIndexesWas" : 3, "ok" : 1 }
 

1.6 刪除全部索引

  1 > db.age01.dropIndexes()
  2 {
  3         "nIndexesWas" : 2,
  4         "msg" : "non-_id indexes dropped for collection",
  5         "ok" : 1
  6 }
 

二 MongoDB聚合

2.1 aggregate() 方法

MongoDB中聚合(aggregate)主要用於處理數據(諸如統計平均值,求和等),並返回計算後的數據結果。有點相似sql語句中的 count(*)。
MongoDB中聚合的方法使用aggregate()。
語法格式:
  1 > db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
  2 [root@uhost ~]# mongo --host 172.24.9.225 --port 27017 -u useradmin -p useradmin
  3 > use mydb
  4 > db.age01.aggregate([{$group: {_id: "$tel", tel: {$sum: 1}}}])
  5 { "_id" : "123456784", "tel" : 1 }
  6 { "_id" : "188888888", "tel" : 2 }
  7 { "_id" : "155555555", "tel" : 1 }
 
提示:以上操做爲統計全部各個tel的個數,相似select tel count(*) from age01 group by tel。

2.2 聚合表達式

表達式
描述
實例
$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"}}}])

三 管道

3.1 管道的概念

管道在Unix和Linux中通常用於將當前命令的輸出結果做爲下一個命令的參數。
MongoDB的聚合管道將MongoDB文檔在一個管道處理完畢後將結果傳遞給下一個管道處理。管道操做是能夠重複的。
表達式:處理輸入文檔並輸出。表達式是無狀態的,只能用於計算當前聚合管道的文檔,不能處理其它的文檔。
聚合框架經常使用操做:
  • $project:修改輸入文檔的結構。能夠用來重命名、增長或刪除域,也能夠用於建立計算結果以及嵌套文檔。
  • $match:用於過濾數據,只輸出符合條件的文檔。$match使用MongoDB的標準查詢操做。
  • $limit:用來限制MongoDB聚合管道返回的文檔數。
  • $skip:在聚合管道中跳過指定數量的文檔,並返回餘下的文檔。
  • $unwind:將文檔中的某一個數組類型字段拆分紅多條,每條包含數組中的一個值。
  • $group:將集合中的文檔分組,可用於統計結果。
  • $sort:將輸入文檔排序後輸出。
  • $geoNear:輸出接近某一地理位置的有序文檔。
  1 [root@uhost ~]# mongo --host 172.24.9.225 --port 27017 -u useradmin -p useradmin
  2 > use mydb
  3 > db.age01.aggregate({$project: {name: 1, tel: 1,}}).pretty()
 
001
提示:_id默認爲輸出,可經過_id: 0關閉_id的輸出。
  1 > db.age01.aggregate([{$match : {age: {$gt: '10', $lt: '20'}}},{$group: {_id: null, count: {$sum: 1}}}])
  2 { "_id" : null, "count" : 2 }			#$match過濾出符合條件的數據,而後$group進行再次處理。
 

3.2 時間聚合

  1 db.getCollection('m_msg_tb').aggregate(
  2 [
  3     {$match:{m_id:10001,mark_time:{$gt:new Date(2017,8,0)}}},
  4     {$group: {
  5        _id: {$dayOfMonth:'$mark_time'},
  6         pv: {$sum: 1}
  7         }
  8     },
  9     {$sort: {"_id": 1}}
 10 ])
 
時間關鍵字以下:
  • $dayOfYear: 返回該日期是這一年的第幾天(整年 366 天)。
  • $dayOfMonth: 返回該日期是這一個月的第幾天(1到31)。
  • $dayOfWeek: 返回的是這個周的星期幾(1:星期日,7:星期六)。
  • $year: 返回該日期的年份部分。
  • $month: 返回該日期的月份部分( 1 到 12)。
  • $week: 返回該日期是所在年的第幾個星期( 0 到 53)。
  • $hour: 返回該日期的小時部分。
  • $minute: 返回該日期的分鐘部分。
  • $second: 返回該日期的秒部分(以0到59之間的數字形式返回日期的第二部分,但能夠是60來計算閏秒)。
  • $millisecond:返回該日期的毫秒部分( 0 到 999)。
  • $dateToString: { $dateToString: { format: , date: } }。
相關文章
相關標籤/搜索