python 爬蟲(十三)MongoDB基礎:增刪改查操作 + MongoDB 聚合 + 遊標的概念和操作 + B tree + hash索引 + 索引的常用命令(創建,刪除等)

小知識:(列表去掉[]:)

a = ['123','23']
b = ''.join(a)
print(b)

在這裏插入圖片描述

文章目錄

一、MongoDB增刪改查操作


1. 增加:insert方法


首先要明確一點,MongoDB存儲的時文檔,文檔其實就是json格式的對象。

語法:

db.collectionName(集合名).insert(document(文檔))

(1)增加單篇文檔(一條數據)


  • 增加單篇文檔
格式:
db.集合名.insert({})
即:
db.collectionName.insert({title:’nice day’})

在這裏插入圖片描述

  • 增加單個文檔,並指定_id
db.collectionName.insert({_id:8,age:78,name:’lisi’})

(2)增加多個文檔(多條數據)


格式:
db.集合名.insert([{},{},{}])
即:
db.collectionName.insert(
[
{time:'friday',study:'mongodb'},
{_id:9,gender:'male',name:'QQ'}
]
)

在這裏插入圖片描述
查看當前文檔內的數據

db.集合名.find()

在這裏插入圖片描述


2. 刪除:remove


  • 語法:
db.collection.remove(查詢表達式, 選項)

選項是指 {justOne:true/false},是否只刪一行, 默認爲false全部刪除,爲true則刪除一行

  • 注意:
  1. 查詢表達式依然是個json對象 {age:20}
  2. 查詢表達式匹配的行,將被刪掉.
  3. 如果不寫查詢表達式,collections中的所有文檔將被刪掉

查詢表達式相當於條件,查到符合表達式的文檔進行刪除操作


(1)刪除符合條件的文檔


  • 語法:
db.stu.remove({name:"張三"})

在這裏插入圖片描述


(2)刪除大於某個值的文檔:$gt


  • 語法:
db.stu.remove({age:{$gt:500}})

在這裏插入圖片描述


(3)刪除小於某個值的數據:$lt


  • 語法:
db.stu.remove({age:{$lt:11}})

在這裏插入圖片描述


(4)刪除小於等於某個值的數據:$lte


  • 語法:
db.stu.remove({age:{$lte:11}})

(5)刪除大於等於:$gte


  • 語法:
db.stu.remove({age:{$gte:11}})

(6)刪除不等於:$ne


  • 語法:
db.stu.remove({age:{$ne:12}})

在這裏插入圖片描述


(7)刪除文檔,只刪除一個:{justOne:true}


該選項有兩種寫法:

  • 第一種:直接在查詢表達式後面寫true
    語法:
    db.stu.remove({"age":10},true)
    
    在這裏插入圖片描述
  • 第二種:在查詢語句後面加{justOne:true}
    語法:
    db.stu.remove({"age":10},{justOne:true})
    
    在這裏插入圖片描述

注意:刪除的一條數據是從上往下找到的第一條文檔


3. 更新 update


  • 語法:
db.collection.update(查詢表達式,新值,選項)

新值:


注意:如果使用下面語句,不是更新數據,而是更新文檔。更新就是用新文檔替換舊文檔。

db.stu.update({name:"one"},{name:"two"})

案例:
在這裏插入圖片描述

總結:所以update操作想要更新文檔內容,必須和更新的操作符配合使用。


操作符:(1)$set 修改某列的值


  • 語法:
db.stu.update({name:”jj”},{$set:{name:”kk”}})

在這裏插入圖片描述


操作符(2)$unset 刪除某個列


  • 語法:
