转载:mongoDB java驱动学习笔记
生活随笔
收集整理的這篇文章主要介紹了
转载:mongoDB java驱动学习笔记
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
http://www.blogjava.net/watchzerg/archive/2012/09/22/388346.html
指定新mongo實例: Mongo m = new Mongo(); Mongo m = new Mongo( "localhost" ); Mongo m = new Mongo( "localhost" , 27017 ); // or, to connect to a replica set, supply a seed list ofmembers Mongo m = new Mongo(Arrays.asList(newServerAddress("localhost", 27017), new ServerAddress("localhost", 27018), new ServerAddress("localhost", 27019))); 然后發(fā)起連接(必須指定數(shù)據(jù)庫名,可以不存在) DB db = m.getDB( "mydb" ); 注意Mongo已經(jīng)實現(xiàn)了連接池,并且是線程安全的。 大部分用戶使用mongodb都在安全內(nèi)網(wǎng)下,但如果將mongodb設(shè)為安全驗證模式,就需要在客戶端提供用戶名和密碼: boolean auth = db.authenticate(myUserName, myPassword); 獲取集合(collection)的名稱列表(類似show databases): Set colls = db.getCollectionNames(); 獲取一個集合(以便增刪改查操作): DBCollection coll = db.getCollection("testCollection") ------------------------------------------------------------- 先假設(shè)要插入的json數(shù)據(jù)如下: { "name" : "MongoDB", "type" :"database", "count" : 1, "info" : { x : 203, y : 102 } } 將其插入數(shù)據(jù)庫: 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); ------------------------------------------------------------- 設(shè)定write concern,以便操作失敗時得到提示: m.setWriteConcern(WriteConcern.SAFE); ------------------------------------------------------------- 查找一個/第一個記錄: DBObject myDoc = coll.findOne(); System.out.println(myDoc); 注意:屬性名不能以下劃線或者美元符號開始,mongodb自己保留。 獲取總記錄數(shù): System.out.println(coll.getCount()); 使用游標操作查詢結(jié)果: DBCursor cursor = coll.find(); try { while(cursor.hasNext()) { System.out.println(cursor.next()); } } finally { cursor.close(); } 條件查詢: BasicDBObject query = new BasicDBObject(); query.put("i", 71); cursor = coll.find(query); try { while(cursor.hasNext()) { System.out.println(cursor.next()); } } finally { cursor.close(); } 如果想使用shell里的類似以下語句的功能: db.things.find({j: {$ne: 3}, k: {$gt: 10} }); 在java驅(qū)動里,{$ne: 3}也是一個普通的DBObject: BasicDBObject query = new BasicDBObject(); query.put("j", new BasicDBObject("$ne",3)); query.put("k", new BasicDBObject("$gt",10)); cursor = coll.find(query); try { while(cursor.hasNext()) { System.out.println(cursor.next()); } } finally { cursor.close(); } 條件查詢一批數(shù)據(jù): 以下是查詢i > 50的記錄: query = new BasicDBObject(); query.put("i", new BasicDBObject("$gt", 50));?// e.g. find all where i > 50 cursor = coll.find(query); try { while(cursor.hasNext()) { System.out.println(cursor.next()); } } finally { cursor.close(); } ? ?? ?? 以下是查詢20 < i <= 30的記錄: query = new BasicDBObject(); query.put("i", new BasicDBObject("$gt",20).append("$lte", 30)); ?// i.e.? 20 < i <= 30 cursor = coll.find(query); try { while(cursor.hasNext()) { System.out.println(cursor.next()); } } finally { cursor.close(); } ------------------------------------------------------------- 創(chuàng)建索引: 指定collection和要index的列即可,1代表升序,-1代表降序。 coll.createIndex(newBasicDBObject("i", 1)); ?// create index on "i",ascending 獲取索引列表: List list = coll.getIndexInfo(); for (DBObject o : list){ System.out.println(o); } ------------------------------------------------------------- 數(shù)據(jù)庫管理相關(guān)的命令: 獲取數(shù)據(jù)庫名稱列表: m.getDatabaseNames() 刪除數(shù)據(jù)庫: m.dropDatabase("my_new_db"); ------------------------------------------------------------- 聚合函數(shù):使用DBCollection.aggregate()產(chǎn)生聚合任務(wù): http://www.mongodb.org/display/DOCS/Using+The+Aggregation+Framework+with+The+Java+Driver // create our pipeline operations, firstwith the $match DBObject match = newBasicDBObject("$match", new BasicDBObject("type", "airfare")); // build the $projectionoperation DBObject fields = newBasicDBObject("department", 1); fields.put("amount", 1); fields.put("_id", 0); DBObject project = newBasicDBObject("$project", fields ); // Now the $group operation DBObject groupFields = newBasicDBObject( "_id", "$department"); groupFields.put("average", newBasicDBObject( "$avg", "$amount")); DBObject group = newBasicDBObject("$group", groupFields); // run aggregation AggregationOutput output =collection.aggregate( match, project, group );
返回結(jié)果是一個AggregationOutput對象,可以用以下方式獲取其中信息:
public Iterable results() public CommandResultgetCommandResult public DBObjectgetCommand()
示例: System.out.println(output.getCommandResult()); { "serverUsed" : "/127.0.0.1:27017", "result" : [ {"_id" : "Human Resources" , "average" :74.91735537190083} , {"_id" : "Sales" , "average" :72.30275229357798} , {"_id" : "Engineering" , "average" :74.1} ] , "ok" : 1.0 } ------------------------------------------------------------- 使用DBObject存取對象: http://www.mongodb.org/display/DOCS/Java+-+Saving+Objects+Using+DBObject 假設(shè)一個類叫做twitter,存儲前必須實現(xiàn)DBObject接口: public class Tweet implements DBObject { } 然后就可以存了: Tweet myTweet = new Tweet(); myTweet.put("user", userId); myTweet.put("message", msg); myTweet.put("date", new Date()); collection.insert(myTweet); 一個文檔從數(shù)據(jù)庫取出時,自動被轉(zhuǎn)為DBObject。如果想取出時轉(zhuǎn)為需要的類,可以先調(diào)用DBCollection.setObjectClass(),然后再進行類型強制轉(zhuǎn)換: collection.setObjectClass(Tweet.class); Tweet myTweet = (Tweet)collection.findOne(); 如果想要改變Tweet類的屬性,可以改完后再存入: Tweet myTweet = (Tweet)collection.findOne(); myTweet.put("message", newMsg); collection.save(myTweet); ------------------------------------------------------------- JAVA驅(qū)動的并發(fā): http://www.mongodb.org/display/DOCS/Java+Driver+Concurrency mongodb的java驅(qū)動是線程安全的,如果是在web服務(wù)環(huán)境下,應(yīng)該創(chuàng)建單例的mongo對象,用這個對象處理每一個請求。mongo對象維護一個內(nèi)部連接池(默認大小為10),對于每個請求(查找插入等),java線程會從線程池取一個連接,執(zhí)行操作,然后釋放連接——這意味著每次操作所使用的連接很有可能是不同的。 ------------------------------ 在復(fù)制(replica)模式下,如果設(shè)置slaveOK選項為on,那么讀操作會被均勻的分布到各個slave上。這意味著對于同一個線程,一個寫操作后緊跟著的一個讀操作,有可能被發(fā)送到不同的服務(wù)器上(寫操作發(fā)送到master上,讀操作發(fā)送到slave上),這樣讀操作有可能不會立刻反映出上一個寫操作的數(shù)據(jù)(因為主從的異步性)。 如果你想要確保在一個session中完整的一致性(例如在一個http請求中),你可能希望java驅(qū)動是用同一個socket連接,這時你可以通過使用"consistentrequest"來達到目的——在操作前后分別調(diào)用requestStart()和requestDone()。 DB db...; db.requestStart(); try { //Ensures that aconnection exists for the "consistent request" db.requestEnsureConnection(); code.... } finally { db.requestDone(); } ------------------------------ 在單獨寫操作上的WriteConcern選項: 默認情況下,每次寫操作后,連接就被釋放回連接池——此時你調(diào)用getLastError()是沒用的。 所以可以采用兩種方式: 1,使用類似WriteConcern.SAFE這樣的寫策略來代替默認策略,這樣java驅(qū)動會自動首先調(diào)用getLastError(),然后才將連接放回連接池。 DBCollection coll...; coll.insert(..., WriteConcern.SAFE); 2,采用上述的requestStart()和requestDone()方式來維持連接不被釋放,中間調(diào)用getLastError()獲取錯誤信息。 DB db...; DBCollection coll...; db.requestStart(); try { coll.insert(...); DBObject err =db.getLastError(); } finally { db.requestDone(); } 這兩種方式等價。 ------------------------------------------------------------- java類型: http://www.mongodb.org/display/DOCS/Java+Types ---------------------------- Object id被用來自動生成唯一的ID: ObjectId id = new ObjectId(); ObjectId copy = new ObjectId(id); ---------------------------- 正則表達式: java驅(qū)動使用JDK的java.util.regex.Pattern表達正則: Pattern john = Pattern.compile("joh?n",CASE_INSENSITIVE); BasicDBObject query = new BasicDBObject("name", john); // finds all people with "name" matching /joh?n/i DBCursor cursor = collection.find(query); ---------------------------- java驅(qū)動使用JDK的 java.util.Date表示日期時間: Date now = new Date(); BasicDBObject time = new BasicDBObject("ts", now); collection.save(time); ---------------------------- com.mongodb.DBRef被用來表示數(shù)據(jù)庫引用(官方一般建議手動引用): DBRef addressRef = new DBRef(db, "foo.bar", address_id); DBObject address = addressRef.fetch(); DBObject person = BasicDBObjectBuilder.start() .add("name","Fred") .add("address",addressRef) .get(); collection.save(person); DBObject fred = collection.findOne(); DBRef addressObj = (DBRef)fred.get("address"); addressObj.fetch() ---------------------------- 二進制數(shù)據(jù): java中的字節(jié)數(shù)組會自動被包裝成二進制數(shù)據(jù)存入數(shù)據(jù)庫。 二進制類可以被用來表示二進制對象,這可以用來取一個自定義類型的字節(jié)。 ---------------------------- 時間戳數(shù)據(jù)(BSONTimestamp對象): 時間戳數(shù)據(jù)是一個mongoDB使用的特殊對象,表示一個(以秒為單位的時間,自增ID)的鍵值對,這被用于主從復(fù)制的操作日志中。 ---------------------------- 代碼對象: 用于表示javascript代碼,例如保存可執(zhí)行的方法到system.js集合中。 Code和CodeWScope類用來表示這種數(shù)據(jù)。 注意有些方法(比如map/reduce)接收字符串,但是在驅(qū)動中將其包裝為代碼對象。 ---------------------------- 嵌套對象: 在javascript里面這樣一個json文檔: { "x" : { "y" : 3 } } 在java中對應(yīng)的形式是: BasicDBObject y = new BasicDBObject("y", 3); BasicDBObject x = new BasicDBObject("x", y); ---------------------------- 數(shù)組: java中所有實現(xiàn)List接口的都被以數(shù)組形式在數(shù)據(jù)庫中保存: 所以如果想保存這樣一個json: { "x" : [ 1, 2, {"foo" : "bar"}, 4 ] } 在java中可以這么做: ArrayList x = new ArrayList(); x.add(1); x.add(2); x.add(new BasicDBObject("foo", "bar")); x.add(4); BasicDBObject doc = new BasicDBObject("x", x); ------------------------------------------------------------- 在java驅(qū)動中的優(yōu)先讀取策略(Read Preferences)和節(jié)點標記(Tagging) http://www.mongodb.org/display/DOCS/Read+Preferences+and+Tagging+in+The+Java+Driver 用來允許應(yīng)用程序開發(fā)者能將讀寫操作指定在某個主從集合的成員節(jié)點上。 2.2版本在節(jié)點標記(node tagging)帶來些新的東西讓你能更好的控制你的數(shù)據(jù)的讀寫。 java驅(qū)動的2.9.0集成了mongodb2.2提供的所有新特性。 ---------------------------- 優(yōu)先讀取策略(Read Preferences): 用于提供客戶端程序選擇那個節(jié)點來讀取,有以下五個選擇: PRIMARY : 默認方式,從主節(jié)點讀取,如果主節(jié)點不可用則拋出異常,無法與標簽(tags)一起使用。 PRIMARY PREFERRED : 優(yōu)先讀取主節(jié)點,失敗的話從副節(jié)點讀取。 SECONDARY : 從副節(jié)點讀取,失敗則拋異常。 SECONDARY PREFERRED : 優(yōu)先讀取副節(jié)點,失敗則從主節(jié)點讀取。 NEAREST : 從最近的節(jié)點讀取,“最近”的定義為ping的響應(yīng)時間最短(也得滿足15毫秒以內(nèi))。 java實現(xiàn):類ReadPreference的工廠模式可以創(chuàng)建對應(yīng)上述五種策略的對象: ReadPreference.primary(); ReadPreference.primaryPreferred(); ReadPreference.secondary(); ReadPreference.secondaryPreferred(); ReadPreference.nearest(); 例如:假設(shè)我們的應(yīng)用需要保持強一致性(寫入的數(shù)據(jù)立即可以被讀出),但是我們又希望萬一主庫掛掉以后,從庫依然可以讀取。這種情況下,我們需要選擇PRIMARYPREFERRED模式: ReadPreference preference =ReadPreference.primaryPreferred(); DBCursor cur = new DBCursor(collection, query, null,preference); java驅(qū)動保持著各個節(jié)點的狀態(tài)信息(每隔一段時間ping一次所有節(jié)點),在這個例子中,java驅(qū)動會檢測到主庫的掛掉,從而將讀操作指向從節(jié)點。 ---------------------------- 節(jié)點標記(Tags): 在mongoDB2.0之后,主從集群中的每一個節(jié)點都可以被標記一個描述,稱為tags。可以用來標記一個節(jié)點的位置,和在集群中的從屬關(guān)系或者特性。這可以讓你的應(yīng)用程序從指定節(jié)點中讀寫。 例子: 假設(shè)我們要運行一個三節(jié)點的主從集群,三個節(jié)點分別在三個不同地理位置的數(shù)據(jù)中心當中。我們希望確保我們的數(shù)據(jù)在災(zāi)難中也可以恢復(fù),所以我們對每一個節(jié)點標記其地理位置,配置文件樣例如下: foo:SECONDARY> rs.conf() { "_id":"foo", "version":103132, "members":[ { "_id":0, "host":"localhost:27017", "priority":10, "tags":{ "datacenter":"Los Angeles", "region":"US_West" } }, { "_id":1, "host":"localhost:27018", "tags":{ "datacenter":"San Jose", "region":"US_West" } }, { "_id":2, "host":"localhost:27019", "tags":{ "datacenter":"Richmond", "region":"US_Eest" } } ], "settings":{ "getLastErrorModes":{ "DRSafe":{ "region":2 } } } } foo:SECONDARY> 注意上面settings字段,我們定義了一個新的getLastErrorModes對象,鍵為DRSafe。當我們客戶端采用此錯誤模式作為WriteConcern的時候,它會使寫操作在完成前復(fù)制到至少兩個節(jié)點上。下面是使用的例子: //使用自定義的getLastErrorMode創(chuàng)建WriteConcern WriteConcern concern = new WriteConcern("DRSafe"); //使用自定義的WriteConcern進行寫操作 coll.insert(new BasicDBObject("name", "simple doc"),concern); ---------------------------- 在優(yōu)先讀取策略(Read Preferences)中使用節(jié)點標記(Tags): 假如我們想要將讀請求發(fā)送到最近的節(jié)點上以便減少請求延時: DBObject query = new BasicDBObject("name", "simple doc") DBObject result = coll.findOne(query, null,ReadPreference.nearest()); 這樣java驅(qū)動會自動將讀請求發(fā)送到ping值最小的節(jié)點(也有可能是主節(jié)點)。 但是,如果我們的java驅(qū)動可以確定自己的請求發(fā)送源位置,那么就可以明確指定將讀請求發(fā)送到距離最近的數(shù)據(jù)中心。再看上面的例子,假如這個讀請求來自南加利福尼亞,我們就明確指定這個讀請求到LosAngeles數(shù)據(jù)中心: // initialize a properly tagged read preference ReadPreference tagged_pref =ReadPreference.secondaryPreferred(new BasicDBObject("datacenter","Los Angeles")); // include the tagged read preference in this request}} DBObject result = coll.findOne(}} new BasicDBObject("name", "simple doc"), null,tagged_pref); 下面的例子指定多個tag,如果讀請求在Los Angeles失敗,則發(fā)送到"US_West"區(qū)域的某個節(jié)點: // read from either LA or US_West DBObject tagSetOne = new BasicDBObject("datacenter", "LosAngeles"): DBObject tagSetTwo = new BasicDBObject("region","US_West"); ReadPreference pref =ReadPreference.primaryPreferred(tagSetOne, tagSetTwo); 下面的例子同樣指定多個tag,首先請求"datacenter=LosAngeles"且"rack=1"的節(jié)點,如果失敗則查找"region=US_West"的節(jié)點 // read from either LA or US_West DBObject tagSetOne = new BasicDBObject("datacenter", "LosAngeles"); tagSetOne.put("rack", "1"); DBObject tagSetTwo = new BasicDBObject("region","US_West"); ReadPreference pref =ReadPreference.primaryPreferred(tagSetOne, tagSetTwo); 優(yōu)先讀取策略(Read Preferences)可以在operation, collection, DB, Mongo,MongoOptions,MongoURI各個級別來設(shè)置,而且設(shè)置會以slaveOK和WriteConcer類似的方式來繼承。 優(yōu)先讀取策略(Read Preferences)在支持主從復(fù)制的服務(wù)器上(1.6+)都可以使用。 在優(yōu)先讀取策略(ReadPreferences)中使用節(jié)點標記(Tags)在所有支持節(jié)點標記的服務(wù)器(2.0+)都可以使用。 在分片(shard)上使用節(jié)點標記(Tags),必須是2.2+版本的服務(wù)器才可以。
mongoDB java驅(qū)動學(xué)習(xí)筆記
指定新mongo實例: Mongo m = new Mongo(); Mongo m = new Mongo( "localhost" ); Mongo m = new Mongo( "localhost" , 27017 ); // or, to connect to a replica set, supply a seed list ofmembers Mongo m = new Mongo(Arrays.asList(newServerAddress("localhost", 27017), new ServerAddress("localhost", 27018), new ServerAddress("localhost", 27019))); 然后發(fā)起連接(必須指定數(shù)據(jù)庫名,可以不存在) DB db = m.getDB( "mydb" ); 注意Mongo已經(jīng)實現(xiàn)了連接池,并且是線程安全的。 大部分用戶使用mongodb都在安全內(nèi)網(wǎng)下,但如果將mongodb設(shè)為安全驗證模式,就需要在客戶端提供用戶名和密碼: boolean auth = db.authenticate(myUserName, myPassword); 獲取集合(collection)的名稱列表(類似show databases): Set colls = db.getCollectionNames(); 獲取一個集合(以便增刪改查操作): DBCollection coll = db.getCollection("testCollection") ------------------------------------------------------------- 先假設(shè)要插入的json數(shù)據(jù)如下: { "name" : "MongoDB", "type" :"database", "count" : 1, "info" : { x : 203, y : 102 } } 將其插入數(shù)據(jù)庫: 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); ------------------------------------------------------------- 設(shè)定write concern,以便操作失敗時得到提示: m.setWriteConcern(WriteConcern.SAFE); ------------------------------------------------------------- 查找一個/第一個記錄: DBObject myDoc = coll.findOne(); System.out.println(myDoc); 注意:屬性名不能以下劃線或者美元符號開始,mongodb自己保留。 獲取總記錄數(shù): System.out.println(coll.getCount()); 使用游標操作查詢結(jié)果: DBCursor cursor = coll.find(); try { while(cursor.hasNext()) { System.out.println(cursor.next()); } } finally { cursor.close(); } 條件查詢: BasicDBObject query = new BasicDBObject(); query.put("i", 71); cursor = coll.find(query); try { while(cursor.hasNext()) { System.out.println(cursor.next()); } } finally { cursor.close(); } 如果想使用shell里的類似以下語句的功能: db.things.find({j: {$ne: 3}, k: {$gt: 10} }); 在java驅(qū)動里,{$ne: 3}也是一個普通的DBObject: BasicDBObject query = new BasicDBObject(); query.put("j", new BasicDBObject("$ne",3)); query.put("k", new BasicDBObject("$gt",10)); cursor = coll.find(query); try { while(cursor.hasNext()) { System.out.println(cursor.next()); } } finally { cursor.close(); } 條件查詢一批數(shù)據(jù): 以下是查詢i > 50的記錄: query = new BasicDBObject(); query.put("i", new BasicDBObject("$gt", 50));?// e.g. find all where i > 50 cursor = coll.find(query); try { while(cursor.hasNext()) { System.out.println(cursor.next()); } } finally { cursor.close(); } ? ?? ?? 以下是查詢20 < i <= 30的記錄: query = new BasicDBObject(); query.put("i", new BasicDBObject("$gt",20).append("$lte", 30)); ?// i.e.? 20 < i <= 30 cursor = coll.find(query); try { while(cursor.hasNext()) { System.out.println(cursor.next()); } } finally { cursor.close(); } ------------------------------------------------------------- 創(chuàng)建索引: 指定collection和要index的列即可,1代表升序,-1代表降序。 coll.createIndex(newBasicDBObject("i", 1)); ?// create index on "i",ascending 獲取索引列表: List list = coll.getIndexInfo(); for (DBObject o : list){ System.out.println(o); } ------------------------------------------------------------- 數(shù)據(jù)庫管理相關(guān)的命令: 獲取數(shù)據(jù)庫名稱列表: m.getDatabaseNames() 刪除數(shù)據(jù)庫: m.dropDatabase("my_new_db"); ------------------------------------------------------------- 聚合函數(shù):使用DBCollection.aggregate()產(chǎn)生聚合任務(wù): http://www.mongodb.org/display/DOCS/Using+The+Aggregation+Framework+with+The+Java+Driver // create our pipeline operations, firstwith the $match DBObject match = newBasicDBObject("$match", new BasicDBObject("type", "airfare")); // build the $projectionoperation DBObject fields = newBasicDBObject("department", 1); fields.put("amount", 1); fields.put("_id", 0); DBObject project = newBasicDBObject("$project", fields ); // Now the $group operation DBObject groupFields = newBasicDBObject( "_id", "$department"); groupFields.put("average", newBasicDBObject( "$avg", "$amount")); DBObject group = newBasicDBObject("$group", groupFields); // run aggregation AggregationOutput output =collection.aggregate( match, project, group );
返回結(jié)果是一個AggregationOutput對象,可以用以下方式獲取其中信息:
public Iterable results() public CommandResultgetCommandResult public DBObjectgetCommand()
示例: System.out.println(output.getCommandResult()); { "serverUsed" : "/127.0.0.1:27017", "result" : [ {"_id" : "Human Resources" , "average" :74.91735537190083} , {"_id" : "Sales" , "average" :72.30275229357798} , {"_id" : "Engineering" , "average" :74.1} ] , "ok" : 1.0 } ------------------------------------------------------------- 使用DBObject存取對象: http://www.mongodb.org/display/DOCS/Java+-+Saving+Objects+Using+DBObject 假設(shè)一個類叫做twitter,存儲前必須實現(xiàn)DBObject接口: public class Tweet implements DBObject { } 然后就可以存了: Tweet myTweet = new Tweet(); myTweet.put("user", userId); myTweet.put("message", msg); myTweet.put("date", new Date()); collection.insert(myTweet); 一個文檔從數(shù)據(jù)庫取出時,自動被轉(zhuǎn)為DBObject。如果想取出時轉(zhuǎn)為需要的類,可以先調(diào)用DBCollection.setObjectClass(),然后再進行類型強制轉(zhuǎn)換: collection.setObjectClass(Tweet.class); Tweet myTweet = (Tweet)collection.findOne(); 如果想要改變Tweet類的屬性,可以改完后再存入: Tweet myTweet = (Tweet)collection.findOne(); myTweet.put("message", newMsg); collection.save(myTweet); ------------------------------------------------------------- JAVA驅(qū)動的并發(fā): http://www.mongodb.org/display/DOCS/Java+Driver+Concurrency mongodb的java驅(qū)動是線程安全的,如果是在web服務(wù)環(huán)境下,應(yīng)該創(chuàng)建單例的mongo對象,用這個對象處理每一個請求。mongo對象維護一個內(nèi)部連接池(默認大小為10),對于每個請求(查找插入等),java線程會從線程池取一個連接,執(zhí)行操作,然后釋放連接——這意味著每次操作所使用的連接很有可能是不同的。 ------------------------------ 在復(fù)制(replica)模式下,如果設(shè)置slaveOK選項為on,那么讀操作會被均勻的分布到各個slave上。這意味著對于同一個線程,一個寫操作后緊跟著的一個讀操作,有可能被發(fā)送到不同的服務(wù)器上(寫操作發(fā)送到master上,讀操作發(fā)送到slave上),這樣讀操作有可能不會立刻反映出上一個寫操作的數(shù)據(jù)(因為主從的異步性)。 如果你想要確保在一個session中完整的一致性(例如在一個http請求中),你可能希望java驅(qū)動是用同一個socket連接,這時你可以通過使用"consistentrequest"來達到目的——在操作前后分別調(diào)用requestStart()和requestDone()。 DB db...; db.requestStart(); try { //Ensures that aconnection exists for the "consistent request" db.requestEnsureConnection(); code.... } finally { db.requestDone(); } ------------------------------ 在單獨寫操作上的WriteConcern選項: 默認情況下,每次寫操作后,連接就被釋放回連接池——此時你調(diào)用getLastError()是沒用的。 所以可以采用兩種方式: 1,使用類似WriteConcern.SAFE這樣的寫策略來代替默認策略,這樣java驅(qū)動會自動首先調(diào)用getLastError(),然后才將連接放回連接池。 DBCollection coll...; coll.insert(..., WriteConcern.SAFE); 2,采用上述的requestStart()和requestDone()方式來維持連接不被釋放,中間調(diào)用getLastError()獲取錯誤信息。 DB db...; DBCollection coll...; db.requestStart(); try { coll.insert(...); DBObject err =db.getLastError(); } finally { db.requestDone(); } 這兩種方式等價。 ------------------------------------------------------------- java類型: http://www.mongodb.org/display/DOCS/Java+Types ---------------------------- Object id被用來自動生成唯一的ID: ObjectId id = new ObjectId(); ObjectId copy = new ObjectId(id); ---------------------------- 正則表達式: java驅(qū)動使用JDK的java.util.regex.Pattern表達正則: Pattern john = Pattern.compile("joh?n",CASE_INSENSITIVE); BasicDBObject query = new BasicDBObject("name", john); // finds all people with "name" matching /joh?n/i DBCursor cursor = collection.find(query); ---------------------------- java驅(qū)動使用JDK的 java.util.Date表示日期時間: Date now = new Date(); BasicDBObject time = new BasicDBObject("ts", now); collection.save(time); ---------------------------- com.mongodb.DBRef被用來表示數(shù)據(jù)庫引用(官方一般建議手動引用): DBRef addressRef = new DBRef(db, "foo.bar", address_id); DBObject address = addressRef.fetch(); DBObject person = BasicDBObjectBuilder.start() .add("name","Fred") .add("address",addressRef) .get(); collection.save(person); DBObject fred = collection.findOne(); DBRef addressObj = (DBRef)fred.get("address"); addressObj.fetch() ---------------------------- 二進制數(shù)據(jù): java中的字節(jié)數(shù)組會自動被包裝成二進制數(shù)據(jù)存入數(shù)據(jù)庫。 二進制類可以被用來表示二進制對象,這可以用來取一個自定義類型的字節(jié)。 ---------------------------- 時間戳數(shù)據(jù)(BSONTimestamp對象): 時間戳數(shù)據(jù)是一個mongoDB使用的特殊對象,表示一個(以秒為單位的時間,自增ID)的鍵值對,這被用于主從復(fù)制的操作日志中。 ---------------------------- 代碼對象: 用于表示javascript代碼,例如保存可執(zhí)行的方法到system.js集合中。 Code和CodeWScope類用來表示這種數(shù)據(jù)。 注意有些方法(比如map/reduce)接收字符串,但是在驅(qū)動中將其包裝為代碼對象。 ---------------------------- 嵌套對象: 在javascript里面這樣一個json文檔: { "x" : { "y" : 3 } } 在java中對應(yīng)的形式是: BasicDBObject y = new BasicDBObject("y", 3); BasicDBObject x = new BasicDBObject("x", y); ---------------------------- 數(shù)組: java中所有實現(xiàn)List接口的都被以數(shù)組形式在數(shù)據(jù)庫中保存: 所以如果想保存這樣一個json: { "x" : [ 1, 2, {"foo" : "bar"}, 4 ] } 在java中可以這么做: ArrayList x = new ArrayList(); x.add(1); x.add(2); x.add(new BasicDBObject("foo", "bar")); x.add(4); BasicDBObject doc = new BasicDBObject("x", x); ------------------------------------------------------------- 在java驅(qū)動中的優(yōu)先讀取策略(Read Preferences)和節(jié)點標記(Tagging) http://www.mongodb.org/display/DOCS/Read+Preferences+and+Tagging+in+The+Java+Driver 用來允許應(yīng)用程序開發(fā)者能將讀寫操作指定在某個主從集合的成員節(jié)點上。 2.2版本在節(jié)點標記(node tagging)帶來些新的東西讓你能更好的控制你的數(shù)據(jù)的讀寫。 java驅(qū)動的2.9.0集成了mongodb2.2提供的所有新特性。 ---------------------------- 優(yōu)先讀取策略(Read Preferences): 用于提供客戶端程序選擇那個節(jié)點來讀取,有以下五個選擇: PRIMARY : 默認方式,從主節(jié)點讀取,如果主節(jié)點不可用則拋出異常,無法與標簽(tags)一起使用。 PRIMARY PREFERRED : 優(yōu)先讀取主節(jié)點,失敗的話從副節(jié)點讀取。 SECONDARY : 從副節(jié)點讀取,失敗則拋異常。 SECONDARY PREFERRED : 優(yōu)先讀取副節(jié)點,失敗則從主節(jié)點讀取。 NEAREST : 從最近的節(jié)點讀取,“最近”的定義為ping的響應(yīng)時間最短(也得滿足15毫秒以內(nèi))。 java實現(xiàn):類ReadPreference的工廠模式可以創(chuàng)建對應(yīng)上述五種策略的對象: ReadPreference.primary(); ReadPreference.primaryPreferred(); ReadPreference.secondary(); ReadPreference.secondaryPreferred(); ReadPreference.nearest(); 例如:假設(shè)我們的應(yīng)用需要保持強一致性(寫入的數(shù)據(jù)立即可以被讀出),但是我們又希望萬一主庫掛掉以后,從庫依然可以讀取。這種情況下,我們需要選擇PRIMARYPREFERRED模式: ReadPreference preference =ReadPreference.primaryPreferred(); DBCursor cur = new DBCursor(collection, query, null,preference); java驅(qū)動保持著各個節(jié)點的狀態(tài)信息(每隔一段時間ping一次所有節(jié)點),在這個例子中,java驅(qū)動會檢測到主庫的掛掉,從而將讀操作指向從節(jié)點。 ---------------------------- 節(jié)點標記(Tags): 在mongoDB2.0之后,主從集群中的每一個節(jié)點都可以被標記一個描述,稱為tags。可以用來標記一個節(jié)點的位置,和在集群中的從屬關(guān)系或者特性。這可以讓你的應(yīng)用程序從指定節(jié)點中讀寫。 例子: 假設(shè)我們要運行一個三節(jié)點的主從集群,三個節(jié)點分別在三個不同地理位置的數(shù)據(jù)中心當中。我們希望確保我們的數(shù)據(jù)在災(zāi)難中也可以恢復(fù),所以我們對每一個節(jié)點標記其地理位置,配置文件樣例如下: foo:SECONDARY> rs.conf() { "_id":"foo", "version":103132, "members":[ { "_id":0, "host":"localhost:27017", "priority":10, "tags":{ "datacenter":"Los Angeles", "region":"US_West" } }, { "_id":1, "host":"localhost:27018", "tags":{ "datacenter":"San Jose", "region":"US_West" } }, { "_id":2, "host":"localhost:27019", "tags":{ "datacenter":"Richmond", "region":"US_Eest" } } ], "settings":{ "getLastErrorModes":{ "DRSafe":{ "region":2 } } } } foo:SECONDARY> 注意上面settings字段,我們定義了一個新的getLastErrorModes對象,鍵為DRSafe。當我們客戶端采用此錯誤模式作為WriteConcern的時候,它會使寫操作在完成前復(fù)制到至少兩個節(jié)點上。下面是使用的例子: //使用自定義的getLastErrorMode創(chuàng)建WriteConcern WriteConcern concern = new WriteConcern("DRSafe"); //使用自定義的WriteConcern進行寫操作 coll.insert(new BasicDBObject("name", "simple doc"),concern); ---------------------------- 在優(yōu)先讀取策略(Read Preferences)中使用節(jié)點標記(Tags): 假如我們想要將讀請求發(fā)送到最近的節(jié)點上以便減少請求延時: DBObject query = new BasicDBObject("name", "simple doc") DBObject result = coll.findOne(query, null,ReadPreference.nearest()); 這樣java驅(qū)動會自動將讀請求發(fā)送到ping值最小的節(jié)點(也有可能是主節(jié)點)。 但是,如果我們的java驅(qū)動可以確定自己的請求發(fā)送源位置,那么就可以明確指定將讀請求發(fā)送到距離最近的數(shù)據(jù)中心。再看上面的例子,假如這個讀請求來自南加利福尼亞,我們就明確指定這個讀請求到LosAngeles數(shù)據(jù)中心: // initialize a properly tagged read preference ReadPreference tagged_pref =ReadPreference.secondaryPreferred(new BasicDBObject("datacenter","Los Angeles")); // include the tagged read preference in this request}} DBObject result = coll.findOne(}} new BasicDBObject("name", "simple doc"), null,tagged_pref); 下面的例子指定多個tag,如果讀請求在Los Angeles失敗,則發(fā)送到"US_West"區(qū)域的某個節(jié)點: // read from either LA or US_West DBObject tagSetOne = new BasicDBObject("datacenter", "LosAngeles"): DBObject tagSetTwo = new BasicDBObject("region","US_West"); ReadPreference pref =ReadPreference.primaryPreferred(tagSetOne, tagSetTwo); 下面的例子同樣指定多個tag,首先請求"datacenter=LosAngeles"且"rack=1"的節(jié)點,如果失敗則查找"region=US_West"的節(jié)點 // read from either LA or US_West DBObject tagSetOne = new BasicDBObject("datacenter", "LosAngeles"); tagSetOne.put("rack", "1"); DBObject tagSetTwo = new BasicDBObject("region","US_West"); ReadPreference pref =ReadPreference.primaryPreferred(tagSetOne, tagSetTwo); 優(yōu)先讀取策略(Read Preferences)可以在operation, collection, DB, Mongo,MongoOptions,MongoURI各個級別來設(shè)置,而且設(shè)置會以slaveOK和WriteConcer類似的方式來繼承。 優(yōu)先讀取策略(Read Preferences)在支持主從復(fù)制的服務(wù)器上(1.6+)都可以使用。 在優(yōu)先讀取策略(ReadPreferences)中使用節(jié)點標記(Tags)在所有支持節(jié)點標記的服務(wù)器(2.0+)都可以使用。 在分片(shard)上使用節(jié)點標記(Tags),必須是2.2+版本的服務(wù)器才可以。
轉(zhuǎn)載于:https://www.cnblogs.com/leeeee/p/7276594.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的转载:mongoDB java驱动学习笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 博途V16软件官方下载和安装
- 下一篇: unity 字体 素材_unity中文字