AsyncIOMotorCursor¶
Warning
Motor will be deprecated on May 14th, 2026, one year after the production release of the PyMongo Async driver. Critical bug fixes will be made until May 14th, 2027. We strongly recommend that Motor users migrate to the PyMongo Async driver while Motor is still supported. To learn more, see the migration guide.
- class motor.motor_asyncio.AsyncIOMotorCursor(cursor, collection)¶
Don’t construct a cursor yourself, but acquire one from methods like
MotorCollection.find()orMotorCollection.aggregate().Note
There is no need to manually close cursors; they are closed by the server after being fully iterated with
to_list(),each(), or async for, or automatically closed by the client when theMotorCursoris cleaned up by the garbage collector.- add_option(mask: int) Cursor[_DocumentType]¶
Set arbitrary query flags using a bitmask.
To set the tailable flag: cursor.add_option(2)
- allow_disk_use(allow_disk_use: bool) Cursor[_DocumentType]¶
Specifies whether MongoDB can use temporary disk files while processing a blocking sort operation.
Raises
TypeErrorif allow_disk_use is not a boolean.Note
allow_disk_use requires server version >= 4.4
- Parameters:
allow_disk_use – if True, MongoDB may use temporary disk files to store data exceeding the system memory limit while processing a blocking sort operation.
- clone()¶
Get a clone of this cursor.
- async close()¶
Explicitly kill this cursor on the server.
Call like:
await cursor.close()
- collation(collation: _CollationIn | None) Cursor[_DocumentType]¶
Adds a
Collationto this query.Raises
TypeErrorif collation is not an instance ofCollationor adict. RaisesInvalidOperationif thisCursorhas already been used. Only the last collation applied to this cursor has any effect.- Parameters:
collation – An instance of
Collation.
- comment(comment: Any) Cursor[_DocumentType]¶
Adds a ‘comment’ to the cursor.
http://mongodb.com/docs/manual/reference/operator/comment/
- Parameters:
comment – A string to attach to the query to help interpret and trace the operation in the server logs and in profile data.
- coroutine distinct(key: str) list¶
Get a list of distinct values for key among all documents in the result set of this query.
Raises
TypeErrorif key is not an instance ofstr.The
distinct()method obeys theread_preferenceof theCollectioninstance on whichfind()was called.- Parameters:
key – name of key for which we want to get the distinct values
- each(callback)¶
Iterates over all the documents for this cursor.
each()returns immediately, and callback is executed asynchronously for each document. callback is passed(None, None)when iteration is complete.Cancel iteration early by returning
Falsefrom the callback. (OnlyFalsecancels iteration: returningNoneor 0 does not.)>>> def each(result, error): ... if error: ... raise error ... elif result: ... sys.stdout.write(str(result["_id"]) + ", ") ... else: ... # Iteration complete ... IOLoop.current().stop() ... print("done") ... >>> cursor = collection.find().sort([("_id", 1)]) >>> cursor.each(callback=each) >>> IOLoop.current().start() 0, 1, 2, 3, 4, done
Note
Unlike other Motor methods,
eachrequires a callback and does not return a Future, so it cannot be used in a coroutine.async forandto_list()are much easier to use.- Parameters:
callback: function taking (document, error)
- coroutine explain() _DocumentType¶
Returns an explain plan record for this cursor.
Note
This method uses the default verbosity mode of the explain command,
allPlansExecution. To use a different verbosity usecommand()to run the explain command directly.See also
The MongoDB documentation on explain.
- hint(index: str | Sequence[str | Tuple[str, int | str | Mapping[str, Any]]] | Mapping[str, Any] | None) Cursor[_DocumentType]¶
Adds a ‘hint’, telling Mongo the proper index to use for the query.
Judicious use of hints can greatly improve query performance. When doing a query on multiple fields (at least one of which is indexed) pass the indexed field as a hint to the query. Raises
OperationFailureif the provided hint requires an index that does not exist on this collection, and raisesInvalidOperationif this cursor has already been used.index should be an index as passed to
create_index()(e.g.[('field', ASCENDING)]) or the name of the index. If index isNoneany existing hint for this query is cleared. The last hint applied to this cursor takes precedence over all others.- Parameters:
index – index to hint on (as an index specifier)
- limit(limit: int) Cursor[_DocumentType]¶
Limits the number of results to be returned by this cursor.
Raises
TypeErrorif limit is not an integer. RaisesInvalidOperationif thisCursorhas already been used. The last limit applied to this cursor takes precedence. A limit of0is equivalent to no limit.- Parameters:
limit – the number of results to return
See also
The MongoDB documentation on limit.
- max(spec: Sequence[str | Tuple[str, int | str | Mapping[str, Any]]] | Mapping[str, Any]) Cursor[_DocumentType]¶
Adds
maxoperator that specifies upper bound for specific index.When using
max,hint()should also be configured to ensure the query uses the expected index and starting in MongoDB 4.2hint()will be required.- Parameters:
spec – a list of field, limit pairs specifying the exclusive upper bound for all keys of a specific index in order.
- max_await_time_ms(max_await_time_ms: int | None) Cursor[_DocumentType]¶
Specifies a time limit for a getMore operation on a
TAILABLE_AWAITcursor. For all other types of cursor max_await_time_ms is ignored.Raises
TypeErrorif max_await_time_ms is not an integer orNone. RaisesInvalidOperationif thisCursorhas already been used.Note
max_await_time_ms requires server version >= 3.2
- Parameters:
max_await_time_ms – the time limit after which the operation is aborted
- max_scan(max_scan: int | None) Cursor[_DocumentType]¶
DEPRECATED - Limit the number of documents to scan when performing the query.
Raises
InvalidOperationif this cursor has already been used. Only the lastmax_scan()applied to this cursor has any effect.- Parameters:
max_scan – the maximum number of documents to scan
- max_time_ms(max_time_ms: int | None) Cursor[_DocumentType]¶
Specifies a time limit for a query operation. If the specified time is exceeded, the operation will be aborted and
ExecutionTimeoutis raised. If max_time_ms isNoneno limit is applied.Raises
TypeErrorif max_time_ms is not an integer orNone. RaisesInvalidOperationif thisCursorhas already been used.- Parameters:
max_time_ms – the time limit after which the operation is aborted
- min(spec: Sequence[str | Tuple[str, int | str | Mapping[str, Any]]] | Mapping[str, Any]) Cursor[_DocumentType]¶
Adds
minoperator that specifies lower bound for specific index.When using
min,hint()should also be configured to ensure the query uses the expected index and starting in MongoDB 4.2hint()will be required.- Parameters:
spec – a list of field, limit pairs specifying the inclusive lower bound for all keys of a specific index in order.
- async next()¶
Advance the cursor.
Added in version 2.2.
- next_object()¶
DEPRECATED - Get a document from the most recently fetched batch, or
None. Seefetch_next.The
next_object()method is deprecated and may be removed in a future major release. Use async for to elegantly iterate overMotorCursorobjects instead.Changed in version 2.2: Deprecated.
- remove_option(mask: int) Cursor[_DocumentType]¶
Unset arbitrary query flags using a bitmask.
To unset the tailable flag: cursor.remove_option(2)
- rewind()¶
Rewind this cursor to its unevaluated state.
- skip(skip: int) Cursor[_DocumentType]¶
Skips the first skip results of this cursor.
Raises
TypeErrorif skip is not an integer. RaisesValueErrorif skip is less than0. RaisesInvalidOperationif thisCursorhas already been used. The last skip applied to this cursor takes precedence.- Parameters:
skip – the number of results to skip
- sort(key_or_list: str | Sequence[str | Tuple[str, int | str | Mapping[str, Any]]] | Mapping[str, Any], direction: int | str | None = None) Cursor[_DocumentType]¶
Sorts this cursor’s results.
Pass a field name and a direction, either
ASCENDINGorDESCENDING:>>> async def f(): ... cursor = collection.find().sort("_id", pymongo.DESCENDING) ... docs = await cursor.to_list() ... print([d["_id"] for d in docs]) ... >>> IOLoop.current().run_sync(f) [4, 3, 2, 1, 0]
To sort by multiple fields, pass a list of (key, direction) pairs:
>>> async def f(): ... cursor = collection.find().sort( ... [("field1", pymongo.ASCENDING), ("field2", pymongo.DESCENDING)] ... ) ... docs = await cursor.to_list() ... print([(d["field1"], d["field2"]) for d in docs]) ... >>> IOLoop.current().run_sync(f) [(0, 4), (0, 2), (0, 0), (1, 3), (1, 1)]
Text search results can be sorted by relevance:
>>> async def f(): ... cursor = collection.find( ... {"$text": {"$search": "some words"}}, {"score": {"$meta": "textScore"}} ... ) ... # Sort by 'score' field. ... cursor.sort([("score", {"$meta": "textScore"})]) ... async for doc in cursor: ... print("%.1f %s" % (doc["score"], doc["field"])) ... >>> IOLoop.current().run_sync(f) 1.5 words about some words 1.0 words
Raises
InvalidOperationif this cursor has already been used. Only the lastsort()applied to this cursor has any effect.- Parameters:
key_or_list: a single key or a list of (key, direction) pairs specifying the keys to sort on
direction (optional): only used if key_or_list is a single key, if not given
ASCENDINGis assumed
- coroutine to_list(length=None)¶
Get a list of documents.
>>> from motor.motor_tornado import MotorClient >>> collection = MotorClient().test.test_collection >>> >>> async def f(): ... cursor = collection.find().sort([("_id", 1)]) ... docs = await cursor.to_list(length=2) ... while docs: ... print(docs) ... docs = await cursor.to_list(length=2) ... print("done") ... >>> ioloop.IOLoop.current().run_sync(f) [{'_id': 0}, {'_id': 1}] [{'_id': 2}, {'_id': 3}] done
- Parameters:
length: maximum number of documents to return for this call, or None
Returns a Future.
Changed in version 2.0: No longer accepts a callback argument.
Changed in version 0.2: callback must be passed as a keyword argument, like
to_list(10, callback=callback), and the length parameter is no longer optional.
- where(code: str | Code) Cursor[_DocumentType]¶
Adds a $where clause to this query.
The code argument must be an instance of
strCodecontaining a JavaScript expression. This expression will be evaluated for each document scanned. Only those documents for which the expression evaluates to true will be returned as results. The keyword this refers to the object currently being scanned. For example:# Find all documents where field "a" is less than "b" plus "c". async for doc in db.test.find().where('this.a < (this.b + this.c)'): print(doc)
Raises
TypeErrorif code is not an instance ofstr. RaisesInvalidOperationif thisMotorCursorhas already been used. Only the last call towhere()applied to aMotorCursorhas any effect.- Parameters:
code: JavaScript expression to use as a filter
- property address¶
The (host, port) of the server used, or None.
Changed in version 3.0: Renamed from “conn_id”.
- property alive¶
Does this cursor have the potential to return more data?
This is mostly useful with tailable cursors since they will stop iterating even though they may return more results in the future.
With regular cursors, simply use a for loop instead of
alive:for doc in collection.find(): print(doc)
- property cursor_id¶
Returns the id of the cursor
Added in version 2.2.
- property fetch_next¶
DEPRECATED - A Future used with gen.coroutine to asynchronously retrieve the next document in the result set, fetching a batch of documents from the server if necessary. Resolves to
Falseif there are no more documents, otherwisenext_object()is guaranteed to return a document:Attention
The
fetch_nextproperty is deprecated and will be removed in Motor 3.0. Use async for to iterate elegantly and efficiently overMotorCursorobjects instead.:>>> async def f(): ... await collection.drop() ... await collection.insert_many([{"_id": i} for i in range(5)]) ... async for doc in collection.find(): ... sys.stdout.write(str(doc["_id"]) + ", ") ... print("done") ... >>> IOLoop.current().run_sync(f) 0, 1, 2, 3, 4, done
While it appears that fetch_next retrieves each document from the server individually, the cursor actually fetches documents efficiently in large batches. Example usage:
>>> async def f(): ... await collection.drop() ... await collection.insert_many([{"_id": i} for i in range(5)]) ... cursor = collection.find().sort([("_id", 1)]) ... while await cursor.fetch_next: ... doc = cursor.next_object() ... sys.stdout.write(str(doc["_id"]) + ", ") ... print("done") ... >>> IOLoop.current().run_sync(f) 0, 1, 2, 3, 4, done
Changed in version 2.2: Deprecated.
- property session¶
The cursor’s
ClientSession, or None.Added in version 3.6.
AsyncIOMotorCommandCursor¶
- class motor.motor_asyncio.AsyncIOMotorCommandCursor(cursor, collection)¶
Don’t construct a cursor yourself, but acquire one from methods like
MotorCollection.find()orMotorCollection.aggregate().Note
There is no need to manually close cursors; they are closed by the server after being fully iterated with
to_list(),each(), or async for, or automatically closed by the client when theMotorCursoris cleaned up by the garbage collector.- async close()¶
Explicitly kill this cursor on the server.
Call like:
await cursor.close()
- each(callback)¶
Iterates over all the documents for this cursor.
each()returns immediately, and callback is executed asynchronously for each document. callback is passed(None, None)when iteration is complete.Cancel iteration early by returning
Falsefrom the callback. (OnlyFalsecancels iteration: returningNoneor 0 does not.)>>> def each(result, error): ... if error: ... raise error ... elif result: ... sys.stdout.write(str(result["_id"]) + ", ") ... else: ... # Iteration complete ... IOLoop.current().stop() ... print("done") ... >>> cursor = collection.find().sort([("_id", 1)]) >>> cursor.each(callback=each) >>> IOLoop.current().start() 0, 1, 2, 3, 4, done
Note
Unlike other Motor methods,
eachrequires a callback and does not return a Future, so it cannot be used in a coroutine.async forandto_list()are much easier to use.- Parameters:
callback: function taking (document, error)
- async next()¶
Advance the cursor.
Added in version 2.2.
- next_object()¶
DEPRECATED - Get a document from the most recently fetched batch, or
None. Seefetch_next.The
next_object()method is deprecated and may be removed in a future major release. Use async for to elegantly iterate overMotorCursorobjects instead.Changed in version 2.2: Deprecated.
- coroutine to_list(length=None)¶
Get a list of documents.
>>> from motor.motor_tornado import MotorClient >>> collection = MotorClient().test.test_collection >>> >>> async def f(): ... cursor = collection.find().sort([("_id", 1)]) ... docs = await cursor.to_list(length=2) ... while docs: ... print(docs) ... docs = await cursor.to_list(length=2) ... print("done") ... >>> ioloop.IOLoop.current().run_sync(f) [{'_id': 0}, {'_id': 1}] [{'_id': 2}, {'_id': 3}] done
- Parameters:
length: maximum number of documents to return for this call, or None
Returns a Future.
Changed in version 2.0: No longer accepts a callback argument.
Changed in version 0.2: callback must be passed as a keyword argument, like
to_list(10, callback=callback), and the length parameter is no longer optional.
- async try_next()¶
Advance the cursor without blocking indefinitely.
This method returns the next document without waiting indefinitely for data.
If no document is cached locally then this method runs a single getMore command. If the getMore yields any documents, the next document is returned, otherwise, if the getMore returns no documents (because there is no additional data) then
Noneis returned.- Returns:
The next document or
Nonewhen no document is available after running a single getMore or when the cursor is closed.
- property address¶
The (host, port) of the server used, or None.
Added in version 3.0.
- property alive¶
Does this cursor have the potential to return more data?
Even if
aliveisTrue,next()can raiseStopIteration. Best to use a for loop:for doc in collection.aggregate(pipeline): print(doc)
- property cursor_id¶
Returns the id of the cursor.
- property fetch_next¶
DEPRECATED - A Future used with gen.coroutine to asynchronously retrieve the next document in the result set, fetching a batch of documents from the server if necessary. Resolves to
Falseif there are no more documents, otherwisenext_object()is guaranteed to return a document:Attention
The
fetch_nextproperty is deprecated and will be removed in Motor 3.0. Use async for to iterate elegantly and efficiently overMotorCursorobjects instead.:>>> async def f(): ... await collection.drop() ... await collection.insert_many([{"_id": i} for i in range(5)]) ... async for doc in collection.find(): ... sys.stdout.write(str(doc["_id"]) + ", ") ... print("done") ... >>> IOLoop.current().run_sync(f) 0, 1, 2, 3, 4, done
While it appears that fetch_next retrieves each document from the server individually, the cursor actually fetches documents efficiently in large batches. Example usage:
>>> async def f(): ... await collection.drop() ... await collection.insert_many([{"_id": i} for i in range(5)]) ... cursor = collection.find().sort([("_id", 1)]) ... while await cursor.fetch_next: ... doc = cursor.next_object() ... sys.stdout.write(str(doc["_id"]) + ", ") ... print("done") ... >>> IOLoop.current().run_sync(f) 0, 1, 2, 3, 4, done
Changed in version 2.2: Deprecated.
- property session¶
The cursor’s
ClientSession, or None.Added in version 3.6.