1

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 ?

1 Answer 1

1

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);
Sign up to request clarification or add additional context in comments.

2 Comments

Ops sorry reduced word should be increased :D thansk for your answer
edited my question, thanks, I thought the same way but thought there should be an easy way to achieve it like the old driver, it had a toArray function

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.