db.stu.update({name:”wangwu”},{$unset:{tag:1})

比如刪除wangwu的tag,不需要知道他的tag值,直接用1代替,可以認爲後面1是固定的
在這裏插入圖片描述


操作符(3)$rename 重命名某個列


注意:重命名的是key

  • 語法:
db.stu.update({name:"wangwu"},{$rename:{name:"firstname"}})

意思就是將name這個key名字改爲firstname
在這裏插入圖片描述


操作符(4)$inc 增長某個列(可以增長正數也可以增長負數);自增某個列的鍵的值


  • 語法:
db.stu.update({name:"xiaoming"},{$inc:{age:10}})### age增加10

在這裏插入圖片描述
也可以爲負
在這裏插入圖片描述


選項:


Option的作用:{upsert:true/false,multi:true/false}

  • upsert:true/false:默認爲false,如果爲true,不存在則插入,如果存在就更新。
  • multi:true/false默認爲false,爲true時,會更新匹配到的所有數據。

選項符(1)upsert:true/false:默認false,true則不存在插入,存在更新


  • 語法:
db.stu.update({age:200},{$set:{name:"xiaohong3",age:103}},{upsert:true})

注意:能匹配到的,匹配第一個符合條件的更新他

注意:匹配不到的,沒有的就會插入進來
在這裏插入圖片描述


選項符(2)multi:true/false:默認爲false,只修改一行,爲true時,會更新所有的數據


  • 語法:
db.stu.update({age:12},{$inc:{age:10}},{multi:true})

在這裏插入圖片描述


4. 查找:find


  • 語法:
db.collection.find(查詢表達式,查詢的列);
db.collections.find(表達式,{1:1,2:1});

(1)$nin --> not in:查詢不在範圍內的


db.stu.find({age:{$nin:[1,2,4]}},{_id=0,age=1})

在這裏插入圖片描述

最後面的是規定要顯示或者不顯示的列

注意:

  • _id:只有在指定=不顯示,纔會沒有,不寫_id=0默認顯示

  • 其他類,不指定默認不顯示

  • 0代表不顯示,1代表顯示


(2)db.stu.find():查詢所有文檔


  • 查詢所有文檔的所有內容
db.stu.find()
  • 查詢所有文檔,最後顯示gender屬性 (_id屬性默認總是查出來)
 db.stu.find({},{gendre:1})
  • 查詢所有文檔,最後顯示gender屬性,且不查詢_id屬性
db.stu.find({},{gender:1, _id:0})
  • 查詢所有gender屬性值爲male的文檔中的name屬性
db.stu.find({gender:’male’},{name:1,_id:0});

(3)all:指數組所有單元匹配,就是指我指定的內容都要有,通過一個list來指定


db.stu.find({hobby:{$all:["aa","bb"]}})

在這裏插入圖片描述


(4)$exists:是否含有默個列


  • {exists:1}表示存在指定字段。
db.stu.find({hobby:{$exists:1}})

在這裏插入圖片描述

  • $exists:0 :不存在某個列
db.stu.find({hobby:{$exists:0}})

在這裏插入圖片描述


(5)查詢表達式查詢多個字段


db.stu.find({name:"李四",age:10}).pretty()

在這裏插入圖片描述
相當於:
在這裏插入圖片描述
pretty()可寫可不寫

注意: MongoDB 的 find() 方法可以傳入多個鍵(key),每個鍵(key)以逗號隔開,及常規 SQL 的 AND 條件。類似於 WHERE 語句:WHERE by=‘來源’ AND title='題目。


(6)find常用查詢方法


  • limit() ## 分頁,取幾行
db.COLLECTION_NAME.find().limit(NUMBER)
  • skip() ## 跳過幾行
db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
db.COLLECTION_NAME.find().skip(NUMBER).limit(NUMBER)
  • sort() ## 排序,KEY:1升序;KEY:-1降序
db.COLLECTION_NAME.find().sort({KEY:1})
  • count() ## 計數,返回行數
 db.mycol.count()

(7)find查詢表達式


  • {filed:value} ,是指查詢field列的值爲value的文檔
  • $lt小於
    db.stu.find({age:{$lt:10}},{name:1,age:1})
    
  • $lte小於等於
  • $gt 大於
  • $gte大於等於
  • $ne — != 查詢表達式
  • {field:{$ne:value}} —作用:查filed列的值 不等於 value 的文檔
    db.goods.find({cat_id:{$ne:3}},{cat_id:1,goods_id:1,goods_name:1,_id:0})
    //查詢cat_id不等3的數據
    
  • $nor ## 所有條件都不滿足
    {$nor:[條件1,條件2]} 是指 所有條件都不滿足的文檔爲真返回
  • $and
    {$and:[條件1,條件2]} 是指 所有條件都滿足,就爲真
  • $or
    {$or:[條件1,條件2]} 是指 條件1和條件2有一個滿足,就爲真

5. 查詢案例


  • //主鍵爲32的商品
db.goods.find({goods_id:32},{goods_id:1})

在這裏插入圖片描述

  • //不屬第3欄目的所有商品($ne)
db.goods.find({cat_id:{$ne:3}},{cat_id:1})

在這裏插入圖片描述

  • //本店價格高於3000元的商品{$gt}
db.goods.find({shop_price:{$gt:3000}},{shop_price:1})

在這裏插入圖片描述

  • //本店價格低於或等於100元的商品($lte)
db.goods.find({shop_price:{$lte:100}},{shop_price:1})

在這裏插入圖片描述

  • //取出第4欄目或第11欄目的商品($in)
db.goods.find({cat_id:{$in:[4,11]}},{goods_name:1})
db.goods.find({$or:[{cat_id:4},{cat_id:11}]},{cat_id:1})

在這裏插入圖片描述

  • //取出100<=價格<=500的商品($and)
db.goods.find({$and:[{shop_price:{$gte:100}},{shop_price:{$lte:500}}]},{shop_p
rice:1})

在這裏插入圖片描述

  • //取出不屬於第3欄目且不屬於第11欄目的商品($and $nin和​$nor分別實現)
db.goods.find({$and:[{cat_id:{$ne:3}},{cat_id:{$ne:11}}]},{cat_id:1})
db.goods.find({cat_id:{$nin:[3,11]}},{cat_id:1})
db.goods.find({$nor:[{cat_id:3},{cat_id:11}]},{cat_id:1})

在這裏插入圖片描述

  • //取出價格大於100且小於300,或者大於4000且小於5000的商品()
db.goods.find({$or:[{$and:[{shop_price:{$gt:100}},{shop_price:{$lt:300}}]},{$and:[{shop_price:{$gt:4000}},{shop_price:{$lt:5000}}]}]},{shop_price:1})

在這裏插入圖片描述

  • //取出goods_id%5 == 1, 即,1,6,11,…這樣的商品;mod取餘,前面除數,後面餘數
db.goods.find({goods_id:{$mod:[5,1]}},{goods_id:1});

在這裏插入圖片描述


二、MongoDB 聚合(db.col.aggregate())


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


  • 語法:
db.COLLECTION_NAME.aggregate(
[
    {管道1},
    {管道2},
    {管道3}...
]
)
  • 原理: MongoDB的聚合管道將MongoDB文檔在一個管道處理完畢後將結果傳遞給下一個管道處理,管道操作是可以重複的。

1. 聚合框架中常用的幾個管道操作


(1)$project:


修改輸入文檔的結構。可以用來重命名、增加或刪除域,也可以用於創建計算結果以及嵌套文檔。


(2)$match:


用於過濾數據,只輸出符合條件的文檔。$match使用MongoDB的標準查詢操作。


(3)$limit:


用來限制MongoDB聚合管道返回的文檔數。


(4)$skip:


在聚合管道中跳過指定數量的文檔,並返回餘下的文檔。


(5)$group:


將集合中的文檔分組,可用於統計結果。


(6)$sort:


將輸入文檔排序後輸出。


2. group中的一些操作表達式


表達式 描述
$sum 計算總和
$avg 計算平均值
$min 獲取集合中所有文檔對應值得最小值
$max
獲取集合中所有文檔對應值得最大值
$first 根據資源文檔的排序獲取第一個文檔數據
$last 根據資源文檔的排序獲取最後一個文檔數據
  • 聚合一些操作練習案例:
  1. 查詢每個欄目下的商品數量
db.collection.aggregate( [{$group:{_id:"$cat_id",total:{$sum:1}}}] ); 
  1. 查詢goods下有多少條商品
db.goods.aggregate([{$group:{_id:null,total:{$sum:1}}}])
  1. 查詢每個欄目下價格大於50元的商品個數
db.goods.aggregate([{$match:{shop_price:{$gt:50}}}, {$group:{_id:"$cat_id",total:{$sum:1}}}])
  1. 查詢每個欄目下的庫存量
db.goods.aggregate([{$group:{_id:"$cat_id" , total:{$sum:"$goods_number"}}}])
  1. 查詢每個欄目下 價格大於50元的商品個數 #並篩選出"滿足條件的商品個數" 大於等於3的欄目
1)價格大於50{$match:{shop_price:{$gt:50}}}2)要想查出個數大於3的欄目,必須先對cat_id進行分組:
{$group:{_id:"$cat_id",total:{$sum:1}}}3)最後用match來去除大於3個的欄目
{$match:{total:{$gte:3}}}

db.goods.aggregate([{$match:{shop_price:{$gt:50}}},{$group:{_id:"$cat_id",total:{$sum:1}}} , {$match:{total:{$gte:3}}}])
  1. 查詢每個欄目下的庫存量,並按庫存量排序
    思路:
1)按欄目的庫存量分組(2)排序
{$group:{_id:"$cat_id" , total:{$sum:"$goods_number"}}}
 {$sort:{total:1}}
db.goods.aggregate([{$group:{_id:"$cat_id" , total:{$sum:"$goods_number"}}}, {$sort:{total:1}}])
1是正序,-1是逆序
  1. 查詢每個欄目的商品平均價格,並按平均價格由高到低排序
db.goods.aggregate([{$group:{_id:"$cat_id",avg:{$avg:"$shop_price"}}},{$sort:{avg:-1}}]) 

注意:對一些複雜的語句,要學會拆分成幾個簡單的步驟,再一步步求出所符合條件的商品


三、遊標


1. 遊標是什麼?


mongo的遊標相當於python中的迭代器。通過將查詢結構定義給一個變量,這個變量就是遊標。通過這個遊標,我們可以每次獲取一個數據。


2. 遊標的聲明:


var curor_name = db.bar.find()

3. 遊標的操作:



(1)遊標操作前的處理


