天天看點

《MongoDB管理與開發精要》——2.5節操作資料庫

2.5 操作資料庫

現在就可以使用自帶的mongodb shell工具來操作資料庫了。 當然,也可以使用各種程式設計語言的驅動來使用mongodb, 但自帶的mongodb shell工具可以友善地管理資料庫。

2.5.1 連接配接資料庫

打開一個session輸入“/apps/mongo/bin/mongo”,如果出現下面的提示,說明已經連接配接上資料庫,可以執行操作了:

預設 shell 連接配接的是本機localhost 上的 test庫,“connecting to:”會顯示正在使用的資料庫名稱,想換資料庫的話可以用“use mydb”來實作。

2.5.2 插入記錄

建立一個things的集合并寫入一些資料,建立兩個對象j和t , 并儲存到集合中,如下面的代碼所示(其中“>”為 shell 輸入提示符):

以下幾點需要注意:

q 不需要預先建立一個集合,在第一次插入資料時會自動建立。

q 在文檔中可以存儲任何結構的資料, 但在實際應用中存儲的還是相同類型文檔的集合。此特性很靈活, 不需要類似alter table 語句來修改資料結構。

q 每次插入資料時,集合中都會有一個id(_id)。

下面插入一些資料,如下面的代碼所示:

從技術上講, find() 傳回一個遊标對象,但在上面的例子裡, 并沒有拿到一個遊标的變量,是以 shell 自動周遊遊标,傳回一個初始化的set,并允許繼續用 it 疊代輸出。當然,也可以直接用遊标來輸出,不過這是“遊标”部分的内容了。

擴充閱讀 什麼是_id key

mongodb支援的資料類型中,_id是其自有産物。存儲在mongodb集合中的每個文檔(document)都有一個預設的主鍵_id,這個主鍵名稱是固定的,它可以是mongodb支援的任何資料類型,預設是objectid。在關系資料庫schema設計中,主鍵大多數是數值型的,比如常用的int和long,并且通常主鍵的取值由資料庫自增獲得,這種主鍵數值的有序性有時也表明了某種邏輯。而mongodb在設計之初就定位于分布式存儲系統,是以它不支援自增主鍵。

當向一個集合中寫入一條文檔時,系統會自動生成一個名為_id 的key,如下面的代碼所示:

這裡多出一個類型為objectid的key值,在插入時并沒有指定,類似oracle的rowid資訊,這屬于自動生成的。

在mongodb中,每一個集合都必須有一個_id字段,字段類型預設是objectid。注意,可以不是objectid,例如下面的_id=3的條目:

雖然_id的類型可以自由指定,但是在同一個集合中必須唯一,如果插入重複的值,系統将會抛出異常,如下面的代碼所示:

因為前面已經插入了一條_id=3的記錄,是以再插入相同的文檔就不允許了。

2.5.3 查詢記錄

在沒有深入講解查詢之前, 先看看怎樣從查詢中傳回一個遊标對象。可以簡單地通過 find() 來查詢,傳回一個任意結構的集合,而如何實作特定的查詢稍後講解。

普通查詢

一般的查詢可以通過 while 循環輸出,如下面的代碼所示:

上面的例子顯示了遊标風格的疊代輸出,hasnext() 函數用于判斷是否還有資料,如果有則調用 next() 函數将資料取出來。

當使用的是 javascript shell時,可以用javascript的foreach特性,這樣就可以輸出遊标了。下面的例子就是使用 foreach() 循環輸出資料,但foreach() 必須定義一個函數供每個遊标元素調用,如下面的代碼所示:

使用遊标時請注意占用記憶體的問題,特别是很大的遊标對象,有可能會記憶體溢出,是以應該用疊代的方式來輸出。下面的示例是把遊标轉換成真實的數組類型:

注意 這些特性隻是在mongodb shell裡使用,不是所有的其他應用程式驅動都支援。如果有其他使用者在集合裡第一次或者最後一次調用next(), 可能得不到遊标裡的資料,是以要明确地鎖定要查詢的遊标。

條件查詢

下面的示例說明了如何執行一個類似sql的查詢,并示範了如何在 mongodb 裡實作,這是在mongodb shell裡查詢,當然,也可以用其他的應用程式驅動或者語言來實作。

查詢條件是 { a:a, b:b, ... } ,類似“where a==a and b==b and ...”。例如,sql查詢:

上面查詢指令中的“{j:true}”顯式地指明結果集隻傳回列“j”的值,而其他列如“x”的值并沒有傳回。

findone()文法

mongodb shell為了避免遊标可能帶來的開銷,提供了一個findone() 函數。這個函數和 find() 函數一樣,不過它傳回的是遊标裡的第一條資料,或者傳回null,即空資料。

例如name=“mongo” 可以用很多方法來實作,如用 next() 來循環遊标或者當成數組傳回第一個元素,而用 findone() 方法更簡單和高效,如下面的代碼所示:

通過limit限制結果集數量

如果需要限制結果集的長度,可以調用limit方法,如下面的代碼所示:

強烈推薦這種解決性能問題的方法,通過限制條數來減少網絡傳輸,同時,limit方法也廣泛應用于分頁技術中。

2.5.4 修改記錄

如果需要修改表中的記錄,可以調用update方法。

例如,将列name的值從“mongo”修改為“mongo_new”,如下面的代碼所示:

接下來通過執行“db.things.find()”指令查詢列name的值是否改過來了,如下面的代碼所示:

經驗證,name的值已經改為“mongo_new”了。

2.5.5 删除記錄

如果要删除表中的記錄,可以調用remove方法。

例如,将使用者name是“mongo_new”的記錄從集合things中删除,如下面的代碼所示:

經驗證,該記錄确實被删除了。