When does MongoDB Fetch results in java driver - mongodb

MongoClient mc=new MongoClient();
MongoDatabase mdb=mc.getDatabase("testdb");
MongoCollection mcol=mdb.getCollection("testcol");
FindIterable<Document> fi=mcol.find();
MongoCursor<Document> mcur=fi.iterator();
MongoCursor<Document> mcur2=fi.iterator();
will mcur and mcur2 have same results all the time as they are reference of FindIterable fi.
In which step of the above code mongodb will get the results Inside mongoCursor or FindIterable step?

mcol.find() is the point where the results are obtained, the .find() will pull all documents from the collection "testcol".
You don't necessarily need to use a FindIterable object an ordinary List<BasicDBObject> does work.
then you can iterate through using:
for(DBObject obj : objList) {
//perform operations
String name = (String) obj.get("nameOfField");
}
hope this helps.

Related

mongo group with match query does not work with java

I have below query working in robo 3T console.
db.metrics.aggregate([
{'$match':{'status':'SUCCESS'}},
{'$group':{ _id:'$bapiName',count:{$sum:1}}}
])
But when I execute it with java,
MongoCollection collection =db.getCollection();
List<Bson> pipeLine = new ArrayList<Bson>();
pipeLine.add(Document.parse("{'$match':{'status':'SUCCESS'}}"));
pipeLine.add(Document.parse("{'$group' : {_id: {bapiName:'$bapiName',status:'$status'}, count:{$sum:1}}}"));
Iterator iterator = collection.aggregate(query.getPipeline()).iterator();
while( iterator.hasNext()) {
Object object = iterator.next();
resultList.add((Document)object);
System.out.println(" class "+object.getClass()+" data "+object);
}
I am not getting the results. Iterator is empty. Any changes need to be made in java to get it working?

Mongo DB : Implementing $not query

I am trying to implement following query from java code:
{ "Post Text" : { "$not" : /.*golf.*/i}}
my java code:
BasicDBObject not = new BasicDBObject();
not.append("$not", "/.*golf.*/i");
BasicDBObject query = new BasicDBObject();
query.put("Post Text", not);
When I am running above query, getting this log:
Cursor id=0, ns=journaldev.Rotunda, query={ "Post Text" : { "$not" : "/.golf./i" }}, numIterated=0, readPreference=primary
extra quotes around the regular expression are creating problem. Can someone help me in fixing this?
Using 3.x, you can use the Filters utility class to create various queries for you. In your case, you need the following construct:
Bson myFilter = Filters.not(
Filters.eq("Post Text",
Pattern.compile(".*golf.*", Pattern.CASE_INSENSITIVE)));
Using the 3.x driver to execute such a query is along the lines of:
MongoClient mongoClient = new MongoClient();
MongoCollection<Document> coll = mongoClient.getDatabase("test").getCollection("mycoll");
coll.find(myFilter); // do something with the FindIterable returned here
You can try something like this
Pattern textRegex = Pattern.compile(".*golf.*", Pattern.CASE_INSENSITIVE);
BasicDBObject not = new BasicDBObject("$not", textRegex);
BasicDBObject query = new BasicDBObject("Post Text", not);
When you pass a pattern, mongo driver automatically takes care of making it a regex. If you debug and see the code it will run with "$regex".
Hope this solves the problem

how to call count operation after find with mongodb java driver

I am using MongoDB 3.0. suppose there is a set of documents named photos, its structure is
{"_id" : 1, photographer: "jack"}
with database.getCollection("photos"), Mongodb will return a MongoCollection object, on which I have the method count() to get the number documents returned.
However, when I make queries with specific conditions. For example find documents with id smaller than 100 :
photosCollections.find(Document.parse("{_id : {$lt : 100}}"))
Above find method will always return a cursor which doesn't provide a count() function. So how can I know how many documents returned ? I know on command line, I can use
db.photos.find({_id : {$lt : 100}}).count()
Of course, I can go through the iterator and count the number of documents myself. However I find it really clumsy. I am wondering does MongoDB java driver provides such functionality to count the number of documents returned by the find() method ? If not, what is the reason behind the decision ?
As you said the MongoCollection has the count() method that will return the number of documents in the collection, but it has also a count(Bson filter) that will return the number of documents in the collection according to the given options.
So you can just use:
long count = photosCollections.count(Document.parse("{_id : {$lt : 100}}"))
or maybe clearer:
Document query = new Document("_id", new Document("$lt", 100));
long count = photosCollections.count(query);
ref: http://api.mongodb.com/java/3.3/com/mongodb/client/MongoCollection.html#count-org.bson.conversions.Bson-
In MongoDB 3.4 you can only use the Iterator of FindIterable to get the count of the documents returned by a filter. e.g.
FindIterable findIterable =
mongoCollection.find(Filters.eq("EVENT_TYPE", "Sport"));
Iterator iterator = findIterable.iterator();
int count = 0;
while (iterator.hasNext()) {
iterator.next();
count++;
}
System.out.println(">>>>> count = " + count);
I had a similar problem. I am using MongoCollection instead of DBCollection, as it is what it is used in MongoDG 3.2 guide. MongoCollection hasn't got count() method, so I think the only option is to use the iterator to count them.
In my case I only needed to know if any document has been returned, I am using this:
if(result.first() != null)
Bson bson = Filters.eq("type", "work");
List<Document> list = collection.find(bson).into(new ArrayList<>());
System.out.println(list.size());
into(A) (A is collection type) method iterates over all the documents and adds each to the given target. Then we can get the count of the returned documents.
The API docs clearly state that DBCursor Object provides a count method:
MongoClient client = new MongoClient(MONGOHOST,MONGOPORT);
DBCollection coll = client.getDB(DBNAME).getCollection(COLLECTION);
DBObject query = new Querybuilder().start()
.put("_id").lessThan(100).get();
DBCursor result = coll.find(query);
System.out.println("Number of pictures found: " + result.count() );

