I am using MongoDB 3.4
My methods are:-
MongoDatabase db = mongo.getDatabase(mongoDBLogs);
MongoIterable allCollections = db.listCollectionNames();
str==FROM COLLECTION
MongoCollection table = db.getCollection(str);
MongoCursor cursor = table.find(queryForLogs).iterator();
The problem is in OLD version I can use the
DB db = mongo.getDB(mongoDBLogs);
Set colls = db.getCollectionNames();
for (String s : colls) {
DBCollection table = db.getCollection(s);
cursor = table.find().explain(); <<<
AND ALSO I have
cursor = table.find().hint(indexKeys);<<<
}
NOW in 3.4 I am not able to access these options by using
MongoCursor cursor = table.find(queryForLogs).explain()
OR
MongoCursor cursor = table.find(queryForLogs).hint(Some value);
So I make another method:-
public BasicDBObject generateQueryForSessionIDLogs(String service_name, String node_name, Date gtDate, Date lteDate, String session_id,List logLevel, String errorMsg){
BasicDBObject andQuery = new BasicDBObject();
List obj = new ArrayList();
//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 vals = new ArrayList();
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 obj2 = new ArrayList();
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.
解决方案
To send things like $hint or $explain to the Java driver you actually use the .modifiers() method from FindIterable. For instance:
MongoCursor 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.