The "limit" argument to mongoc_collection_find should be used for two purposes:
1. Mark a mongoc_cursor_t as "done" once it has fetched "limit" documents
2. Send limit to the server as the nToReturn field in the OP_QUERY and OP_GETMORE message headers
The driver respects #1, but not #2. Instead, it always sends nToReturn of 0 to the server, meaning, "accept server default" batch size of 101 documents at first, then 4MB of documents after.
This bug incurs a performance penalty: the final batch is always full-sized (about 4MB) even if the cursor only needs part of it.
If mongoc_collection_find's batch_size is non-0 the logic is correct; it's when batch_size is 0 (the default) that limit is incorrectly ignored when formatting OP_QUERY and OP_GETMORE:
static int32_t _mongoc_n_return (mongoc_cursor_t * cursor) { /* by default, use the batch size */ int32_t r = cursor->batch_size; if (cursor->is_command) { /* commands always have n_return of 1 */ r = 1; } else if (cursor->limit) { /* calculate remaining */ uint32_t remaining = cursor->limit - cursor->count; /* use min of batch or remaining */ r = BSON_MIN(r, (int32_t)remaining); } return r; }
- related to
-
CDRIVER-411 find() with a limit ignores documents not fitting in the initial batch
- Closed
-
PHPLIB-152 Do not specify negative limit in FindOne operation
- Closed
-
CDRIVER-267 Streamline limit / batchSize
- Closed