2012年11月1日 星期四

用 Java 存取 MongoDB

要透過 Java 連接、插入和讀取 MongoDB,方法其實在官方的文件 [1] 中寫得蠻清楚的~
以下直接轉貼官方的範例。

連接 MongoDB
Mongo m = new Mongo();
DB db = m.getDB( "mydb" );
DBCollection coll = db.getCollection("testCollection");
在產生 Mongo 的實體時,如果沒有輸入任何參數,會自動使用 MongoDB 預設的 localhost:27017 來連接。
有需要的時候可以自行指定位址和連接埠,另外也可以用 ServerAddress 的方式來表達多個 MongoDB 的位址(用於 sharding)。

初始化 Mongo 的實體之後,可以使用 getDB() 來指定要使用的資料庫名稱,然後再使用 getCollection() 選定目前要存取的集合名稱。

新增資料到 MongoDB
在 Java 中要對 MongoDB 下指令,通常都會使用 BasicDBObject 這個物件來作為指令
這個物件其實格式就是 JSON 的格式,因為 MongoDB 都是直接使用 JSON 來下指令的。
舉例來說,如果要插入的資料是以下的資料:
{
  "name": "MongoDB",
  "type": "database",
  "count": 1
  "info": {
    "x": 203,
    "y": 102
  }
}
那麼在 Java 中插入的方法如下:
BasicDBObject doc = new BasicDBObject();
doc.put("name", "MongoDB");
doc.put("type", "database");
doc.put("count", 1);
// Info
BasicDBObject info = new BasicDBObject();
info.put("x", 203);
info.put("y", 102);

doc.put("info", info);
// Insert into collection
coll.insert(doc);

在 MongoDB 上搜尋資料
搜尋資料的方法也是一樣的,一樣是透過 BasicDBObject 來操作。
BasicDBObject query = new BasicDBObject();
query.put("i", 71);
cursor = coll.find(query);

try {
  while(cursor.hasNext()) {
    System.out.println(cursor.next());
  }
} finally {
  cursor.close();
}
其中上述的 find() 的效果等同於用 MongoDB 的 Shell 執行以下的指令(假設集合名稱是 testCollection):
db.testCollection.find({i:71});
也就是要尋找在 testCollection 集合中,所有 i 的值為 71 的資料。

如果需要的是數字比較,或者是要用 Regular Expression,可以參考 [2] 的說明
有講解到在 MongoDB 裡面要如何使用更進階的 Query 方法。

在 MongoDB 上建立索引
雖然說 MongoDB 不用建索引,速度也是快得有點嚇人(可以看後面的測試...)
不過當然一般狀況下還是推薦要建立索引,畢竟速度這種東西沒有人嫌慢的!XD

註:資料量已經很多的時候才去建索引時,MongoDB 會花上比較長時間建立,並且在建立期間會鎖住整個資料庫。
如果需要維持 MongoDB 的服務持續運作,在建立索引時必須加入 background: true 屬性來要求在背景建立。

建立索引的說明可以參考官方文件 [3],基本的索引的建立方法很簡單~指令的下法一樣是透過 BasicDBObject
BasicDBObject indexDbo = new BasicDBObject();
indexDbo.append("path", 1);
coll.ensureIndex(indexDbo);
上述的指令效果等同於用 MongoDB 的 Shell 執行以下的指令(假設集合名稱是 testCollection):
db.testCollection.ensureIndex({path:1});
亦即對 testCollection 集合的 path 做索引,所以的順序為 1。
而順序的部份,依據 [3] 的說明節錄如下:
When creating an index, the number associated with a key specifies the direction of the index, so it should always be 1 (ascending) or -1 (descending). Direction doesn't matter for single key indexes or for random access retrieval but is important if you are doing sorts or range queries on compound indexes.

可以看出索引的屬性只有 1 或 -1,用來表示「遞增」或「遞減」,會影響到需要做排序或者對某個範圍搜尋的結果。

參考資料:
1、MongoDB:Java Tutorial
2、MongoDB:Advanced Queries
3、MongoDB:Indexes
4、How to query mongodb with “like” using the java api?
5、MongoDB regex, I get a different answer from the Java API compared with the console

沒有留言: