转载  

       

在工作中使用到了MongoDB,平时也看了一些资料,感觉MongoDB官网内develop zone有个不错的manual,很多资料都可以查到,地址如下:

另外,本blog主要记录一下使用mongodb java driver来访问数据库的一些总结。

主要是由createMongoInstance()方法完成初始化工作。

Java代码  
  1. protectedstaticfinal Mongo mongoInstance = createMongoInstance();  

  2. privatestatic Mongo createMongoInstance() {  

  3.        MongoOptions mo = new MongoOptions();  

  4.        mo.socketKeepAlive=true;  

  5.        mo.autoConnectRetry = true;  

  6.        mo.maxAutoConnectRetryTime=10;  

  7.        mo.connectionsPerHost = 40;  

  8.        mo.connectTimeout = 20 * 1000;  

  9.        mo.socketTimeout = 60 * 1000;  

  10. try {  

  11. if (DatabaseProject.DB_CONFIG.containsKey("mongodb.ips")) {  

  12. returnnew Mongo(getServerAddrsFromConf("mongodb"),mo);  

  13.            }  

  14. returnnew Mongo(new ServerAddress(DatabaseProject.DB_CONFIG.getString("mongodb.ip"), DatabaseProject.DB_CONFIG.getInt("mongodb.port")),mo);  

  15.        } catch (Throwable e) {  

  16.            DatabaseProject.LOGGER.error("Failed to init mongodb", e);  

  17. thrownew ExceptionInInitializerError(e);  

  18.        }  

  19.    }  

 其中有一些数据库配置直接写在配置文件里了,在MongoJavaDriverDAO中初始化一部分数据:

Java代码  
  1. publicvoid insertCollData(){  

  2. //如果该collection不存在则会自动创建

  3.        DBCollection parentcoll = getCollection("ParentColl");  

  4.        DBCollection childcoll = getCollection("ChildColl");  

  5. for(int i=0;i<1000;i++){  

  6.            DBObject document = new BasicDBObject();  

  7.            document.put("intData", 1000+i);  

  8.            document.put("longData", System.currentTimeMillis());  

  9.            document.put("strData", UUID.randomUUID().toString());  

  10.            document.put("doubleData", 1.123+i);  

  11.            document.put("createDate", new Date());  

  12.            document.put("booleanData", true);  

  13.            DBObject innerDoc = new BasicDBObject();  

  14.            innerDoc.put("innertype", "string");  

  15.            innerDoc.put("innerContent", "string"+i);  

  16.            document.put("documentData", innerDoc);  

  17.            parentcoll.insert(document);  

  18.            DBObject childDocument = new BasicDBObject();  

  19.            childDocument.put("parentId", document.get("_id"));  

  20.            childDocument.put("createDate", new Date());  

  21.            List list = new ArrayList();  

  22.            list.add("str" + i%10);  

  23.            list.add("str" + i%20);  

  24.            list.add(new BasicDBObject("arr"+(i%10),(i%10)));  

  25.            list.add(new BasicDBObject("arr"+(i%20),(i%20)));  

  26.            childDocument.put("arrays",list);  

  27.            childcoll.insert(childDocument);  

  28.        }  

  29.        System.out.println("ParentColl Count:"+parentcoll.count());  

  30.        System.out.println("ChildColl Count:"+childcoll.count());  

  31.    }  

其中getCollection方法会获取集合,不存在的话会自动创建一个。getCollection方法如下:

Java代码  
  1. publicstatic DBCollection getCollection(String collectionName){  

  2. return getDB().getCollection(collectionName);  

  3. }  

现在创建了2个集合ParentColl、ChildColl,并初始化了数据。

查询相关方法:

Java代码  
  1. /**

  2.     * 查询全部数据

  3.     */

  4. publicvoid findColl(){  

  5.        coll = getCollection("ParentColl");  

  6.        DBCursor cur = coll.find();  

  7. while(cur.hasNext()){  

  8.            System.out.println(cur.next());  

  9.        }  

  10.        System.out.println("Count:"+coll.count());  

  11.    }  

  12. /**

  13.     * 根据ObjectId查询

  14.     */

  15. publicvoid findById(String id){  

  16.        coll = getCollection("ParentColl");  

  17.        DBCursor cur = coll.find(new BasicDBObject("_id", new ObjectId(id)));//直接用string查不出来

  18. while(cur.hasNext()){  

  19.            System.out.println(cur.next());  

  20.        }  

  21.    }  

  22. /**

  23.     * And多条件查询

  24.     */

  25. publicvoid findByAndQuery(int intData,long longData){  

  26.        coll = getCollection("ParentColl");  

  27.        BasicDBObject query = new BasicDBObject();  

  28.        query.put("intData", intData);  

  29.        query.put("longData", longData);  

  30.        System.out.println(coll.findOne(query));  

  31.    }  

  32. /**

  33.     * OR多条件查询

  34.     */

  35. publicvoid findByORQuery(int lte,int gt,long longData){  

  36.        coll = getCollection("ParentColl");  

  37.        BasicDBObject query=new BasicDBObject();  

  38.        BasicDBObject longdata = new BasicDBObject("longData", longData);  

  39.        BasicDBObject intdata = new BasicDBObject("intData", new BasicDBObject().append("$gt", gt).append("$lte",lte));  

  40.        BasicDBList cond=new BasicDBList();  

  41.        cond.add(longdata);  

  42.        cond.add(intdata);  

  43.        query.put("$or", cond);  

  44.        DBCursor cur = coll.find(query);  

  45. while(cur.hasNext()){  

  46.            System.out.println(cur.next());  

  47.        }  

  48.    }  

  49. /**

  50.     * IN查询

  51.     */

  52. publicvoid findByINQuery(int value1,int value2){  

  53.        coll = getCollection("ParentColl");  

  54.        BasicDBObject query=new BasicDBObject();  

  55.        BasicDBList cond=new BasicDBList();  

  56.        cond.add(value1);  

  57.        cond.add(value2);  

  58.        query.put("intData",new BasicDBObject("$in", cond));  

  59.        DBCursor cur = coll.find(query);  

  60. while(cur.hasNext()){  

  61.            System.out.println(cur.next());  

  62.        }  

  63.    }  

  64. /**

  65.     * NOT查询

  66.     */

  67. publicvoid findByNotQuery(int value1,int value2){  

  68.        coll = getCollection("ParentColl");  

  69.        BasicDBObject query=new BasicDBObject();  

  70.        BasicDBList cond=new BasicDBList();  

  71.        cond.add(value1);  

  72.        cond.add(value2);  

  73.        query.put("intData",new BasicDBObject("$nin", cond));  

  74.        System.out.println("Count:"+coll.find(query).count());  

  75.    }  

  76. /**

  77.     * 获取结果集第一条

  78.     */

  79. publicvoid fetchFirstQuery(int value1,int value2){  

  80.        coll = getCollection("ParentColl");  

  81.        BasicDBList cond = new BasicDBList();  

  82.        cond.add(value1);  

  83.        cond.add(value2);  

  84.        BasicDBObject query = new BasicDBObject().append("intData",new BasicDBObject("$nin",cond));  

  85.        System.out.println(coll.findOne(query));  

  86.    }  

  87. /**

  88.     * 查询文档部分列

  89.     */

  90. publicvoid querySomeKey(){  

  91.        coll = getCollection("ParentColl");  

  92.        DBCursor cur = coll.find(new BasicDBObject(),new BasicDBObject("intData",true));  

  93. while(cur.hasNext()){  

  94.            System.out.println(cur.next());  

  95.        }  

  96.    }  

  97. /**

  98.     * 查询内嵌文档

  99.     */

  100. publicvoid queryInnerDocument(){  

  101.        coll = getCollection("ParentColl");  

  102.        BasicDBObject map = new BasicDBObject();  

  103.        map.put("innertype","string");  

  104.        map.put("innerContent","string0");  

  105.        DBCursor cur = coll.find(new BasicDBObject("documentData",map));  

  106. while(cur.hasNext()){  

  107.            System.out.println(cur.next());  

  108.        }  

  109.    }  

  110. /**

  111.     * 查询内嵌部分文档

  112.     */

  113. publicvoid querySubInnerDocument(){  

  114.        coll = getCollection("ParentColl");      

  115.        DBCursor cur = coll.find(new BasicDBObject("documentData.innerContent","string0"));  

  116. while(cur.hasNext()){  

  117.            System.out.println(cur.next());  

  118.        }  

  119.    }  

  120. /**

  121.     * 查询分页文档

  122.     */

  123. publicvoid queryByPage(int skipNum,int pageNum){  

  124.        coll = getCollection("ParentColl");  

  125.        DBCursor cur = coll.find().skip(skipNum).limit(pageNum);  

  126. while(cur.hasNext()){  

  127.            System.out.println(cur.next());  

  128.        }  

  129.    }  

  130. /**

  131.     * 查询文档某列是否存在

  132.     */

  133. publicvoid queryExists(){  

  134.        coll = getCollection("ParentColl");  

  135.        DBCursor cur = coll.find(new BasicDBObject("longData",new BasicDBObject("$exists",true)));  

  136. while(cur.hasNext()){  

  137.            System.out.println(cur.next());  

  138.        }  

  139.    }  

  140. /**

  141.     * 查询文档排序

  142.     */

  143. publicvoid sortDocument(){  

  144.        coll = getCollection("ParentColl");  

  145.        DBCursor cur = coll.find().sort(new BasicDBObject("intData",-1));//1:asc / -1:desc

  146. while(cur.hasNext()){  

  147.            System.out.println(cur.next());  

  148.        }  

  149.    }  

