Skip to content

Commit 2362d1a

Browse files
alcaeusjmikola
andauthored
DRIVERS-3009, DRIVERS-1447: Updates to find operations (#1691)
Co-authored-by: Jeremy Mikola <[email protected]>
1 parent d795d49 commit 2362d1a

File tree

5 files changed

+355
-13
lines changed

5 files changed

+355
-13
lines changed

source/crud/crud.md

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -176,18 +176,20 @@ interface Collection {
176176
/**
177177
* Finds the documents matching the model.
178178
*
179-
* Note: The filter parameter below equates to the $query meta operator. It cannot
180-
* contain other meta operators like $maxScan. However, do not validate this document
181-
* as it would be impossible to be forwards and backwards compatible. Let the server
182-
* handle the validation.
183-
*
184179
* Note: result iteration should be backed by a cursor. Depending on the implementation,
185180
* the cursor may back the returned Iterable instance or an iterator that it produces.
186181
*
187-
* @see https://www.mongodb.com/docs/manual/core/read-operations-introduction/
182+
* @see https://www.mongodb.com/docs/manual/reference/command/find/
188183
*/
189184
find(filter: Document, options: Optional<FindOptions>): Iterable<Document>;
190185
186+
/**
187+
* Find a document matching the model.
188+
*
189+
* @see https://www.mongodb.com/docs/manual/reference/command/find/
190+
*/
191+
findOne(filter: Document, options: Optional<FindOneOptions>): Optional<Document>;
192+
191193
}
192194
193195
interface Database {
@@ -712,6 +714,8 @@ class FindOptions {
712714
*/
713715
let: Optional<Document>;
714716
}
717+
718+
type FindOneOptions = Omit<FindOptions, 'batchSize' | 'cursorType' | 'limit' | 'noCursorTimeout'>;
715719
```
716720

717721
##### Count API Details
@@ -783,7 +787,26 @@ filter, skip, and limit are added as options to the `aggregate` command.
783787
In the event this aggregation is run against an empty collection, an empty array will be returned with no `n` field.
784788
Drivers MUST interpret this result as a `0` count.
785789
786-
##### Combining Limit and Batch Size for the Wire Protocol
790+
##### findOne API details
791+
792+
The `findOne` operation is implemented using a `find` operation, but only returns the first document returned in the
793+
cursor. Due to the special case, `findOne` does not support the following options supported in `find`:
794+
795+
- `batchSize`: drivers MUST NOT set a `batchSize` in the `find` command created for a `findOne` operation
796+
- `cursorType`: `findOne` only supports non-tailable cursors
797+
- `limit`: drivers MUST set `limit` to 1 in the `find` command created for a `findOne` operation
798+
- `noCursorTimeout`: with a `limit` of 1 and no `batchSize`, there will not be an open cursor on the server
799+
800+
To ensure that the cursor is closed regardless of the default server `batchSize`, drivers MUST also set
801+
`singleBatch: true` in the `find` command.
802+
803+
##### Setting limit and batchSize options for find commands
804+
805+
When users specify both `limit` and `batchSize` options with the same value, the server returns all results in the first
806+
batch, but still leaves an open cursor that needs to be closed using the `killCursors` command. To avoid this, drivers
807+
MUST send a value of `limit + 1` for `batchSize` in the resulting `find` command. This eliminates the open cursor issue.
808+
809+
##### Combining Limit and Batch Size for OP_QUERY
787810
788811
The OP_QUERY wire protocol only contains a numberToReturn value which drivers must calculate to get expected limit and
789812
batch size behavior. Subsequent calls to OP_GET_MORE should use the user-specified batchSize or default to 0. If the
@@ -2397,12 +2420,6 @@ update and delete. This generally causes some issues for new developers and is a
23972420
developers. The safest way to combat this without introducing discrepancies between drivers/driver versions or breaking
23982421
backwards compatibility was to use multiple methods, each signifying the number of documents that could be affected.
23992422
2400-
Q: Speaking of "One", where is `findOne`?
2401-
2402-
If your driver wishes to offer a `findOne` method, that is perfectly fine. If you choose to implement `findOne`, please
2403-
keep to the naming conventions followed by the `FindOptions` and keep in mind that certain things don't make sense like
2404-
limit (which should be -1), tailable, awaitData, etc...
2405-
24062423
Q: What considerations have been taken for the eventual merging of query and the aggregation framework?
24072424
24082425
In the future, it is probable that a new query engine (QE) will look very much like the aggregation framework. Given
@@ -2496,6 +2513,8 @@ aforementioned allowance in the SemVer spec.
24962513
24972514
## Changelog
24982515
2516+
- 2024-11-13: Define `findOne` operation as optional, and add guidance on `limit` and `batchSize` for `find` operations.
2517+
24992518
- 2024-11-04: Always send a value for `bypassDocumentValidation` if it was specified.
25002519
25012520
- 2024-11-01: Add hint to DistinctOptions

source/crud/tests/unified/find.json

Lines changed: 62 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

source/crud/tests/unified/find.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,31 @@ tests:
105105
- { _id: 2, x: 22 }
106106
- { _id: 3, x: 33 }
107107
- { _id: 4, x: 44 }
108+
-
109+
description: 'Find with batchSize equal to limit'
110+
operations:
111+
-
112+
object: *collection0
113+
name: find
114+
arguments:
115+
filter: { _id: { $gt: 1 } }
116+
sort: { _id: 1 }
117+
limit: 4
118+
batchSize: 4
119+
expectResult:
120+
- { _id: 2, x: 22 }
121+
- { _id: 3, x: 33 }
122+
- { _id: 4, x: 44 }
123+
- { _id: 5, x: 55 }
124+
expectEvents:
125+
- client: *client0
126+
events:
127+
- commandStartedEvent:
128+
command:
129+
find: *collection0Name
130+
filter: { _id: { $gt: 1 } }
131+
limit: 4
132+
# Drivers use limit + 1 for batchSize to ensure the server closes the cursor
133+
batchSize: 5
134+
commandName: find
135+
databaseName: *database0Name

source/crud/tests/unified/findOne.json

Lines changed: 158 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)