iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 10
0
Big Data

30天之你好MongoDB系列 第 10

30-10之新手村CRUD---搜尋之Cursor運用與搜尋原理

本篇文章將要說明cursor的用法以及一些curosr的方法,可以搜尋後用來限制或排序結果的功能,以及說明一下在不考慮索引情況下find的搜尋原理。

  • Cursor是啥
  • Cursor的方法
  • 搜尋的原理

P.S 三分之一囉,也代表基本的mongodbcrudEnding囉。

~ Cursor是啥 ~


cursorfind時回傳的結果,它可以讓使用者對最終結果進行有效的控制,它事實上也就是Iterator 模式的實作。

除了可以控制最終結果以外,它另一個好處是可以一次查看一條結果,像之前insertMany時,他會一次回傳全部的結果,mongodb shell就會自動一直輸出,結果看不到後來執行的東西。

我們實際來看一下cursor的用法,首先我們還是要先新增一些資料。

for (var i=0;i<10;i++){
	db.test.insert({x:i})
}

然後進行搜尋,並用一個變數cursor存放。

var cursor = db.test.find();

while (cursor.hasNext()){
	obj = cursor.next();
	print(obj.x + " ~呼呼~")
}

結行結果如下圖。

~ Cursor的方法 ~


limit、skip、sort這三個是很常用的cursor方法,主要功能就是限制、忽略、排序。

limit

要限制find結果的數量可以用limit,不過注意limit是指定上限而不是指定下限,
使用方法如下,limit(10)就是代表最多只回傳10筆資料。

db.test.find().limit(10)

skip

當你想要忽略前面幾筆,在開始回傳值時,就是可以用skip,使用方法如下,skip(10),代表忽略前十筆,然後在開始回傳,不過注意『 skip如果數量很多時速度會變很慢 』。

db.test.find().skip(10)

sort

sort它主要就是將find出的資料,根據條件,進行排序。

例如假設我們有以下的資料。

{"name":"mark" , age:20}
{"name":"steven" , age:25}
{"name":"max" , age:10}
{"name":"stanly" , age:40}
{"name":"crisis" , age:5}

然後我們希望可以根據age排序,由小到大,{age:1}代表由小到大,而{age:-1}則相反由大到小。

db.user.find().sort({age:1})

結果如下~

三個都可以一起使用

這三個條件我們都可以一起使用,例如,你希望尋找先忽略前10筆,並且數量限制為50筆,最後在進行排序,則指令如下。

db.test.find().skip(10).limit(50).sort({x:1})

~ 搜尋的原理 ~


在不考慮有索引(下一篇會開始說)的條件下,mongodb會如下圖一樣開始搜尋。

所以說如果你要找的值是放在資料的最後面,你找到的時間會最久,給個程式實驗看看。

首先來個測試資料。

for (var i=0; i<1000000;i++){
	db.test.insert({"x":i})
}

來我們來測試看看找到{"x" : 1}{"x": 999999}速度會差多少,其中加limit(1)是因為只讓它尋找第一個,如果沒限制它會一直繼續找,看還有沒有符合的,這樣兩者速度是相等的,因為都是全文掃描,而explain("executionStats")是叫mongodb列出詳細的執行結果。

db.test.find({"x" : 1}).limit(1).explain("executionStats")

db.test.find({"x" : 999999}).limit(1).explain("executionStats")

首先看看下圖,是 { "x" : 1 }的,可以看到執行時間幾乎沒有,而掃描的document之有2,也就是只找兩個document就找到{ "x" :1 },而那兩個就是{ "x" : 0 } 和 { "x" : 1 }

然後我們在來看看 { "x" : 999999 }的結果,執行時間413ms差距和{"x":1}差距實在很大,而它幾乎要全部掃描完document才找到 { "x" : 999999 },難怪會著麼慢。

~ 結語 ~


或許會有人問我,為什麼要把搜尋原理放在搜尋的最後才講,這個麻,因為突然想到…… , 不過我個人是比較喜好先寫的出來,在來想它的原理,這種道理就像大學如果一開始先教資料庫的正規化,然後才開始學著麼用資料庫的道理是一樣 ~ 不過這也只是個人的想法 ~

呼 ~ 今天鐵人賽總於進行了三分之一了,也終於將mongodb的基本CRUD都『簡單』的說明一下,記好是『簡單』,如果是『詳細』的話那大概30天都在寫它了,這樣太無趣了。

~ 參考資料 ~



上一篇
30-9之新手村CRUD---搜尋之陣列欄位與regex
下一篇
30-11之索引(1)---索引的哩哩扣扣
系列文
30天之你好MongoDB30

尚未有邦友留言

立即登入留言