补充distinct查询:

Java代码  
  1. /**

  2. * 获取根据某元素做distinct查询.

  3. */

  4. publicvoid distinctKey(){  

  5. coll = getCollection("ParentColl");  

  6. List<String> list = coll.distinct("documentData.innertype");  

  7. for(String str:list){  

  8.    System.out.println(str);  

  9. }  

  10.  }  

不难发现主要用到BasicDBObject、BasicDBList、DBCursor这三个类。BasicDBObject好比一个map,好比使用json查询中的{} 。BasicDBList是个list,用于or,nin等条件查询。DBCursor用于遍历结果集。其实只要将对应的json查询使用这3个类转化一下,就能写出对应的java代码了。

更新相关:

Java代码  
  1. /**

  2.     * 更新文档1

  3.     */

  4. publicvoid updateDocument(){  

  5.        DB db = getDB();  

  6. //由于mongodb中使用连接池的原因,getLastError()需要再次从连接池中获取连接.

  7. //保证update操作和getLastError()使用同一个连接.

  8.        db.requestStart();  

  9.        coll = db.getCollection("ParentColl");  

  10.        WriteResult result = coll.update(new BasicDBObject("intData",1100),new BasicDBObject("$set", new BasicDBObject("booleanData",false)));  

  11.        System.out.println("update count:"+result.getN());  

  12. if(result.getLastError().ok()){

    //获取上次操作结果是否有错误.

  13.            System.out.println("update document success.");  

  14.        }else{  

  15.            System.out.println(result.getLastError().getErrorMessage());  

  16.        }  

  17.        db.requestDone();  

  18.    }  

  19. /**

  20.     * 更新文档2

  21.     */

  22. publicvoid updateMultiDocument(){  

  23.        DB db = getDB();  

  24.        db.requestStart();  

  25.        coll = db.getCollection("ParentColl");  

  26. //第三个参数:如果没有该文档是否创建,第四个参数:是否更新全部匹配条件的文档.

  27.        WriteResult result = coll.update(new BasicDBObject("booleanData",false),new BasicDBObject("$set", new BasicDBObject("booleanData",true)),false,true);  

  28.        System.out.println("update count:"+result.getN());  

  29. if(result.getLastError().ok()){

    //获取上次操作结果是否有错误.

  30.            System.out.println("update document success.");  

  31.        }else{  

  32.            System.out.println(result.getLastError().getErrorMessage());  

  33.        }  

  34.        db.requestDone();  

  35.    }  