在進行遊標操作之前,我們先用js語法插入1000條數據。

注意:MongoDB在底層上時用js來實現的,所以我們可以通過以下代碼,在數據庫中插入1000條數據。

for (var i=0;i<1000;i++){
db.bar.insert({_id:i+1,title:'hello world'+i,content:'aaa'+i})
}

我們可以看出,上面就是js的for循環代碼。所以在MongoDB中可以將js代碼和我們的數據庫做操作指令一起配合來使用。

如果數據庫中很多數據,比如剛剛插入的1000條,我們執行以下命令:

db.bar.find()

作用:他會將所有的數據都查詢出來給我們,此時我們考慮是否能讓我們在查詢的時候,像python中生成器那樣,每次給我們返回一個數據。其實在MongoDB中也有類似生成器這樣的東東,他叫遊標


(2)遊標具體操作


  • 遊標的一些方法hasNext()和next():
    curor.hasNext()//判斷遊標是否已經取到盡頭,|true表示沒有到盡頭。
    curor.next()//取出遊標的下一個單元
    
  • 案例:
    var mycusor = db.bar.find().limit(5)
    print(mycusor.next())//會顯示是一個bson格式的數據
    printjson(mycusor.next())
    
    在這裏插入圖片描述
  • 循環打印:
    while(mycusor.hasNext()){
    		printjson(mycusor.next())
    }
    
    在這裏插入圖片描述

(3)遊標的toArray()方法,方便我們可以看到所有行


print(mycusor.toArray())//看到所有行
	print(mycusor.toArray()[2])//看到第二行

在這裏插入圖片描述
注意:不要使用toArray(),原因是會把所有的行立即以對象的形式放在內存中,可以再取出少數幾行時,使用此功能。(佔用內存,少用)


