1. 程式人生 > >Java通過mongo-java-driver-3.0+查詢mongodb資料庫

Java通過mongo-java-driver-3.0+查詢mongodb資料庫

本文以mongo-java-driver-3.5.0.jar為例

1 基本查詢關鍵字(對應的sql語句):

MongoDB Aggregation Operators SQL Terms, Functions, and Concepts
$match WHERE/HAVING
$group GROUP BY
$project SELECT
$limit LIMIT
$sort (降序:-1 升序:1) ORDER BY (降序:DESC 升序:ASC預設)
$skip 跳過n個 持久化框架有介面
$sum SUM()/COUNT()
$in IN()
$nin NOT IN()
$or OR
$and AND
$regex 模糊查詢 LIKE
$gt >
$gte >=
$lt <
$lte <=
$ne !=
=


2 構造複雜查詢條件的3種方法:

2.1 測試資料

{ "_id" : { "$oid" : "59c8cbea6157d6c78dab4ff0" }, "name" : "yy", "password" : "123"
, "nickname" : "ygirl2", "iid" : 2 } { "_id" : { "$oid" : "59c9c1393471f5330c65ccd2" }, "name" : "nie", "password" : "nie", "nickname" : "nn", "iid" : 8 } { "_id" : { "$oid" : "59c9ec75a4e55c541a000003" }, "name" : "yy", "password" : "123", "nickname" : "ygirl2", "iid" : 8.0, "isRead" : false, "createTime" : { "$date
" : 1506405705952 }
, "money" : 88.88 } { "_id" : { "$oid" : "59b34277beca1aaeaf1d1fbe" }, "name" : "yan", "password" : "ygirlyan", "nickname" : "ygirl2", "iid" : 3.0 } { "_id" : { "$oid" : "59b34282beca1aaeaf1d1fbf" }, "name" : "yan", "password" : "ygirlyan", "nickname" : "ygirl2", "iid" : 4.0 }

2.3 實現構造複雜查詢條件的3種方法:

public static MongoCollection<Document> connect() {  
    @SuppressWarnings("resource")  
    MongoClient client = new MongoClient("127.0.0.1", 27017);  
    MongoDatabase db = client.getDatabase("test");  
    MongoCollection<Document> collection = db.getCollection("user");  
    return collection;
} 

public static List<Document> findBy(Bson filter) {  
    List<Document> results = new ArrayList<Document>();  
    FindIterable<Document> iterables = connect().find(filter);  
    MongoCursor<Document> cursor = iterables.iterator();  
    while (cursor.hasNext()) {  
        results.add(cursor.next());  
    }  

    return results;  
}  
public static List<Document> findBy1(DBObject filter) {  
    List<Document> results = new ArrayList<Document>();  
    FindIterable<Document> iterables = connect().find((Bson) filter);  
    MongoCursor<Document> cursor = iterables.iterator();  
    while (cursor.hasNext()) {  
        results.add(cursor.next());  
    }  

    return results;  
}  

// 方法1:運用Filters.and新增複合條件;
@Test  
public void testFindByLickQuery2(){  
    int iid = 2;
    String name = "yy";
    String nickname = "ygirl2";
    Bson filter = null;
    if (iid >= 0) {
        if (name != "") {
            if (nickname != "") {
                filter = Filters.and(Filters.gte("iid", iid), Filters.eq("nickname", nickname), Filters.regex("name", name));
            } else {
                filter = Filters.and(Filters.gte("iid", iid), Filters.regex("name", name));
            }
        } else {
            if (nickname != "") {
                filter = Filters.and(Filters.gte("iid", iid), Filters.eq("nickname", nickname));
            } else {
                filter = Filters.and(Filters.gte("iid", iid));
            }
        }
    } else {
        if (name != "") {
            if (nickname != "") {
                filter = Filters.and(Filters.eq("nickname", nickname), Filters.regex("name", name));
            } else {
                filter = Filters.and(Filters.regex("name", name));
            }
        } else {
            if (nickname != "") {
                filter = Filters.and(Filters.eq("nickname", nickname));
            } else {
                filter = Filters.and();
            }
        }
    }
    List<Document> results = findBy(filter);
    for(Document doc : results){  
        System.out.println(doc.toJson());  
    }  
    // { "_id" : { "$oid" : "59c8cbea6157d6c78dab4ff0" }, "name" : "yy", "password" : "123", "nickname" : "ygirl2", "iid" : 2 }
    // { "_id" : { "$oid" : "59c9ec75a4e55c541a000003" }, "name" : "yy", "password" : "123", "nickname" : "ygirl2", "iid" : 8.0, "isRead" : false, "createTime" : { "$date" : 1506405705952 }, "money" : 88.88 }
}  

// 方法2:運用Document filter.append新增複合條件;
@Test  
public void testFindByLickQuery1(){  
    int iid = 3, iid2 = 4;
    String name = "";
    String nickname = "";
    Document filter = new Document(); 
    if (iid >= 0) {
        filter.append("iid", new Document("$gte", iid));
    }
    // 得到iid<=4結果;
    // iid>=3條件被覆蓋,Document.append不適合在同一個結果新增多個條件
    if (iid2 >= 0) {
        filter.append("iid", new Document("$lte", iid2));

    }
    if (name != "") {
        filter.append("name",new Document("$regex", name));
    }
    if (nickname != "") {
        filter.append("nickname",nickname);  
    }

    List<Document> results = findBy(filter); 
    for(Document doc : results){  
        System.out.println(doc.toJson());  
    }  
    // { "_id" : { "$oid" : "59c8cbea6157d6c78dab4ff0" }, "name" : "yy", "password" : "123", "nickname" : "ygirl2", "iid" : 2 }
    // { "_id" : { "$oid" : "59b34277beca1aaeaf1d1fbe" }, "name" : "yan", "password" : "ygirlyan", "nickname" : "ygirl2", "iid" : 3.0 }
    // { "_id" : { "$oid" : "59b34282beca1aaeaf1d1fbf" }, "name" : "yan", "password" : "ygirlyan", "nickname" : "ygirl2", "iid" : 4.0 }
} 

// 方法3:運用DBObject.put新增複合條件;
@Test  
public void testFindByLickQuery1Copy(){  
    int iid = 3, iid2 = 4;
    String name = "";
    String nickname = "";
    DBObject filter = new BasicDBObject();  
    if (iid >= 0) {
        filter.put("iid", new BasicDBObject("$gte", iid));          
    }
    // 得到iid<=4結果;
    // iid>=3條件被覆蓋,Document.append不適合在同一個結果新增多個條件
    if (iid2 >= 0) {
        if (iid >= 0) {
            BasicDBObject[] queryObjectAnd =  new BasicDBObject[] { new BasicDBObject("iid", new BasicDBObject("$gte", iid)),  
                    new BasicDBObject("iid", new BasicDBObject("$lte", iid2)) };
            filter.put("$and", queryObjectAnd);
        } else {
        filter.put("iid",  new BasicDBObject("$lte", iid2)); 
        }

    }
    if (name != "") {
        filter.put("name",new BasicDBObject("$regex", name));
    }
    if (nickname != "") {
        filter.put("nickname",nickname);  
    }

    List<Document> results = findBy1(filter); 
    for(Document doc : results){  
        System.out.println(doc.toJson());  
    } 
    // { "_id" : { "$oid" : "59b34277beca1aaeaf1d1fbe" }, "name" : "yan", "password" : "ygirlyan", "nickname" : "ygirl2", "iid" : 3.0 }
    // { "_id" : { "$oid" : "59b34282beca1aaeaf1d1fbf" }, "name" : "yan", "password" : "ygirlyan", "nickname" : "ygirl2", "iid" : 4.0 }
} 

2.3 分析構造複雜查詢條件的3種方法異同:

方法 實現 難易程度 能否給同一個欄位加大於1個約束條件 適用於
方法1 Bson filter=Filters.and(Filters 1,…) 條件越多實現越困難,if-else越複雜 查詢條件少且固定永遠不變
方法2 Document f=append(key, v)
Document f=append(key, newBasicDBObject(“$gte”,v))
條件越多實現不會太困難 不能,後面的append條件會覆蓋前面的 查詢條件多且每個屬性查詢條件<=1
方法3 DBObject filter=put(“iid”,new BasicDBObject(“$gte”,v)); 條件越多實現不會太困難 適用於一切查詢,特別適用於複雜條件查詢應用


3 其他查詢關鍵字應用:

3.1 String型別按條件聚合

@Test
public void testGroup() {
     /* Group操作*/  
    //DBObject groupFields = new BasicDBObject("_id", new BasicDBObject("name", "$name").append("nickname", "$nickname"));  
    // 1 加入標誌項_id,即聚合欄位值;
    DBObject groupFields = new BasicDBObject("_id", "$name");  
    // 2 加入統計數count,即聚合個數;
    groupFields.put("count", new BasicDBObject("$sum", 1));  
    DBObject group = new BasicDBObject("$group", groupFields); 

    // 排序操作  ,按count降序
    DBObject sortchBasicDBObjet = new BasicDBObject("$sort", new BasicDBObject("count",-1));  

    // 分頁操作.skip(startRow),首先取2個記錄,再跳過1個記錄取出第二個記錄顯示出來;
    DBObject limitBasicDBObjet = new BasicDBObject("$limit",2); 
    DBObject limitBasicDBObjet2 = new BasicDBObject("$skip",2);

    // project 操作  : 過濾查詢顯示欄位個數,db.books.aggregate( [ { $project : { _id: 0, name : 1 , password : 1 }]);只顯示name和password
    // DBObject projectBasicDBObjet = new BasicDBObject("$project", new BasicDBObject("_id",0).append("times", "$_id.times").append("user_id", "$_id.user_id").append("user_account", "$_id.user_account").append("count", 1));
    List<Bson> list = new ArrayList<Bson>();  
    list.add((Bson) group); 
    list.add((Bson) sortchBasicDBObjet);  
    // $limit和$skip   add到list順序不一樣,結果不一樣
    list.add((Bson) limitBasicDBObjet2);
    list.add((Bson) limitBasicDBObjet);  
    // list.add((Bson) limitBasicDBObjet2);
    List<Document> results = MongoDb.group(list);; 
    for(Document doc : results){  
        System.out.println(doc.toJson());  
    }  
}


/*
 * 
 * isRead  "0"表示未讀,"1"表示已讀
 */
public List<Object> findIfreadAlarmLog(String isRead, String CommunityName, String EQAddress) {
    MongoCollection<Document> collection = getMongodbCollection();
    // 新增統計統計
    //DBObject matchBasicDBObjet = new BasicDBObject("$match",new BasicDBObject("IsRead", "0"));
    DBObject queryCondition = new BasicDBObject();  
    queryCondition.put("IsRead", isRead);
    if (CommunityName != null && !"".equals(CommunityName)) {
        // 模糊匹配
        queryCondition.put("CommunityName", new BasicDBObject("$regex", CommunityName));
    }
    if (EQAddress != null && !"".equals(EQAddress)) {
        // 模糊匹配
        queryCondition.put("EQAddress", new BasicDBObject("$regex", EQAddress));
    }
    DBObject matchBasicDBObjet = new BasicDBObject("$match", queryCondition);

    // 新增統計條件
    DBObject groupFields = new BasicDBObject("_id", new BasicDBObject("CommunityID", "$CommunityID").append("CommunityName", "$CommunityName").append("EQName", "$EQName")
            .append("EQAccount", "$EQAccount").append("EQAddress", "$EQAddress").append("Coordinate", "$Coordinate").append("SingleCoordinate", "$SingleCoordinate"));  
    // 加入統計數count,即聚合個數;
       groupFields.put("count", new BasicDBObject("$sum", 1));  
       DBObject group = new BasicDBObject("$group", groupFields); 

       // 新增顯示條件
       DBObject projectBasicDBObjet = new BasicDBObject("$project", new BasicDBObject("_id",0).append("CommunityID", "$_id.CommunityID").append("CommunityName", "$_id.CommunityName").append("EQName", "$_id.EQName")
            .append("EQAccount", "$_id.EQAccount").append("EQAddress", "$_id.EQAddress").append("Coordinate", "$_id.Coordinate").append("SingleCoordinate", "$_id.SingleCoordinate").append("count", 1));
       List<Bson> list = new ArrayList<Bson>(); 
       list.add((Bson) matchBasicDBObjet); 
       list.add((Bson) group); 
       list.add((Bson) projectBasicDBObjet); 
       AggregateIterable<Document> iterables = collection.aggregate(list);       
       List<Object> results = new ArrayList<Object>();  
       MongoCursor<Document> cursor = iterables.iterator();  
       while (cursor.hasNext()) {  
           results.add(cursor.next());  
       }  
       return results;  
}

3.2 json格式的查詢

/*
 * 先轉換為Object再查詢
 */
public List<String> getHouseHouseAccounts(List<Object> singleCoords , String isRead) {
    MongoCollection<Document> collection = getMongodbCollection();
    DBObject queryCondition = new BasicDBObject();  
    List<String> resultArray = new ArrayList<String>();
    // 報錯:org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class cn.com.vo.Point.,Point包含lng,lat屬性
    // queryCondition.put("SingleCoordinate", JsonUtils.jsonToPojo(singleCoord, Point.class));

    // 返回空
    //queryCondition.put("SingleCoordinate", singleCoord);

    // 成功返回,(DBObject) JSON.parse(singleCoord)=JSON.parse(singleCoord)={ "lng" : 102.731653 , "lat" : 25.052474},88:H20170926000002     88:H20170926000003,H20170926000004
    //queryCondition.put("SingleCoordinate", JSON.parse(singleCoord));

    // 成功返回,JsonUtils.jsonToPojo(singleCoord, Object.class)={lng=102.731653, lat=25.052474},88:H20170926000002     88:H20170926000003,H20170926000004
    for (Object object : singleCoords) {
        //queryCondition.put("SingleCoordinate", JsonUtils.jsonToPojo(singleCoord, Object.class));
        queryCondition.put("SingleCoordinate", object);
        queryCondition.put("IsRead", isRead);
        List<Object> list = new ArrayList<Object>();
        FindIterable<Document> findIterable =collection.find((Bson) queryCondition);
        MongoCursor<Document> mongoCursor = findIterable.iterator();
        while(mongoCursor.hasNext()){  
           Document document=mongoCursor.next();
           list.add(document);         
        }  
        List<AlarmLog> alarmLogLists = JsonUtils.jsonToList(JsonUtils.objectToJson(list), AlarmLog.class);
        for (AlarmLog alarmLog : alarmLogLists) {
            resultArray.add("'" + alarmLog.getHouseAccount() + "'");
        }
    }

    //return StringUtils.collectionToDelimitedString(resultArray, ",");
    return resultArray;
}

3.3 $or和$and關鍵字查詢

/**
 * Document  OR  AND 查詢:db.user.find({"likes": {$gt:50}, $or: [{"by": "菜鳥教程"},{"title": "MongoDB 教程"}]}).pretty();
 * 適合少條件且條件不變的查詢,適合單欄位多條件查詢
 */
@Test  
public void testFindByOrAnd(){   
    // (查詢iid等於2或者iid等於8的資料)  失敗   只能查到8
    Document filter = new Document(); 
    filter.append("iid", 2);
    filter.append("iid", 8);
    List<Document> results = MongoDb.findBy(filter);

    // $or (查詢iid等於2或者iid等於8的資料)  
    BasicDBObject queryObjectOr = new BasicDBObject().append(  
            "$or",  
            new BasicDBObject[] { new BasicDBObject("iid", 2),  
                    new BasicDBObject("iid", 8) }); 

    // (查詢iid等於2並且name等於nie的資料)   成功查出相應資料
    Document filter2 = new Document(); 
    filter2.append("iid", 2);
    filter2.append("name", "yy");
    List<Document> results2 = MongoDb.findBy(filter2);

    // $and(查詢iid等於2並且name等於nie的資料)  
    BasicDBObject queryObjectAnd = new BasicDBObject().append("$and",  
            new BasicDBObject[] { new BasicDBObject("iid", 2),  
                    new BasicDBObject("name", "yy") });  
    List<Document> results3 = MongoDb.findBy(queryObjectOr); 
    List<Document> results4 = MongoDb.findBy(queryObjectAnd);
    for(Document doc : results){  
        System.out.println(doc.toJson());  
    }  
    System.out.println("==========");  
    for(Document doc : results3){  
        System.out.println(doc.toJson());  
    }  
    System.out.println("==========");  
    for(Document doc : results4){  
        System.out.println(doc.toJson());  
    } 
    System.out.println("==========");  
    for(Document doc : results2){  
        System.out.println(doc.toJson());  
    } 
    // { "_id" : { "$oid" : "59c9c1393471f5330c65ccd2" }, "name" : "nie", "password" : "nie", "nickname" : "nn", "iid" : 8 }
    // { "_id" : { "$oid" : "59c9ec75a4e55c541a000003" }, "name" : "yy", "password" : "123", "nickname" : "ygirl2", "iid" : 8.0, "isRead" : false, "createTime" : { "$date" : 1506405705952 }, "money" : 88.88 }
    // ==========
    // { "_id" : { "$oid" : "59c8cbea6157d6c78dab4ff0" }, "name" : "yy", "password" : "123", "nickname" : "ygirl2", "iid" : 2 }
    // { "_id" : { "$oid" : "59c9c1393471f5330c65ccd2" }, "name" : "nie", "password" : "nie", "nickname" : "nn", "iid" : 8 }
    // { "_id" : { "$oid" : "59c9ec75a4e55c541a000003" }, "name" : "yy", "password" : "123", "nickname" : "ygirl2", "iid" : 8.0, "isRead" : false, "createTime" : { "$date" : 1506405705952 }, "money" : 88.88 }
    // ==========
    // { "_id" : { "$oid" : "59c8cbea6157d6c78dab4ff0" }, "name" : "yy", "password" : "123", "nickname" : "ygirl2", "iid" : 2 }
    // ==========
    // { "_id" : { "$oid" : "59c8cbea6157d6c78dab4ff0" }, "name" : "yy", "password" : "123", "nickname" : "ygirl2", "iid" : 2 }

}

3.4$in和$nin關鍵字查詢

/**
 * Document  in  nin 查詢
 */
@Test  
public void testFindByInNin(){   

    // $in  (查詢iid為12的資料)
    BasicDBObject queryObjectIn = new BasicDBObject().append("iid", new BasicDBObject(  
            "$in", new int[] { 2, 8 })); 
    // $nin  (查詢iid不為1,2,3,4,5,6,7,8,9的資料)
    BasicDBObject queryObjectNin = new BasicDBObject().append("iid", new BasicDBObject(
            "$nin", new int[] { 2, 9 })); 
    List<Document> results3 = MongoDb.findBy(queryObjectIn); 
    List<Document> results4 = MongoDb.findBy(queryObjectNin);
    for(Document doc : results3){  
        System.out.println(doc.toJson());  
    }  
    // { "_id" : { "$oid" : "59c8cbea6157d6c78dab4ff0" }, "name" : "yy", "password" : "123", "nickname" : "ygirl2", "iid" : 2 }
    // { "_id" : { "$oid" : "59c9c1393471f5330c65ccd2" }, "name" : "nie", "password" : "nie", "nickname" : "nn", "iid" : 8 }
    // { "_id" : { "$oid" : "59c9ec75a4e55c541a000003" }, "name" : "yy", "password" : "123", "nickname" : "ygirl2", "iid" : 8.0, "isRead" : false, "createTime" : { "$date" : 1506405705952 }, "money" : 88.88 }
}