Mongo DB regex aggregation query using java API

I want to query using regex and aggregation in mongo db, the following is working fine in mongo shell but how to write the same using Java API.
db.posts_collection.aggregate({$unwind:"$posts"},
{$match :{"posts.message":/.*keyword.*/} })
I tried using the following but unable to get the required result,
BasicDBObject unwind = new BasicDBObject("$unwind","$posts");
BasicDBObject matchKeyWord = new BasicDBObject("$match",new
BasicDBObject("posts.message",java.util.regex.Pattern.compile("keyword")));
AggregationOutput output = collection.aggregate(unwind,matchKeyWord);
Please tell me how to write the same query in java.
I would think that should work, but if you really wanted to be sure use the $regex operator form instead:
BasicDBObject unwind = new BasicDBObject("$unwind","$posts");
BasicDBObject matchKeyWord = new BasicDBObject(
"$match",new BasicDBObject(
"posts.message",new BasicDBObject("$regex",".*keyword.*")
)
);
AggregationOutput output = collection.aggregate(unwind,matchKeyWord);
That operator exists for the purpose of "safe" serialization with differing drivers.

MongoDB: Retrieving the first document in a collection

I'm new to Mongo, and I'm trying to retrieve the first document from a find() query:
> db.scores.save({a: 99});
> var collection = db.scores.find();
[
{ "a" : 99, "_id" : { "$oid" : "51a91ff3cc93742c1607ce28" } }
]
> var document = collection[0];
JS Error: result is undefined
This is a little weird, since a collection looks a lot like an array. I'm aware of retrieving a single document using findOne(), but is it possible to pull one out of a collection?
The find method returns a cursor. This works like an iterator in the result set. If you have too many results and try to display them all in the screen, the shell will display only the first 20 and the cursor will now point to the 20th result of the result set. If you type it the next 20 results will be displayed and so on.
In your example I think that you have hidden from us one line in the shell.
This command
> var collection = db.scores.find();
will just assign the result to the collection variable and will not print anything in the screen. So, that makes me believe that you have also run:
> collection
Now, what is really happening. If you indeed have used the above command to display the content of the collection, then the cursor will have reached the end of the result set (since you have only one document in your collection) and it will automatically close. That's why you get back the error.
There is nothing wrong with your syntax. You can use it any time you want. Just make sure that your cursor is still open and has results. You can use the collection.hasNext() method for that.
Is that the Mongo shell? What version? When I try the commands you type, I don't get any extra output:
MongoDB shell version: 2.4.3
connecting to: test
> db.scores.save({a: 99});
> var collection = db.scores.find();
> var document = collection[0];
In the Mongo shell, find() returns a cursor, not an array. In the docs you can see the methods you can call on a cursor.
findOne() returns a single document and should work for what you're trying to accomplish.
So you can have several options.
Using Java as the language, but one option is to get a db cursor and iterate over the elements that are returned. Or just simply grab the first one and run.
DBCursor cursor = db.getCollection(COLLECTION_NAME).find();
List<DOCUMENT_TYPE> retVal = new ArrayList<DOCUMENT_TYPE>(cursor.count());
while (cursor.hasNext()) {
retVal.add(cursor.next());
}
return retVal;
If you're looking for a particular object within the document, you can write a query and search all the documents for it. You can use the findOne method or simply find and get a list of objects matching your query. See below:
DBObject query = new BasicDBObject();
query.put(SOME_ID, ID);
DBObject result = db.getCollection(COLLECTION_NAME).findOne(query) // for a single object
DBCursor cursor = db.getCollection(COLLECTION_NAME).find(query) // for a cursor of multiple objects