(4)cursor.forEach(回調函數)


var gettile = function(obj){print(obj.goods_name)}
var cursor = db.goods.find()
cursor.forEach(gettile)

在這裏插入圖片描述


(5)遊標在分頁中的應用


一般的,我們假設每頁N行,當前是page頁,就需要跳過(page-1)*N,再取N行,在mysql中,用limit,offset,N來實現,在MongoDB中,用skip(),limit()函數來實現。

var mycusor = db.bar.find().skip(90).limit(10)//跳過90條,取10條。
 var mycursor = db.bar.find().skip(9995);

則是查詢結果中,跳過前9995行

查詢第901頁,每頁10條

則是 var mytcursor = db.bar.find().skip(9000).limit(10);

四、索引創建


  • 索引提高查詢速度,降低寫入速度,[權衡常用的查詢字段,不必在太多列上建索引](佔用內存)
  • 在mongodb中,索引可以按字段升序/降序來創建,便於排序
  • 默認是用btree來組織索引文件,2.4版本以後,也允許建立hash索引

1. B tree的概念



B 樹是爲了磁盤或其它存儲設備而設計的一種多叉平衡查找樹。
區別:

  • (1)有n棵子樹的結點中含有n個關鍵字; 而B樹是n棵子樹有n-1個關鍵字
  • (2)所有的葉子結點中包含了全部關鍵字的信息,及指向含有這些關鍵字記錄的指針,且葉子結點本身依關鍵字的大小自小而大的順序鏈接。而B樹的葉子節點並沒有包括全部需要查找的信息
  • (3)所有的非終端結點可以看成是索引部分,結點中僅含有其子樹根結點中最大(或最小)關鍵字。 而B 樹的非終節點也包含需要查找的有效信息
    而且:
  • a.B±tree的內部結點並沒有指向關鍵字具體信息的指針。因此其內部結點相對B 樹更小。
  • b.B±tree查詢效率更加穩定

(1) B-tree的介紹


B-Tree是爲磁盤等外存儲設備設計的一種平衡查找樹。因此在講B-Tree之前先了解下磁盤的相關知識。

系統從磁盤讀取數據到內存時是以磁盤塊(block)爲基本單位的,位於同一個磁盤塊中的數據會被一次性讀取出來,而不是需要什麼取什麼。

InnoDB存儲引擎中有頁(Page)的概念,頁是其磁盤管理的最小單位。InnoDB存儲引擎中默認每個頁的大小爲16KB,可通過參數innodb_page_size將頁的大小設置爲4K、8K、16K

而系統一個磁盤塊的存儲空間往往沒有這麼大,因此InnoDB每次申請磁盤空間時都會是若干地址連續磁盤塊來達到頁的大小16KB。InnoDB在把磁盤數據讀入到磁盤時會以頁爲基本單位,在查詢數據時如果一個頁中的每條數據都能有助於定位數據記錄的位置,這將會減少磁盤I/O次數,提高查詢效率。

B-Tree結構的數據可以讓系統高效的找到數據所在的磁盤塊。爲了描述B-Tree,首先定義一條記錄爲一個二元組[key, data] ,key爲記錄的鍵值,對應表中的主鍵值,data爲一行記錄中除主鍵外的數據。對於不同的記錄,key值互不相同。

一棵m階的B-Tree有如下特性:

  1. 每個節點最多有m個孩子。
  2. 除了根節點和葉子節點外,其它每個節點至少有Ceil(m/2)個孩子。
  3. 若根節點不是葉子節點,則至少有2個孩子
  4. 所有葉子節點都在同一層,且不包含其它關鍵字信息
  5. 每個非終端節點包含n個關鍵字信息(P0,P1,…Pn, k1,…kn)
  6. 關鍵字的個數n滿足:ceil(m/2)-1 <= n <= m-1
  7. ki(i=1,…n)爲關鍵字,且關鍵字升序排序。
  8. Pi(i=1,…n)爲指向子樹根節點的指針。P(i-1)指向的子樹的所有節點關鍵字均小於ki,但都大於k(i-1)

