MongoDB入門

broadviewbj發表於2013-04-16

MongoDB入門

連線資料庫

在這裡我們使用MongoDB提供的JavaScript. shell進行資料庫操作,當然也可以透過不同的驅動利用其他程式語言實現同樣的功能,不過shell在管理資料庫的方面還是很方便的。

啟動JavaScript. shell的方法很簡單,命令如下:

C:\mongodb\bin\mongo

在預設情況下,shell連線到本地test資料庫,可以看到如下資訊:

C:\mongodb\bin>mongo

MongoDB shell version: 2.0.2

connecting to: test

connecting to”的後面是要連線的資料庫的名字,如果想換成其他的資料庫,可以用如下命令:

> use mydb

switched to dbmydb

注意:切換資料庫後,如果切換的資料庫不存在,系統並不會馬上建立這個資料庫,而是在對它進行第一次插入操作時才建立。這意味著當你使用“show dbs”命令檢視現有資料庫時,並不能看到切換的資料庫。

動態模式(無模式)

MongoDB包含資料庫(database)、集合(collection),以及和傳統關聯式資料庫很相似的索引結構(index)。對於資料庫和集合這些物件(object),系統會隱式地進行建立,然而一旦建立它們就被記錄到了系統目錄中(db.systems.collectionsdb.system.indexes)。

集合由文件(document)組成,文件中包含域(field),也就是傳統關聯式資料庫中的欄位。但與關聯式資料庫不同,MongoDB不會對域進行預定義,也沒有給文件定義模式,這就意味著文件中不同域和它們的值是可以變化的。因此,MongoDB並沒有“alter table”操作來增加或者減少域的個數。在實際應用中,一個文件中通常包含相同型別的結構,但這並不是必須的。這種彈性使得模式變動或者增加變得非常容易,幾乎不用寫任何指令碼程式就可實現“alter table”操作。另外,動態模式機制便於對基於MongoDB資料庫的軟體進行重複性開發,大大減少了由於模式變化所帶來的工作量。

向集合中插入資料

首先建立一個名為test的集合,再向test中插入資料。我們建立兩個物件jt,然後將它們儲存到集合things中。

在下面的例子中,“>”表示shell命令提示符:

>j={name:"mongo"}

{ "name" : "mongo" }

> t={x:3}

{ "x" : 3 }

>db.things.save(j)

>db.things.save(t)

>db.things.find()

{ "_id" : ObjectId("4f361b1f64480e0bcb6d6021"), "name" : "mongo" }

{ "_id" : ObjectId("4f361c6364480e0bcb6d6022"), "x" : 3 }

注意:

我們並沒有預定義集合,資料庫是在進行第一次插入操作時自動建立集合的。

我們儲存的文件包含不同的域,在這個例子中,文件中沒有相同的資料元素。但在實際
     
應用中,往往把相同結構的資料儲存在一個集合中。

一旦被儲存到資料庫中,如果沒有事先定義,物件就會被自動分配一個ObjectId,並且
     
儲存到field_id域中。當你執行上面的例子時,會有不同的ObjectId

向集合中增加更多的記錄,下面的程式碼利用了迴圈結構:

> for (var i=1; i<=20; i++) db.things.save({x:4,j:i})

>db.things.find()

{ "_id" : ObjectId("4f361b1f64480e0bcb6d6021"), "name" : "mongo" }

{ "_id" : ObjectId("4f361c6364480e0bcb6d6022"), "x" : 3 }

{ "_id" : ObjectId("4f36234964480e0bcb6d6023"), "x" : 4, "j" : 1 }

……

{ "_id" : ObjectId("4f36234964480e0bcb6d6034"), "x" : 4, "j" : 18 }

has more

值得注意的是,上面例子中沒有顯示出全部的文件,shell預設顯示的數目是20。如果想檢視其餘的文件,可以使用it命令:

{ "_id" : ObjectId("4f36234964480e0bcb6d6034"), "x" : 4, "j" : 18 }

has more

>it

{ "_id" : ObjectId("4f36234964480e0bcb6d6035"), "x" : 4, "j" : 19 }

{ "_id" : ObjectId("4f36234964480e0bcb6d6036"), "x" : 4, "j" : 20 }

嚴格來講,find()返回的是指標物件。但是在上面的例子中,我們並沒有把指標物件賦予任何變數。所以,shell自動對指標進行迭代,直到給出初始的結果集,我們可以透過it命令顯示出其餘的資訊,但是也可以直接對find()返回的指標進行操作,11.3.3.4節中將對其進行介紹。

查詢資料

在討論資料查詢之前,先了解一下如何操作查詢結果,即指標物件。我們將使用簡單的find()方法,返回集合中全部的文件,之後再討論如何寫出特定的查詢語句。

為了瞭解使用mongo shell時集合中的全部元素,我們需要明確地使用find()方法返回的指標。利用while迴圈對find()返回的指標進行迭代,實現和前面例子相同的查詢結果:

>var cursor=db.things.find()

>while (cursor.hasNext()) printjson(cursor.next())

{ "_id" : ObjectId("4f361b1f64480e0bcb6d6021"), "name" : "mongo" }

{ "_id" : ObjectId("4f361c6364480e0bcb6d6022"), "x" : 3 }

{ "_id" : ObjectId("4f36234964480e0bcb6d6023"), "x" : 4, "j" : 1 }

