MangoDB高階應用
MongoDB高階應用
Author:SimpleWu
聚合
聚合(aggregate)主要用於處理資料(諸如統計平均值,求和等),並返回計算後的資料結果。有點類似sql語句中的 count(*)。
//統計員工總數 db.emp.aggregate([{$count:"countName"}]) //或者 db.emp.find().count()
$group
使用$group是對篩選的資料進行分組。類似於mysql中的group by關鍵字。
//根據員工gender來分組並且統計數量 db.emp.aggregate([{$group : {_id : "$gender", count: {$sum : 1}}}])
說明:
- 這裡_id是表示分組的欄位,名字是固定的。
- count表示聚合生成列的名稱。
- $sum表示聚合函式。
- 1統計的值,其他聚合函式也可以是欄位。
聚合表示式
表示式 | 描述 | 例項 |
---|---|---|
$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"}}}]) |
這些聚合函式基本上與mysql,oracle中效果是一致的。
索引
所以這東西學習過資料庫的都知道是不可缺少的,當然我們的MangoDB也是有的。
索引通常能夠極大的提高查詢的效率,如果沒有索引,MongoDB在讀取資料時必須掃描集合中的每個文件,並選取那些符合查詢條件的記錄。
建立索引語法:
db.collection.createIndex(keys, options) /* key:你要建立的索引欄位,1 為指定按升序建立索引,如果你想按降序來建立索引指定為 -1 即可。如果多個欄位使用,隔開 */ db.emp.createIndex({"name":1})#建立單列索引 db.emp.createIndex({"name":1,"age":-1})#建立多列索引。
索引的常見操作:
//檢視集合索引 db.emp.getIndexes() //檢視集合索引大小 db.emp.totalIndexSize() //刪除集合所有索引 db.emp.dropIndexes() //刪除集合指定索引 db.emp.dropIndex("索引名稱")
索引的種類、
在mysql裡面索引有許多種類當然我們的MongoDB中也有很多種類:id索引、單鍵索引、多鍵索引、複合索引、過期索引、全文索引。
id索引
ID索引也稱為主鍵索引,是我們建立一個集合時,自動建立的索引。
集合的預設排序是按照id來進行排序的。在mongodb中id是根據ObjectId()來生成的,這個順序是以時間撮來進行生成。
單鍵索引
單鍵索引是最普通的索引。
和id索引不同,單鍵索引不會自動建立,需要我們手動建立。
db.col.createIndex({"name":1})//建立單列索引,對name列建立索引
多鍵索引
多鍵索引和單鍵索引建立形式相同,區別在於欄位的值。
單鍵索引:值是一個單一的值,例如:字串,數字或者日期。
多鍵索引:值有多個記錄,例如:陣列。
db.emp.createIndex({"name":1,"age":-1})//建立多列索引,對name和age建立索引
複合索引
當我們的查詢條件不只一個時,就需要建立符合索引。符合索引是在多個列上同時建立索引。
db.col.createIndex({"name":1,"age":-1})//建立複合索引。
索引的命名
預設情況下,索引的命名是列+1或者-1,這種方式不是很方面記憶,而且刪除是也不太方面。這時候我們就需要為索引建立一個名稱。
//建立索引並命名為ix_name。 db.students.createIndex({name:-1},{name:"ix_name"})
唯一索引
我們可以為索引新增一個唯一性,從而儲存該列的資料不允許重複。
//建立索引並命名為ix_name。 db.students.createIndex({name:-1},{name:"ix_name",unique:true})
過期索引
過期索引:就是在一段時間後會自動過期的索引。在索引過期後,相應的資料也會被刪除。
適合儲存一些希望一段時間後會失效的資料,比如使用者登入資訊,儲存的日誌等。
db.collections.createIndex({time:1},{expireAfterSeconds:10})
過期索引的一些限制:
- 過期索引的值必須是指定的時間型別,必須使用ISODate或者ISODate陣列,不能使用時間撮,否則不會被自動刪除。
- 如果指定的是ISODate陣列,則按照最小時間刪除。
- 過期索引不能是複合索引。
- 刪除時間是有一定的誤差,由於刪除過程是由後臺程式每60秒跑一次,而且刪除資料也需要一定的時間。所以存在誤差。
全文索引
當要對一篇文章中的文字內容進行搜尋的時候,這個時候可以考慮全文索引。全文索引可以加快檢索內容關鍵字的效率。全文索引只能對字串或者字串陣列有效。
//建立全文索引 db.students.createIndex({name:"text",info:"text"})
使用全文索引
建立好全文索引後,我們就可以來使用全文索引,使用全文索引需要使用$text和$search兩個運算子。
//查詢全文索引中包含了zhangsan的文件。 db.students.find({$text:{$search:"zhangsan"}}) //查詢全文索引中包含了zhangsan或者zhangsanfeng的文件。 db.students.find({$text:{$search:"zhangsan zhangsanfeng"}}) //查詢全文索引中包含了zhangsan,但不包含zhangsanfeng的文件。 db.students.find({$text:{$search:"zhangsan -zhangsanfeng"}}) //查詢全文索引中包含了zhangsan和zhangsanfeng的文件。 db.students.find({$text:{$search:"\"zhangsan\" \"zhangsanfeng\""}})
全文索引的相似度
我們在百度中搜索時,經常會看到和我們關鍵字匹配度越高的,排行就越靠前。在mongodb中,我們還可以返回查詢結果的相似度,與sort一起使用效果會更好。
使用方式:在find後面跟上{score:{$meta:"textScore"}}
db.students.find({$text:{$search:"zhangsan"}},{score:{$meta:"textScore"}}) .sort({score:{$meta:"textScore"}})
全文索引的限制
- 每次查詢只能指定一個text。
- text操作符不能出現在$nor查詢中。
- 查詢中如果包含了text則hint將不再起作用。
- mongodb的全文索引對中文支援不是很好。
索引的注意事項
索引像一把雙刃劍,用得好可以提高查詢效率,如果用不好可能會導致效能的降低。
- $where和$exists完全不能走索引
- ne取反操作效率很低
- $not、$nin$or、$in
explain執行計劃
索引的效能如何,我們可以通過explain執行計劃來進行分析,從而使索引的效能達到最優。
explain的使用方式非常簡單,我們只需要在執行的find()命令後新增一個explain()方法即可。
db.students.find().explain();
文件之間的關係
很多時候資料庫中的資料不是單獨存在的,資料和資料之間會有一些相互之間的聯絡。我們mongodb可以配置這種資料之間的關係。
文件之間的關係
- 一對一(one to one)
- 一對多(one to many)
- 多對一(many to one)
- 多對多(many to many)
每種關係又可以有兩種方式來實現。
嵌入式:巢狀在一個document文件中。
引用式:通過外來鍵引用的方式來實現。
Java操作MongoDB
下載MongoDB驅動http://mongodb.github.io/mongo-java-driver/
<dependency> <groupId>org.mongodb</groupId> <artifactId>mongodb-driver</artifactId> <version>3.9.0</version> </dependency>
連線資料庫,你需要指定資料庫名稱,如果指定的資料庫不存在,mongo會自動建立資料庫。
public static void main( String args[] ){ try{ // 連線到 mongodb 服務 MongoClient mongoClient = new MongoClient( "localhost" , 27017 ); // 連線到資料庫 MongoDatabase mongoDatabase = mongoClient.getDatabase("students"); System.out.println("Connect to database successfully"); }catch(Exception e){ System.err.println( e.getClass().getName() + ": " + e.getMessage() ); } }
我們可以使用 com.mongodb.client.MongoDatabase 類中的createCollection()來建立集合
我們可以使用com.mongodb.client.MongoCollection類的 insertMany() 方法來插入一個文件。
我們可以使用 com.mongodb.client.MongoCollection 類中的 find() 方法來獲取集合中的所有文件。
你可以使用 com.mongodb.client.MongoCollection 類中的 updateMany() 方法來更新集合中的文件。
要刪除集合中的第一個文件,首先你需要使用com.mongodb.DBCollection類中的 findOne()方法來獲取第一個文件,然後使用remove 方法刪除。