mongoDB入门必读(概念与实战并重)
一、概述 MongoDB是一個基于分布式文件存儲的數據庫開源項目。由C++語言編寫。旨在為WEB應用提供可護展的高性能數據存儲解決方案。
MongoDB是一個介于關系數據庫和非關系數據庫之間的產品,是非關系數據庫當中功能最豐富,最像關系數據庫的。他支持的數據結構非常松散,是類似json的bjson格式,因此可以存儲比較復雜的數據類型。Mongo最大的特點是他支持的查詢語言非常強大,其語法有點類似于面向對象的查詢語言,幾乎可以實現類似關系數據庫單表查詢的絕大部分功能,而且還支持對數據建立索引。?
Mongo主要解決的是海量數據的訪問效率問題,根據官方的文檔,當數據量達到50GB以上的時候,Mongo的數據庫訪問速度是MySQL的10倍以上。Mongo的并發讀寫效率不是特別出色,根據官方提供的性能測試表明,大約每秒可以處理0.5萬-1.5次讀寫請求。
因為Mongo主要是支持海量數據存儲的,所以Mongo還自帶了一個出色的分布式文件系統GridFS,可以支持海量的數據存儲,但我也看到有些評論認為GridFS性能不佳,有待驗證。?
最后由于Mongo可以支持復雜的數據結構,而且帶有強大的數據查詢功能,因此非常受到歡迎,很多項目都考慮用MongoDB來替代MySQL來實現不是特別復雜的Web應用,比方說 why we migrated from MySQL to MongoDB就是一個真實的從MySQL遷移到MongoDB的案例,由于數據量實在太大,所以遷移到了Mongo上面,數據查詢的速度得到了非常顯著的提升。?
MongoDB也有一個ruby的項目 MongoMapper,是模仿Merb的DataMapper編寫的MongoDB的接口,使用起來非常簡單,幾乎和DataMapper一模一樣,功能非常強大易用。?
總結起來,monggDB的特點是高性能、易部署、易使用,存儲數據非常方便。主要功能特性有:
*面向集合存儲,易存儲對象類型的數據。
*模式自由。
*支持動態查詢。
*支持完全索引,包含內部對象。
*支持查詢。
*支持復制和故障恢復。
*使用高效的二進制數據存儲,包括大型對象(如視頻等)。
*自動處理碎片,以支持云計算層次的擴展性
*支持RUBY,PYTHON,JAVA,C++,PHP等多種語言。
*文件存儲格式為BSON(一種JSON的擴展)
*可通過網絡訪問
所謂“面向集合”(Collenction-Orented),意思是數據被分組存儲在數據集中,被稱為一個集合(Collenction)。每個集合在數據庫中都有一個唯一的標識名,并且可以包含無限數目的文檔。集合的概念類似關系型數據庫(RDBMS)里的表(table),不同的是它不需要定義任何模式(schema)。
模式自由(schema-free),意味著對于存儲在mongodb數據庫中的文件,我們不需要知道它的任何結構定義。如果需要的話,你完全可以把不同結構的文件存儲在同一個數據庫里。
存儲在集合中的文檔,被存儲為鍵-值對的形式。鍵用于唯一標識一個文檔,為字符串類型,而值則可以是各中復雜的文件類型。我們稱這種存儲形式為BSON(Binary Serialized dOcument Format)。
MongoDB的優點
- 高性能,速度非常快(如果你的內存足夠的話)
- 沒有固定的表結構,不用為了修改表結構而進行數據遷移
- 查詢語言簡單,容易上手
- 使用Sharding實現水平擴展
- 部署方便
使用MongoDB,你得記住以下幾點:
- MongoDB 假設你有大磁盤空間
- MongoDB 假設你的內存也足夠大于放下你的熱數據
- MongoDB 假設你是部署在64位系統上的(32位有2G的限制,試用還可以)
- MongoDB 假設你的系統是little-endian的
- MongoDB 假設你有多臺機器(并不專注于單機可靠性)
- MongoDB 假設你希望用安全換性能,同時允許你用性能換安全
MongoDB在下面領域不太擅長
- 不太穩定,特別是auto-sharding目前還有很多問題
- 不支持SQL,這意味著你很多通過SQL接口的工具不再適用
- 持久化,MongoDB單機可靠性不太好,宕機可能丟失一段時間的數據
- 相關文檔比較少,新功能都有這個問題
- 相關人才比較難找,這也是新功能的問題之一?
二、安裝
MongoDB服務端可運行在Linux、Windows或OS X平臺,支持32位和64位應用,默認端口為27017。推薦運行在64位平臺,因為MongoDB
在32位模式運行時支持的最大文件尺寸為2GB。MongoDB把數據存儲在文件中(默認路徑為:/data/db),為提高效率使用內存映射文件進行管理。
(一)Linux/OS X下:
1 建立數據目錄
mkdir -p /data/db
2 下載壓縮包
curl -O?http://downloads.mongodb.org/linux/mongodb-linux-i686-latest.tgz
3 解壓縮文件
tar xzf mongodb-linux-i386-latest.tgz
4 啟動服務
bin/mongod run &
5 使用自帶客戶端連接
/bin/mongo
6 測試
db.foo.save( { a : 1 } )
db.foo.findOne()
(二)windows下:
1 建立數據目錄c:\data\db
2 下載壓縮包,解壓文件
3 啟動服務
bin\mongod.exe run
4 自帶客戶端
bin\mongon.exe
在LINUX和WINDOWS系統下的使用大同小異,不同的地方主要是默認的數據存儲目錄。LINUX類系統下存放在/data/db下,而WINDOWS
會存放在C:\data\db下。可以在啟動時使用--dbpath參數指定存儲目錄并啟動。如:bin\mongod.exe --dbpath d:\data\mongo
常用啟動參數:
run 直接啟動。例:./mongod run
--dbpath 指定特定存儲目錄啟動,若目錄不存在則創建。例:./mongod --dbpath /var/data/mongo
--port 指定端口啟動。例:./mongod --port 12345
停止MONGO服務:
方法1:服務端停止,可使用Ctrl+C
方法2:在客戶端停止,可先連接客戶端
./mongo
并使用命令
db.shutdownerver()
然后退出客戶端
exit
三、mongoDB常用命令
1、與Mql對照
?
| MySQL | MongoDB | 說明 |
| mysqld | mongod | 服務器守護進程 |
| mysql | mongo | 客戶端工具 |
| mysqldump | mongodump | 邏輯備份工具 |
| mysql | mongorestore | 邏輯恢復工具 |
| ? | db.repairDatabase() | 修復數據庫 |
| mysqldump | mongoexport | 數據導出工具 |
| source | mongoimport | 數據導入工具 |
| grant * privileges on *.* to … | Db.addUser() Db.auth() | 新建用戶并權限 |
| show databases | show dbs | 顯示庫列表 |
| Show tables | Show collections | 顯示表列表 |
| Show slave status | Rs.status | 查詢主從狀態 |
| Create table users(a int, b int) | db.createCollection("mycoll", {capped:true, size:100000})?另:可隱式創建表。 | 創建表 |
| Create INDEX idxname ON users(name) | db.users.ensureIndex({name:1}) | 創建索引 |
| Create INDEX idxname ON users(name,ts DESC) | db.users.ensureIndex({name:1,ts:-1}) | 創建索引 |
| Insert into users values(1, 1) | db.users.insert({a:1, b:1}) | 插入記錄 |
| Select a, b from users | db.users.find({},{a:1, b:1}) | 查詢表 |
| Select * from users | db.users.find() | 查詢表 |
| Select * from users where age=33 | db.users.find({age:33}) | 條件查詢 |
| Select a, b from users where age=33 | db.users.find({age:33},{a:1, b:1}) | 條件查詢 |
| select * from users where age<33 | db.users.find({'age':{$lt:33}}) | 條件查詢 |
| select * from users where age>33 and age<=40 | db.users.find({'age':{$gt:33,$lte:40}}) | 條件查詢 |
| select * from users where a=1 and b='q' | db.users.find({a:1,b:'q'}) | 條件查詢 |
| select * from users where a=1 or b=2 | db.users.find( { $or : [ { a : 1 } , { b : 2 } ] } ) | 條件查詢 |
| select * from users limit 1 | db.users.findOne() | 條件查詢 |
| select * from users where name like "%Joe%" | db.users.find({name:/Joe/}) | 模糊查詢 |
| select * from users where name like "Joe%" | db.users.find({name:/^Joe/}) | 模糊查詢 |
| select count(1) from users | Db.users.count() | 獲取表記錄數 |
| select count(1) from users where age>30 | db.users.find({age: {'$gt': 30}}).count() | 獲取表記錄數 |
| select DISTINCT last_name from users | db.users.distinct('last_name') | 去掉重復值 |
| select * from users ORDER BY name | db.users.find().sort({name:-1}) | 排序 |
| select * from users ORDER BY name DESC | db.users.find().sort({name:-1}) | 排序 |
| EXPLAIN select * from users where z=3 | db.users.find({z:3}).explain() | 獲取存儲路徑 |
| update users set a=1 where b='q' | db.users.update({b:'q'}, {$set:{a:1}}, false, true) | 更新記錄 |
| update users set a=a+2 where b='q' | db.users.update({b:'q'}, {$inc:{a:2}}, false, true) | 更新記錄 |
| delete from users where z="abc" | db.users.remove({z:'abc'}) | 刪除記錄 |
| ? | db. users.remove() | 刪除所有的記錄 |
| drop database IF EXISTS test; | use test db.dropDatabase() | 刪除數據庫 |
| drop table IF EXISTS test; | db.mytable.drop() | 刪除表/collection |
| ? | db.addUser(‘test’, ’test’) | 添加用戶 readOnly-->false |
| ? | db.addUser(‘test’, ’test’, true) | 添加用戶 readOnly-->true |
| ? | db.addUser("test","test222") | 更改密碼 |
| ? | db.system.users.remove({user:"test"}) 或者db.removeUser('test') | 刪除用戶 |
| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | use admin | 超級用戶 |
| ? | db.auth(‘test’, ‘test’) | 用戶授權 |
| ? | db.system.users.find() | 查看用戶列表 |
| ? | show users | 查看所有用戶 |
| ? | db.printCollectionStats() | 查看各collection的狀態 |
| ? | db.printReplicationInfo() | 查看主從復制狀態 |
| ? | show profile | 查看profiling |
| ? | db.copyDatabase('mail_addr','mail_addr_tmp') | 拷貝數據庫 |
| ? | db.users.dataSize() | 查看collection數據的大小 |
| ? | db. users.totalIndexSize() | 查詢索引的大小 |
?
2、shell數據操作實戰?
插入數據到集合
下面我們來建立一個test的集合并寫入一些數據. 建立兩個對象, j 和 t , 并保存到集合中去.
在例子里 ‘>’ 來表示是 shell 輸入提示符
有幾點需要注意下 :
- 不需要預先建立一個集合. 在第一次插入數據時候會自動建立.
- 在例子其實可以存儲任何結構的數據, 當然在實際應用我們存儲的還是相同元素的集合. 這個特性其實可以在應用里很靈活, 你不需要類似alter table 來修改你的數據結構
- 每次插入數據時候對象都會有一個ID, 名字叫 _id.
- 當你運行不同的例子, 你的對象ID值都是不同的.
下面再加點數據:
> for( var i = 1; i < 10; i++ ) db.things.save( { x:4, j:i } ); > db.things.find();{"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")}{"x" : 3 , "_id" : ObjectId("497cf61651712cf7758fbdbc")}{"x" : 4 , "j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")}{"x" : 4 , "j" : 2 , "_id" : ObjectId("497cf87151712cf7758fbdbe")}{"x" : 4 , "j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")}{"x" : 4 , "j" : 4 , "_id" : ObjectId("497cf87151712cf7758fbdc0")}{"x" : 4 , "j" : 5 , "_id" : ObjectId("497cf87151712cf7758fbdc1")}{"x" : 4 , "j" : 6 , "_id" : ObjectId("497cf87151712cf7758fbdc2")}{"x" : 4 , "j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")}{"x" : 4 , "j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")}請注意下, 這里循環次數是10, 但是只顯示到8, 還有2條數據沒有顯示.
如果想繼續查詢下面的數據只需要使用 it 命令, 就會繼續下面的數據:
{"x" : 4 , "j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")}{"x" : 4 , "j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")}繼續
> it{"x" : 4 , "j" : 9 , "_id" : ObjectId("497cf87151712cf7758fbdc5")}{"x" : 4 , "j" : 10 , "_id" : ObjectId("497cf87151712cf7758fbdc6")}從技術上講 find() 返回一個游標對象. 但在上面的例子里, 并沒有拿到一個游標的變量. 所以 shell 自動遍歷游標, 返回一個初始化的set, 并允許我們繼續用 it 迭代輸出.
當然我們也可以直接用游標來輸出, 不過這個是下一部分的內容了.
查詢數據
在沒有深入查詢之前, 我們先看看怎么從一個查詢中返回一個游標對象. 可以簡單的通過 find() 來查詢, 他返回一個任意結構的集合. 如果實現特定的查詢稍后講解.
實現上面同樣的查詢, 然后通過 while 來輸出:
上面的例子顯示了游標風格的迭代輸出. hasNext() 函數告訴我們是否還有數據, 如果有則可以調用 next() 函數. 這里我們也用了自帶的 tojson() 方法返回一個標準的 JSON 格式數據.
當我們使用的是 JavaScript shell, 可以用到JS的特性, forEach 就可以輸出游標了. 下面的例子就是使用 forEach() 來循環輸出:
forEach() 必須定義一個函數供每個游標元素調用.
> db.things.find().forEach( function(x) { print(tojson(x));});{"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")}{"x" : 3 , "_id" : ObjectId("497cf61651712cf7758fbdbc")}{"x" : 4 , "j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")}{"x" : 4 , "j" : 2 , "_id" : ObjectId("497cf87151712cf7758fbdbe")}{"x" : 4 , "j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")}{"x" : 4 , "j" : 4 , "_id" : ObjectId("497cf87151712cf7758fbdc0")}{"x" : 4 , "j" : 5 , "_id" : ObjectId("497cf87151712cf7758fbdc1")}{"x" : 4 , "j" : 6 , "_id" : ObjectId("497cf87151712cf7758fbdc2")}{"x" : 4 , "j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")}{"x" : 4 , "j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")}{"x" : 4 , "j" : 9 , "_id" : ObjectId("497cf87151712cf7758fbdc5")}>在 mongo shell 里, 我們也可以把游標當作數組來用 :
> var cursor = db.things.find();> print (tojson(cursor[4]));{"x" : 4 , "j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")}使用游標時候請注意占用內存的問題, 特別是很大的游標對象, 有可能會內存溢出. 所以應該用迭代的方式來輸出.
下面的示例則是把游標轉換成真實的數組類型:
請注意這些特性只是在 mongo shell 里使用, 而不是所有的其他應用程序驅動都支持.
MongoDB 游標對象不是沒有快照 – 如果有其他用戶在集合里第一次或者最后一次調用 next(), 你可以得不到游標里的數據. 所以要明確的鎖定你要查詢的游標.
指定條件的查詢
到這里我們已經知道怎么從游標里實現一個查詢并返回數據對象, 下面就來看看怎么根據指定的條件來查詢.
下面的示例就是說明如何執行一個類似SQL的查詢, 并演示了怎么在 MongoDB 里實現. 這是在 MongoDB shell 里查詢, 當然你也可以用其他的應用驅動或者語言來實現:
SELECT * FROM things WHERE name="mongo" >db.things.find({name:"mongo"}).forEach(function(x) { print(tojson(x));});{"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")}>SELECT * FROM things WHERE x=4> db.things.find({x:4}).forEach(function(x) { print(tojson(x));});{"x" : 4 , "j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")}{"x" : 4 , "j" : 2 , "_id" : ObjectId("497cf87151712cf7758fbdbe")}{"x" : 4 , "j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")}{"x" : 4 , "j" : 4 , "_id" : ObjectId("497cf87151712cf7758fbdc0")}{"x" : 4 , "j" : 5 , "_id" : ObjectId("497cf87151712cf7758fbdc1")}{"x" : 4 , "j" : 6 , "_id" : ObjectId("497cf87151712cf7758fbdc2")}{"x" : 4 , "j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")}{"x" : 4 , "j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")}{"x" : 4 , "j" : 9 , "_id" : ObjectId("497cf87151712cf7758fbdc5")}>查詢條件是 { a:A, b:B, … } 類似 “where a==A and b==B and …”, 更多的查詢方式可以參考 Mongo 開發教程部分.
上面顯示的是所有的元素, 當然我們也可以返回特定的元素, 類似于返回表里某字段的值, 只需要在 find({x:4}) 里指定元素的名字, 比如 j:
SELECT j FROM things WHERE x=4> db.things.find({x:4}, {j:true}).forEach(function(x) { print(tojson(x));});{"j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")}{"j" : 2 , "_id" : ObjectId("497cf87151712cf7758fbdbe")}{"j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")}{"j" : 4 , "_id" : ObjectId("497cf87151712cf7758fbdc0")}{"j" : 5 , "_id" : ObjectId("497cf87151712cf7758fbdc1")}{"j" : 6 , "_id" : ObjectId("497cf87151712cf7758fbdc2")}{"j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")}{"j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")}{"j" : 9 , "_id" : ObjectId("497cf87151712cf7758fbdc5")}>請注意 “_id” 元素會一直被返回.
findOne()?
為了方便, mongo shell (其他驅動) 避免游標的可能帶來的開銷, 提供一個findOne() 函數. 這個函數和 find() 參數一樣, 不過他返回游標里第一條數據, 或者返回 null 空數據庫.
作為一個例子, name==’mongo’ 可以用很多方法來實現, 可以用 next() 來循環游標(需要校驗是否為null), 或者當做數組返回第一個元素.
但是用 findOne() 方法則更簡單和高效:
> var mongo = db.things.findOne({name:"mongo"});> print(tojson(mongo));{"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")}>findOne 方法更跟 find({name:”mongo”}).limit(1) 一樣.
limit() 查詢
你可以需要限制結果集的長度, 可以調用 limit 方法.
這是強烈推薦高性能的原因, 通過限制條數來減少網絡傳輸, 例如:
> db.things.find().limit(3);in cursor for : DBQuery: example.things ->{"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")}{"x" : 3 , "_id" : ObjectId("497cf61651712cf7758fbdbc")}{"x" : 4 , "j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")}>更多幫助
除非了一般的 help 之外, 你還可以查詢 help 數據庫和db.whatever 來查詢具體的說明.
這篇寫得常用命令也不錯http://www.cnblogs.com/hoojo/archive/2011/06/01/2066426.html
四、與java結合
使用JAVA語言操作MONGODB非常簡單,只要將驅動文件加入到CLASSPATH中就可以使用。
junit-4.11和hamcrest-core-1.3是junit4依賴包
mongo-java-driver-2.9.3為mongodb的java驅動包
實戰:
import com.mongodb.Mongo;
import com.mongodb.DBCollection;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.DBCursor;
import com.mongodb.MongoAdmin;
1、獲得連接
Mongo db = new Mongo("mydb");
Mongo db = new Mongo("localhost", "mydb");
Mongo db = new Mongo("localhost", 27017, "mydb");
查看mongoDB數據庫列表?
Mongo m = new Mongo();?
for (String s : m.getDatabaseNames()) {?
System.out.println(s);?
}?
刪除一個數據庫?
Mongo m = new Mongo();?
m.dropDatabase("myDatabaseName");?
2 安全驗證(非必選)
MongoDB服務可以在安全模式運行,此時任何客戶端要連接數據庫時需使用用戶名和密碼。在JAVA中可使用如下方法連接:
boolean auth = db.authenticate(userName, password);
如果用戶名密碼驗證通過,返回值為true,否則為false
3 獲取集合列表
每個數據庫都存在零個或多個集合,需要時你可以獲得他們的列表:
Set<String> colls = db.getCollectionNames();
for(String s : colls){
System.out.println(s);
}
4 獲得一個集合
要獲得某個特定集合,你可以指定集合的名字,并使用getCollection()方法:
DBCollection coll = db.getCollection("testCollection");
當你獲取了這個集合對象,你就可以對數據進行增刪查改之類的操作。
查看一個集合的索引?
List<DBObject> list = coll.getIndexInfo();?
for (DBObject o : list) {?
System.out.println(o);?
}?
5 插入文檔
默認ID?
當保存的對象沒有設置ID時,mongoDB會默認給該條記錄設置一個ID("_id")。?
當然你也可以設置自己指定的ID,如:(在mongoDB中執行用db.users.save({_id:1,name:'bruce'});)?
當你獲得了一個集合對象,你就可以把文檔插入到這個對象中。例如,存在一個JSON式的小文檔:
{
"name" : "MongoDB",
"type" : "database",
"count" : 1,
"info" : {
?? x : 203,
?? y : 102
? }
}
請注意,這個文檔包含一個內部文檔。我們可以使用BasicDBObject類來創建這個文檔,并且使用insert()方法方便地將它插入到集
合中。
BasicDBObject doc = new BasicDBObject();
doc.put("name", "MongoDB");
doc.put("type", "database");
doc.put("count", 1);
BasicDBObject info = new BasicDBObject();
info.put("x", 203);
info.put("y", 102);
doc.put("info", info);
coll.insert(doc);
批量插入?
List datas = new ArrayList();?
for (int i=0; i < 100; i++) {?
BasicDBObject bo = new BasicDBObject();?
bo.put("name", "bruce");?
bo.append("age", i);?
datas.add(bo);?
}?
coll.insert(datas);?
6 使用findOne()查找集合中第一個文檔
要查找我們上一步插入的那個文檔,可以簡單地使用findOne()操作來獲取集合中第一個文檔。這個方法返回一個單一文檔(這是相對于使用DBCursor的find()操作的返回),這對于只有一個文檔或我們剛插入第一個文檔時很有用,因為此時并不需要使用光標。
DBObject myDoc = coll.findOne();
System.out.println(myDoc);
返回類似:
{
"_id" : "ac907a1f5b9d5e4a233ed300" ,
"name" : "MongoDB" ,
"type" : 1 ,
"info" : {
? "x" : 203 ,
? "y" : 102} ,
"_ns" : "testCollection"
}
注意_id和_ns元素是由MongoDB自動加入你的文檔。記住:MongoDB內部存儲使用的元素名是以“_”做為開始。
7 加入多種文檔
為了做更多有趣的查詢試驗,讓我們向集合中加入多種文檔類型,象:
{
"i" : value
}
可以通過循環來實現
for(int i = 0; i < 100; i++){
coll.insert(new BasicDBObject().append("i", i));
}
注意我們可以在一個集合中插入不同類型的文檔,這就是我們所說的“模式自由”(schema-free)。
8 統計文檔數量
使用getCount()方法
System.out.println(coll.getCount());
9 使用光標(cursor)來獲取全部文檔
為了獲取集合中的所有文檔,我們可以使用find()方法。這個方法返回一上DBCursor對象,來允許我們將符合查詢條件的文檔迭代
出來。
DBCursor cur = coll.find();
while(cur.hasNext()){
System.out.println(cur.next());
}
10 在查詢中獲取單一文檔
我們可以創建一個查詢,并傳遞給find()方法來獲取集合中所有文檔的一個子集。例如,我們想要查詢域名為"i",并且值為71的文檔:
BasicDBObject query = new BasicDBObject();
query.put("i", 71);
cur = coll.find(query);
while(cur.hasNext()){
System.out.println(cur.next());
}
類轉換?
當把一個類對象存到mongoDB后,從mongoDB取出來時使用setObjectClass()將其轉換回原來的類。?
public class Tweet implements DBObject {?
??? /* ... */?
}?
Tweet myTweet = new Tweet();?
myTweet.put("user", "bruce");?
myTweet.put("message", "fun");?
myTweet.put("date", new Date());?
collection.insert(myTweet);?
//轉換?
collection.setObjectClass(Tweet);?
Tweet myTweet = (Tweet)collection.findOne();?
11 使用條件查詢獲取集合
比較符?
"$gt": 大于?
"$gte":大于等于?
"$lt": 小于?
"$lte":小于等于?
"$in": 包含?
例如,我們想要查詢所有i>50的文檔:
BasicDBObject query = new BasicDBObject();
query.put("i", new BasicDBObject("$gt", 50));
cur = coll.find(query);
while(cur.hasNext()){
System.out.println(cur.next());
}
當然,我們也可以做20 < i <= 30的查詢
BasicDBObject query = new BasicDBObject();
query.put("i", new BasicDBObject("$gt", 20).append("$lte", 30));
cur = coll.find(query);
while(cur.hasNext()){
System.out.println(cur.next());
}
正則表達式?
查詢所有名字匹配 /joh?n/i 的記錄?
Pattern pattern = Pattern.compile("joh?n", CASE_INSENSITIVE);?
BasicDBObject query = new BasicDBObject("name", pattern);?
DBCursor cursor = coll.find(query);?
12 創建索引
MongoDB支持索引,而且很容易在集合上增加索引。要創建索引,只需要指定要加索引的屬性,并且指定升序(1)或降序即可(-1)。
coll.createIndex(new BasicDBObject("i", 1));
13 獲取索引列表
List<DBObject> list = coll.getIndexInfo();
for(DBObject o : list){
System.out.println(o);
}
14 MongoDB管理函數
管理函數在com.mongodb.MongoAdmin類中定義。
例A:獲取數據庫列表
MongoAdmin admin = new MongoAdmin();
for(String s : admin.getDatabaseNames()){
? System.out.println(s);
}
例B:獲取數據庫對象
Mongo m = admin.getDB("mydb");
例C:刪除數據庫
admin.dropDatabase("mydb");
15 用DBObject存儲JAVA對象
MongoDB for JAVA驅動中提供了用于向數據庫中存儲普通對象的接口DBObject
例如,存在一個需要存儲的對象類Tweet
public class Tweet implements DBObject{
/*...*/
}
可以使用如下代碼:
Tweet myTweet = new Tweet();
myTweet.put("user", userId);
myTweet.put("message", message);
myTweet.put("date", new Date());
collection.insert(myTweet);
當一個文檔從MongoDB中取出時,它會自動把文檔轉換成DBObject接口類型,要將它實例化為你的對象,需使用
DBCollection.setObjectClass()。
collection.setObjectClass(Tweet);
Tweet myTweet = (Tweet)collection.findOne();
16 JAVA驅動的并發性
JAVA的MongoDB驅動是線程安全的。如果你將它用在WEB服務中,可以創建它的一個單例,并在所有請求中使用它。
然而,如果你需要在一個會話(例如HTTP請求)中保證事務一致性,也許你會希望在這個會話中對驅動使用同一個端口。這僅僅在
請求量非常大的環境中,例如你經常會讀取剛寫入的數據。
為了這一點,你需要使用如下代碼:
Mongo m;
m.restartStart();
// code.........
m.requestDone();
源碼下載地址
參考:
http://www.iteye.com/blogs/tag/NoSQL
http://blog.nosqlfan.com/html/2215.html
http://josh-persistence.iteye.com/blog/1882436
http://www.mongodb.org/display/DOCS/Manual
http://blog.nosqlfan.com/html/342.html
http://myeyeofjava.iteye.com/blog/1296575
http://docs.mongodb.org/ecosystem/drivers/java/
?
總結
以上是生活随笔為你收集整理的mongoDB入门必读(概念与实战并重)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不可新增人员
- 下一篇: Servlet基本_オブジェクトのスコー