MongoDB入門

來源:互聯網
上載者:User
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 todbmydb

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

動態模式(無模式)

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

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

向集合中插入資料

首先建立一個名為test的集合,再向test中插入資料。我們建立兩個對象j和t,然後將它們儲存到集合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查詢,並且說明如何藉助mongoshell使得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:A,b:B,…}意思是“where
a==A and b==B and …”。如果想瞭解更多條件查詢有關的資訊,可以到MongoDB官網上查看MongoDB開發人員手冊,網址如下:

http://www.mongodb.org/display/DOCS/Manual

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”欄位總是會返回在結果中的。

 

作者簡介

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

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

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.