甩祸 发表于 2015-7-8 09:04:13

Java的MongoDB驱动及读写策略

网上看见一篇博文,详细讲了MongoDB读写策略,将来生产会遇到类似的问题,转来备查。
指定新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 of members
Mongo m = new Mongo(Arrays.asList(new ServerAddress("localhost", 27017),
                                    new ServerAddress("localhost", 27018),
                                    new ServerAddress("localhost", 27019)));
然后发起连接(必须指定数据库名,可以不存在)
DB db = m.getDB( "mydb" );

注意Mongo已经实现了连接池,并且是线程安全的。

大部分用户使用mongodb都在安全内网下,但如果将mongodb设为安全验证模式,就需要在客户端提供用户名和密码:
boolean auth = db.authenticate(myUserName, myPassword);

获取集合(collection)的名称列表(类似show databases):
Set colls = db.getCollectionNames();

获取一个集合(以便增删改查操作):
DBCollection coll = db.getCollection("testCollection")

-------------------------------------------------------------
先假设要插入的json数据如下:
{
   "name" : "MongoDB",
   "type" : "database",
   "count" : 1,
   "info" : {
               x : 203,
               y : 102
             }
}

将其插入数据库:
      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);

-------------------------------------------------------------
设定write concern,以便操作失败时得到提示:
m.setWriteConcern(WriteConcern.SAFE);
-------------------------------------------------------------
查找一个/第一个记录:
DBObject myDoc = coll.findOne();
System.out.println(myDoc);

注意:属性名不能以下划线或者美元符号开始,mongodb自己保留。

获取总记录数:
System.out.println(coll.getCount());

使用游标操作查询结果:
      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驱动里,{$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();
      }

条件查询一批数据:
以下是查询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

注意上面settings字段,我们定义了一个新的getLastErrorModes对象,键为DRSafe。当我们客户端采用此错误模式作为WriteConcern的时候,它会使写操作在完成前复制到至少两个节点上。下面是使用的例子:
//使用自定义的getLastErrorMode创建WriteConcern
WriteConcern concern = new WriteConcern("DRSafe");
//使用自定义的WriteConcern进行写操作
coll.insert(new BasicDBObject("name", "simple doc"), concern);

----------------------------
在优先读取策略(Read Preferences)中使用节点标记(Tags):

假如我们想要将读请求发送到最近的节点上以便减少请求延时:
DBObject query = new BasicDBObject("name", "simple doc")
DBObject result = coll.findOne(query, null, ReadPreference.nearest());
这样java驱动会自动将读请求发送到ping值最小的节点(也有可能是主节点)。

但是,如果我们的java驱动可以确定自己的请求发送源位置,那么就可以明确指定将读请求发送到距离最近的数据中心。再看上面的例子,假如这个读请求来自南加利福尼亚,我们就明确指定这个读请求到Los Angeles数据中心:
// 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失败,则发送到"US_West"区域的某个节点:
// read from either LA or US_West
DBObject tagSetOne = new BasicDBObject("datacenter", "Los Angeles"):
DBObject tagSetTwo = new BasicDBObject("region", "US_West");
ReadPreference pref = ReadPreference.primaryPreferred(tagSetOne, tagSetTwo);

下面的例子同样指定多个tag,首先请求"datacenter=Los Angeles"且"rack=1"的节点,如果失败则查找"region=US_West"的节点
// read from either LA or US_West
DBObject tagSetOne = new BasicDBObject("datacenter", "Los Angeles");
tagSetOne.put("rack", "1");
DBObject tagSetTwo = new BasicDBObject("region", "US_West");
ReadPreference pref = ReadPreference.primaryPreferred(tagSetOne, tagSetTwo);

优先读取策略(Read Preferences)可以在operation, collection, DB, Mongo, MongoOptions, MongoURI各个级别来设置,而且设置会以slaveOK和WriteConcer类似的方式来继承。
优先读取策略(Read Preferences)在支持主从复制的服务器上(1.6+)都可以使用。
在优先读取策略(Read Preferences)中使用节点标记(Tags)在所有支持节点标记的服务器(2.0+)都可以使用。
在分片(shard)上使用节点标记(Tags),必须是2.2+版本的服务器才可以。

转自 http://www.blogjava.net/watchzerg/archive/2012/09/22/388346.html
页: [1]
查看完整版本: Java的MongoDB驱动及读写策略