注意requestStart、requestDone方法保证使用同一个数据库连接。WriteResult记录更新结果。

索引相关:

Java代码  
  1. /**

  2.     * 创建唯一索引

  3.     */

  4. publicvoid createIndexes(){  

  5.        coll = getCollection("ParentColl");  

  6.        BasicDBObject index = new BasicDBObject();  

  7.        index.put("intData",1);//1:asc / -1:desc

  8.        index.put("unique",true);//唯一索引

  9.        coll.createIndex(index);  

  10.    }  

  11. /**

  12.     * 查询索引信息

  13.     */

  14. publicvoid getIndexes(){  

  15.        coll = getCollection("ParentColl");  

  16.        List<DBObject> indexInfo = coll.getIndexInfo();  

  17.        System.out.println(indexInfo);  

  18.    }  

  19. /**

  20.     * 删除索引信息

  21.     */

  22. publicvoid dropIndexes(){  

  23.        coll = getCollection("ParentColl");  

  24. //删除的索引必须跟创建的索引名称\排序\是否唯一都相同才能删除

  25.        BasicDBObject index = new BasicDBObject();  

  26.        index.put("intData",1);  

  27.        index.put("unique",true);  

  28.        coll.dropIndex(index);  

  29.    }  

对于文档可能还会对数组操作:

Java代码  
  1. /**

  2.     * 取出文档中的数组

  3.     */

  4. publicvoid queryArray(){  

  5.        coll = getCollection("ChildColl");  

  6.        DBCursor cur = coll.find(new BasicDBObject(),new BasicDBObject("arrays",1));  

  7. while(cur.hasNext()){  

  8.            BasicDBObject bo = (BasicDBObject)cur.next();  

  9.            List<BasicDBObject> list = (List<BasicDBObject>)bo.get("arrays");  

  10.            System.out.println(list.toString());  

  11.        }  

  12.    }  

  13. /**

  14.     * 查询数组内是否包含某元素

  15.     */

  16. publicvoid queryElementInArray(){  

  17.        coll = getCollection("ChildColl");  

  18.        BasicDBObject query = new BasicDBObject();  

  19.        BasicDBObject obj = new BasicDBObject();  

  20.        obj.put("arr0",0);  

  21.        query.put("arrays", new BasicDBObject("$elemMatch",obj));  

  22.        DBCursor cur = coll.find(query);  

  23. while(cur.hasNext()){  

  24.            System.out.println(cur.next());  

  25.        }  

  26.    }  

  27. /**

  28.     * 数组内包含元素的值

  29.     */

  30. publicvoid queryElementArray(){  

  31.        coll = getCollection("ChildColl");  

  32.        BasicDBObject obj = new BasicDBObject();  

  33.        obj.put("arrays", "str0");  

  34.        obj.put("arrays.arr0",0);  

  35.        obj.put("arrays.arr10",10);  

  36.        DBCursor cur = coll.find(obj);  

  37. while(cur.hasNext()){  

  38.            System.out.println(cur.next());  

  39.        }  

  40.    }  

  41. /**

  42.     * push(pushAll) array element

  43.     */

  44. publicvoid pushElementInArray(String _id){  

  45.        DB db = getDB();  

  46.        db.requestStart();  

  47.        coll = getCollection("ChildColl");  

  48. //WriteResult result = coll.update(new BasicDBObject("_id", new ObjectId(_id)),new BasicDBObject("$push",new BasicDBObject("arrays",new BasicDBObject("arr99","99"))));

  49.        List<BasicDBObject> list=new ArrayList<BasicDBObject>();  

  50.        list.add(new BasicDBObject("arr99",99));  

  51.        list.add(new BasicDBObject("arr100",100));  

  52.        WriteResult result = coll.update(new BasicDBObject("_id", new ObjectId(_id)),new BasicDBObject("$pushAll",new BasicDBObject("arrays",list)));  

  53.        System.out.println("update count:"+result.getN());  

  54. if(result.getLastError().ok()){  

  55.            System.out.println("update document success.");  

  56.        }else{  

  57.            System.out.println(result.getLastError().getErrorMessage());  

  58.        }  

  59.        db.requestDone();  

  60.    }  

  61. /**

  62.     * pull(pullAll) array element

  63.     */

  64. publicvoid pullElementInArray(String _id){  

  65.        DB db = getDB();  

  66.        db.requestStart();  

  67.        coll = getCollection("ChildColl");  

  68.        List<BasicDBObject> list=new ArrayList<BasicDBObject>();  

  69.        list.add(new BasicDBObject("arr99",99));  

  70.        list.add(new BasicDBObject("arr100",100));  

  71. //WriteResult result = coll.update(new BasicDBObject("_id", new ObjectId(_id)),new BasicDBObject("$pull",new BasicDBObject("arrays",new BasicDBObject("arr100",100))));

  72.        WriteResult result = coll.update(new BasicDBObject("_id", new ObjectId(_id)),new BasicDBObject("$pullAll",new BasicDBObject("arrays",list)));  

  73.        System.out.println("update count:"+result.getN());  

  74.        db.requestDone();  

  75.    }  

  76. /**

  77.     * pop array element(1,last;-1,first)

  78.     */

  79. publicvoid popElementInArray(String _id){  

  80.        coll = getCollection("ChildColl");  

  81.        WriteResult result = coll.update(new BasicDBObject("_id", new ObjectId(_id)),new BasicDBObject("$pop",new BasicDBObject("arrays",-1)));//1,last;-1,first

  82.        System.out.println("update count:"+result.getN());  

  83.    }  

  84. /**

  85.     * addToSet And Each array element

  86.     */

  87. publicvoid addToSetAndEachElementInArray(String _id){  

  88.        coll = getCollection("ChildColl");  

  89.        List list = new ArrayList();  

  90.        list.add("str0");  

  91.        list.add("str1");  

  92.        list.add(new BasicDBObject("arr99",99));  

  93.        WriteResult result = coll.update(new BasicDBObject("_id", new ObjectId(_id)),new BasicDBObject("$addToSet",new BasicDBObject("arrays",new BasicDBObject("$each",list))));//1,last;-1,first

  94.        System.out.println("update count:"+result.getN());  

  95.    }  

  96. /**

  97.     * 按数组位置更新文档(查询条件需要包含更新内容,$为数组位置占位符,只更新匹配到的第一个文档.)

  98.     */

  99. publicvoid updatePositionInArray(String _id){  

  100.        coll = getCollection("ChildColl");  

  101.        WriteResult result = coll.update(new BasicDBObject("arrays.arr0", 100),new BasicDBObject("$set",new BasicDBObject("arrays.$.arr0",101)));  

  102.        System.out.println("update count:"+result.getN());  

  103.    }  

 以上都是一些基本的查询、更新操作,当然还有一些如map reduce和关联查询等复杂的方法,我将另写一篇blog总结一下。

参考文献包括:《mongodb权威指南》、《mongodb管理与开发精要》,另外文章开头提到的MongoDB官网内的develop zone也是很不错的资料来源。

PS:

mongodb driver在线API文档: http://api.mongodb.org/java/2.8.0/ (目前是2.8.0)