……

{ "_id" : ObjectId("4f36234964480e0bcb6d6036"), "x" : 4, "j" : 20 }

上面的例子顯示了指標迭代器,hasNext()方法判斷是否還能返回文件,next()方法返回下一個文件。我們也使用了內建的printjson()方法使文件以JSON形式展現。

當在JavaScript. shell下工作時,我們也可以利用JavaScript語言的特徵,比如使用forEach輸出指標物件。下面的程式碼輸出與上面相同的查詢結果,但是在程式碼中使用forEach而不是while迴圈:

>db.things.find().forEach(printjson)

{ "_id" : ObjectId("4f361b1f64480e0bcb6d6021"), "name" : "mongo" }

{ "_id" : ObjectId("4f361c6364480e0bcb6d6022"), "x" : 3 }

{ "_id" : ObjectId("4f36234964480e0bcb6d6023"), "x" : 4, "j" : 1 }

……

{ "_id" : ObjectId("4f36234964480e0bcb6d6036"), "x" : 4, "j" : 20 }

在使用forEach()方法的時候,必須為指標指向的每一個文件定義函式(這裡用了內建方法printjson())。

mongo shell中,可以像對陣列一樣操作指標:

>var cursor=db.things.find()

>printjson(cursor[4])

{ "_id" : ObjectId("4f36234964480e0bcb6d6025"), "x" : 4, "j" : 3 }

當用這種方式使用指標時,指標指示的值都能同時載入到記憶體中,這一點不利於返回較大的查詢結果,因為有可能發生記憶體溢位。對於結果較大的查詢,應該用迭代方式輸出指標值。

另外,你可以將指標轉變為真正的陣列進行處理:

>arr[5]

{ "_id" : ObjectId("4f36234964480e0bcb6d6026"), "x" : 4, "j" : 4 }

注意,這些陣列特性都僅適用於shell模式,但對於其他語言環境並不適合。MongoDB指標並不是快照,當在集合上進行操作時,如果有其他人在集合裡第一次或者最後一次呼叫next(),那麼你的指標可能不能成功返回結果,所以要明確鎖定你要查詢的指標。

條件查詢

我們已經知道如何操作查詢返回的指標,現在我們要針對特定條件實現對查詢結果的篩選。一般來說,實現條件查詢就需要建立“查詢文件”,即指明鍵需要匹配的模式和值的文件。對於這一點用例子證明要比用文字解釋清楚得多。在下面的例子中,我們將給出SQL查詢,並且說明如何藉助mongo shell使得MongoDB能實現相同的查詢(參見表11-4與表11-5)。這種條件查詢是MongoDB的基本功能,所以你也可以用其他程式驅動或者語言實現條件查詢。

11-4  MongoDB條件查詢(name="mongo"

SELECT * FROM things WHERE name="mongo"

>db.things.find({name:"mongo"}).forEach(printjson)

{ "_id" : ObjectId("4f361b1f64480e0bcb6d6021"), "name" : "mongo" }

11-5  MongoDB條件查詢(x=4

SELECT * FROM things WHERE x=4

>db.things.find({x:4}).forEach(printjson)

{ "_id" : ObjectId("4f36234964480e0bcb6d6023"), "x" : 4, "j" : 1 }

{ "_id" : ObjectId("4f36234964480e0bcb6d6024"), "x" : 4, "j" : 2 }

續表 

……

{ "_id" : ObjectId("4f36234964480e0bcb6d6036"), "x" : 4, "j" : 20 }

查詢表示式本身是一個文件,一個查詢文件{a:Ab:B…}意思是“where a==A and b==B and …”。如果想了解更多條件查詢有關的資訊,可以到MongoDB官網上檢視MongoDB開發者手冊,網址如下:

MongoDB也允許返回“部分文件”,也就是結果中只包含資料庫文件的一些子元素,類似於關聯式資料庫中針對某些列的查詢。為了實現這個查詢,可以在find()方法中增加第二個引數,表示返回某些特定元素。為了便於說明,下面我們還是實現find({x:4})的查詢,只不過增加了額外的引數使得結果中只包含j元素:

11-6  MongoDB條件查詢(返回特定元素j

SELECT j FROM things WHERE x=4

>db.things.find({x:4},{j:true}).forEach(printjson)

{ "_id" : ObjectId("4f36234964480e0bcb6d6023"), "j" : 1 }

……

{ "_id" : ObjectId("4f36234964480e0bcb6d6036"), "j" : 20 }

注意:_id”欄位總是會返回在結果中的。

 

MongoDB入門

作者簡介

陸嘉恆,中國人民大學教授,博士生導師。2006年畢業於新加坡國立大學電腦科學系,獲博士學位;2006-2008年在美國加利福尼亞大學爾灣分校(University of California, Irvine)進行博士後研究;2008年加入中國人民大學,2012年破格晉升為教授。主要研究領域包括資料庫技術和雲端計算技術。先後在SIGMODVLDBICDEWWW等國際重要會議和期刊上發表資料庫方向的論文40多篇,主編多本雲端計算和大資料的教材和著作。

本文節選自《大資料挑戰與NoSQL資料庫技術》一書。陸嘉恆 編著,由電子工業出版社出版。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/13164110/viewspace-758557/,如需轉載,請註明出處,否則將追究法律責任。

相關文章