How to use $query, $hint or $explain from Java

冷暖自知 提交于 2021-01-28 05:52:03

问题


I am using MongoDB 3.4 My methods are:-

MongoDatabase db = mongo.getDatabase(mongoDBLogs);
MongoIterable<String> allCollections = db.listCollectionNames();
str==FROM COLLECTION
MongoCollection<Document> table = db.getCollection(str);
MongoCursor<Document> cursor = table.find(queryForLogs).iterator();

The problem is in OLD version I can use the

DB db = mongo.getDB(mongoDBLogs);
Set<String> colls = db.getCollectionNames();
for (String s : colls) {
DBCollection table = db.getCollection(s);
cursor = table.find().explain(); <<<<---- I have this explain method
AND ALSO I have
cursor = table.find().hint(indexKeys);<<<<---- I have this hint method
}

NOW in 3.4 I am not able to access these options by using

MongoCursor<Document> cursor = table.find(queryForLogs).explain() <-- this is type  FindIterable<Document>

OR

MongoCursor<Document> cursor = table.find(queryForLogs).hint(Some value); <---This is type  FindIterable<Document>

I refer the link:- https://docs.mongodb.com/manual/reference/operator/meta/hint/ https://docs.mongodb.com/manual/reference/method/cursor.explain/

So I make another method:-

    public  BasicDBObject generateQueryForSessionIDLogs(String service_name, String node_name, Date gtDate, Date lteDate, String session_id,List<String> logLevel, String errorMsg){
        BasicDBObject andQuery = new BasicDBObject();
        List<BasicDBObject> obj = new ArrayList<BasicDBObject>();

        //Use session to search. If session is unknown, start and end date must be provided
        if(!session_id.isEmpty() && session_id != null){
            String[] sessionarray = session_id.split(",");

            if(sessionarray.length == 1){
                Long val = Long.valueOf(sessionarray[0].trim()).longValue();
                obj.add(new BasicDBObject("s", val));

            } else{ 
                ArrayList<Long> vals =  new ArrayList<Long>();
                for(String strn : sessionarray){
                    vals.add(Long.valueOf(strn.trim()).longValue());
                }

                obj.add(new BasicDBObject("s", new BasicDBObject("$in", vals )));
            }
        }else{      
            if((gtDate != null) && (lteDate != null)){
                obj.add(new BasicDBObject("d",  new BasicDBObject("$gt", gtDate).append("$lte", lteDate)));
            }
        }

        if(!node_name.isEmpty()){
            obj.add(new BasicDBObject("i", node_name));
        }
        if(!service_name.isEmpty()){
            obj.add(new BasicDBObject("n", service_name ));
        }
        if(!errorMsg.isEmpty()) {
            obj.add(new BasicDBObject("m", Pattern.compile(errorMsg)));
        }

        if(!logLevel.isEmpty()){
//          obj.add(new BasicDBObject("r", new BasicDBObject("$in", logLevel )));
            obj.add(new BasicDBObject("r", logLevel.get(0) ));
        }

        if (obj.size() > 1){ //append 'AND' if there is >1 conditions
            andQuery.put("$and", obj);
        }

        BasicDBObject andQuery2 = new BasicDBObject();
        andQuery2.put("$query", andQuery);
        List<BasicDBObject> obj2 = new ArrayList<BasicDBObject>();
        obj2.add(new BasicDBObject("i",1));
        andQuery2.put("$hint", obj2);
        andQuery2.put("$explain", 1);
        logger.debug("Query String for Logs: " + andQuery2);
        return andQuery;
    }

My final query make like:-

Query String for Logs: { "$query" : { "$and" : [ { "d" : { "$gt" : { "$date" : "2017-06-19T04:00:00.000Z"} , "$lte" : { "$date" : "2017-06-20T04:00:00.000Z"}}} , { "i" : "WM96BEPSIT02"}]} , "$hint" : [ { "i" : 1}] , "$explain" : 1}

With error:- Exception in thread "pool-2-thread-16" Exception in thread "pool-2-thread-15" com.mongodb.MongoQueryException: Query failed with error code 2 and error message 'unknown top level operator: $query' on server

Please also suggest any alternative way to call the indexed values first. As in my case all search values are not indexed.


回答1:


To send things like $hint or $explain to the Java driver you actually use the .modifiers() method from FindIterable. For instance:

MongoCursor<Document> iterator = collection.find()
    .modifiers(new Document("$explain",1)).iterator();

while (iterator.hasNext()) {
  System.out.println(iterator.next().toJson());
}

This will print the explain stats output.

Any BsonDocument type is valid to provide as an argument. The valid list is on Query Modifiers in the core documentation.

Generally speaking, $query is not something that you actually use from the modifiers list, since you are actually constructing that with any argument to .find(). But all the other modifiers are valid for use here.



来源:https://stackoverflow.com/questions/44667364/how-to-use-query-hint-or-explain-from-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!