B-Tree中的每個節點根據實際情況可以包含大量的關鍵字信息和分支,如下圖所示爲一個3階的B-Tree:
在這裏插入圖片描述
每個節點佔用一個盤塊的磁盤空間,一個節點上有兩個升序排序的關鍵字和三個指向子樹根節點的指針,指針存儲的是子節點所在磁盤塊的地址。兩個關鍵詞劃分成的三個範圍域對應三個指針指向的子樹的數據的範圍域。以根節點爲例,關鍵字爲17和35,P1指針指向的子樹的數據範圍爲小於17,P2指針指向的子樹的數據範圍爲17~35,P3指針指向的子樹的數據範圍爲大於35。

模擬查找關鍵字29的過程:

根據根節點找到磁盤塊1,讀入內存。【磁盤I/O操作第1次】
比較關鍵字29在區間(17,35),找到磁盤塊1的指針P2。
根據P2指針找到磁盤塊3,讀入內存。【磁盤I/O操作第2次】
比較關鍵字29在區間(26,30),找到磁盤塊3的指針P2。
根據P2指針找到磁盤塊8,讀入內存。【磁盤I/O操作第3次】
在磁盤塊8中的關鍵字列表中找到關鍵字29。
分析上面過程,發現需要3次磁盤I/O操作,和3次內存查找操作。由於內存中的關鍵字是一個有序表結構,可以利用二分法查找提高效率。而3次磁盤I/O操作是影響整個B-Tree查找效率的決定因素。B-Tree相對於AVLTree縮減了節點個數,使每次磁盤I/O取到內存的數據都發揮了作用,從而提高了查詢效率。


(2)B+tree的介紹


B+Tree是在B-Tree基礎上的一種優化,使其更適合實現外存儲索引結構,InnoDB存儲引擎就是用B+Tree實現其索引結構。

從上一節中的B-Tree結構圖中可以看到每個節點中不僅包含數據的key值,還有data值。而每一個頁的存儲空間是有限的,如果data數據較大時將會導致每個節點(即一個頁)能存儲的key的數量很小,當存儲的數據量很大時同樣會導致B-Tree的深度較大,增大查詢時的磁盤I/O次數,進而影響查詢效率。在B+Tree中,所有數據記錄節點都是按照鍵值大小順序存放在同一層的葉子節點上,而非葉子節點上只存儲key值信息,這樣可以大大加大每個節點存儲的key值數量,降低B+Tree的高度。

B+Tree相對於B-Tree有幾點不同:

  1. 非葉子節點只存儲鍵值信息。
  2. 所有葉子節點之間都有一個鏈指針。
  3. 數據記錄都存放在葉子節點中。
    將上一節中的B-Tree優化,由於B+Tree的非葉子節點只存儲鍵值信息,假設每個磁盤塊能存儲4個鍵值及指針信息,則變成B+Tree後其結構如下圖所示:
    在這裏插入圖片描述
    通常在B+Tree上有兩個頭指針,一個指向根節點,另一個指向關鍵字最小的葉子節點,而且所有葉子節點(即數據節點)之間是一種鏈式環結構。因此可以對B+Tree進行兩種查找運算:一種是對於主鍵的範圍查找和分頁查找,另一種是從根節點開始,進行隨機查找。

注意:B+tree和B-tree最大的區別就是B+tree的葉子結點可以指向下一個葉子結點,比起B-tree優化更高


2. hash索引


(1)hash索引的介紹


hash索引基於哈希表實現,只有精確匹配索引所有列的查詢纔有效。Memory引擎默認使用的是此種索引。

存儲引擎對所有的索隱列計算出一個哈希碼,將哈希碼存儲在索引中,同時哈希表中保存每個數據行的指針。
這樣,對於此種索引查找速度是非常快的。出現哈希值碰撞的話,索引會以鏈表的形式存放多個記錄指針到
同一個哈希條目中。

