Reputation: 4692
the question is very simple and clear. I don't want to use a cursor since it dramatically increases my operation time, I want to fetch all my documents at once and cache them through method execution.
MongoClient mongoClient = new MongoClient( "HOST" );
MongoDatabase db = mongoClient.getDatabase( "DB" );
MongoCollection<Document> collection = db.getCollection( "COLLECTION" );
FindIterable<Document> iterable = externalobjects.find( new Document( "test", "123" ) );
So, I want to convert above iterable
into a list, how can I use find and convert cursor to array ?
Upvotes: 1
Views: 2072
Reputation: 47905
The FindIterable
does not contain the documents you 'found' instead it acts as a handle to a server side cursor and in order to pull the data from that server side cursor and store them in a list within your application you must read documents from the cursor and add them to your list. For example:
// Java 8
List<Document> asList = new ArrayList<>();
documents.forEach((Consumer<Document>) d -> asList.add(d));
// Guava
List<Document> asList = Lists.newArrayList(documents);
// old skool
List<Document> asList = new ArrayList<>();
for (Document d : documents) {
asList.add(d);
}
There's no magic to it and no shortcut.
FWIW, this sounds a bit unusual:
I don't want to use a cursor since it dramatically reduces my operation time
Usually reduced operation time is a good thing ;) I'm guessing you might mean that it reduces the performance somehow? If so, the FindIterable
wraps a FindOperationIterable
which uses a MongoBatchCursorAdapter
as its iterator. According to the Java API docs tThe behaviour of the batch cursor is:
MongoDB returns query results as batches, and this interface provideds an iterator over those batches. The first call to the next method will return the first batch, and subsequent calls will trigger a request to get the next batch of results. Clients can control the batch size by setting the batchSize property between calls to next.
So, the FindIterable
serves to reduce the on-heap footprint (within your application) of the results of a find()
call and allows your application to get results as it needs them. There is one big caveat here: the default batch size is (IIRC) 100 so if you are reading a large mutiple of 100 documents then iterating over a FindIterable
will result in numerous calls back to the MongoDB server (one for each batch of 100 docuemnts in the result set). Perhaps this is the issue you are encountering? If so, then you can set the batch size to a number which achieves a compromise between the number of MongoDB server side calls and the heap available in your application. You set the batch size like this:
int batchSize = ...;
FindIterable<Document> iterable = externalobjects
.find(new Document("test", "123"))
.batchSize(batchSize);
Upvotes: 1