在這裏插入圖片描述
Hash檢索效率非常高,索引的檢索可以一次定位,不像B-Tree 索引需要從根節點到枝節點,最後才能訪問到數據節點這樣多次的IO訪問,所以 Hash 索引的查詢效率要遠高於 B-Tree 索引。

但是任何事物都有兩面性,他的特殊性也帶來了很多弊端和限制。


(2)hash索引缺點


  • (1)Hash 索引僅僅能滿足"=",“IN"和”<=>"查詢,不能使用範圍查詢。

  • (2)Hash 索引無法被用來避免數據的排序操作。
    由於 Hash 索引中存放的是經過 Hash 計算之後的 Hash 值,而且Hash值的大小關係並不一定和 Hash 運算前的鍵值完全一樣,所以數據庫無法利用索引的數據來避免任何排序運算;

  • (3)Hash 索引不能利用部分索引鍵查詢。
    對於組合索引,Hash 索引在計算 Hash 值的時候是組合索引鍵合併後再一起計算 Hash 值,而不是單獨計算 Hash 值,所以通過組合索引的前面一個或幾個索引鍵進行查詢的時候,Hash 索引也無法被利用。

  • (4)Hash 索引在任何時候都不能避免表掃描。
    Hash 索引是將索引鍵通過 Hash 運算之後,將 Hash運算結果的 Hash 值和所對應的行指針信息存放於一個 Hash 表中,由於不同索引鍵存在相同 Hash 值,所以即使取滿足某個 Hash 鍵值的數據的記錄條數,也無法從 Hash 索引中直接完成查詢,還是要通過訪問表中的實際數據進行相應的比較,並得到相應的結果。

  • (5)Hash 索引遇到大量Hash值相等的情況後性能並不一定就會比B-Tree索引高。

    use aaa
    for (var i=0;i<1000;i++){
    		db.bar.insert({_id:i+1,title:'hello world'+i,content:'aaa'+i})
    	}
    通過上面方法插入1000條數據
    db.bar.explain('executionStats').find({content:'aaa998'})//性能分析
    

3. 索引常用命令


  • (1)查看當前索引狀態:db.collection.getIndexes()

  • (2)創建普通單列索引:db.collection.ensureIndex({field:1/-1})//1爲正序,-1爲逆序

  • (3)刪除單個索引:db.collection.dropIndex({field:1/-1})

  • (4)刪除所有索引:db.collection.dropIndexes()
    注意: _id所在的列的索引不能刪除。

  • (5)創建多列索引:db.collection.ensureIndex({field1:1/-1,field2:1/-1})
    多列索引的使用範圍更廣,因爲一般情況下,我們都是通過多個字段來進行查詢數據的,這時候單列索引其實用不到。
    兩個列一起建立索引其實就是將兩個列綁定到一起,來創建索引

  • (6)子文檔索引:
    子文檔查詢:

    1. 插入兩條帶子文檔的數據
      db.shop. insert({name: 'N0kia' , SPC: {weight: 120 , area: ' taiwan ' } } ) ;
      db.shop. insert({name: 'sanxing ' , SPC :{weight: 100 , area: 'hanguo'}
      
    2. 查詢出產地在臺灣的手機db.shop.find({'spc.area':'taiwan'})
    3. 給子文檔加索引:db.shop.ensureIndex({'spc.area':1})//子文檔索引就創建好了
  • (7) 唯一索引:{unique:true}

    db.collection.ensureIndex({field:1/-1},{unique:true})
    

    注意:唯一索引的列不能重複插入

  • (8)創建稀疏索引:{sparse:true}
    稀疏索引的特點:如果針對field列做索引,針對不含field的列的文檔,將不建立索引,與之相對,普通索引,會把該文檔的field列的值認爲null,並建立索引。

    db.collection.ensureIndex({field:1/-1},{sparse:true})
    
  • (9)hash索引:

    db.collection.ensureIndex({field:'hashed'})
    

發佈了107 篇原創文章 · 獲贊 43 · 訪問量 7049
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章