'Finds a single document and updates it, returning either the
original or the updated document.
>>> db.test.find_one_and_update(
...    {\'_id\': 665}, {\'$inc\': {\'count\': 1}, \'$set\': {\'done\': True}})
{u\'_id\': 665, u\'done\': False, u\'count\': 25}}
By default :meth:`find_one_and_update` returns the original version of
the document before the update was applied. To return the updated
version of the document instead, use the *return_document* option.
>>> from pymongo import ReturnDocument
>>> db.example.find_one_and_update(
...     {\'_id\': \'userid\'},
...     {\'$inc\': {\'seq\': 1}},
...     return_document=ReturnDocument.AFTER)
{u\'_id\': u\'userid\', u\'seq\': 1}
You can limit the fields returned with the *projection* option.
>>> db.example.find_one_and_update(
...     {\'_id\': \'userid\'},
...     {\'$inc\': {\'seq\': 1}},
...     projection={\'seq\': True, \'_id\': False},
...     return_document=ReturnDocument.AFTER)
{u\'seq\': 2}
The *upsert* option can be used to create the document if it doesn\'t
already exist.
>>> db.example.delete_many({}).deleted_count
1
>>> db.example.find_one_and_update(
...     {\'_id\': \'userid\'},
...     {\'$inc\': {\'seq\': 1}},
...     projection={\'seq\': True, \'_id\': False},
...     upsert=True,
...     return_document=ReturnDocument.AFTER)
{u\'seq\': 1}
If multiple documents match *filter*, a *sort* can be applied.
>>> for doc in db.test.find({\'done\': True}):
...     print(doc)
{u\'_id\': 665, u\'done\': True, u\'result\': {u\'count\': 26}}
{u\'_id\': 701, u\'done\': True, u\'result\': {u\'count\': 17}}
>>> db.test.find_one_and_update(
...     {\'done\': True},
...     {\'$set\': {\'final\': True}},
...     sort=[(\'_id\', pymongo.DESCENDING)])
{u\'_id\': 701, u\'done\': True, u\'result\': {u\'count\': 17}}
:Parameters:
- `filter`: A query that matches the document to update.
- `update`: The update operations to apply.
- `projection` (optional): A list of field names that should be
returned in the result document or a mapping specifying the fields
to include or exclude. If `projection` is a list "_id" will
always be returned. Use a dict to exclude fields from
the result (e.g. projection={\'_id\': False}).
- `sort` (optional): a list of (key, direction) pairs
specifying the sort order for the query. If multiple documents
match the query, they are sorted and the first is updated.
- `upsert` (optional): When ``True``, inserts a new document if no
document matches the query. Defaults to ``False``.
- `return_document`: If
:attr:`ReturnDocument.BEFORE` (the default),
returns the original document before it was updated, or ``None``
if no document matches. If
:attr:`ReturnDocument.AFTER`, returns the updated
or inserted document.
- `**kwargs` (optional): additional command arguments can be passed
as keyword arguments (for example maxTimeMS can be used with
recent server versions).
.. versionchanged:: 3.4
Added the `collation` option.
.. versionchanged:: 3.2
Respects write concern.
.. warning:: Starting in PyMongo 3.2, this command uses the
:class:`~pymongo.write_concern.WriteConcern` of this
:class:`~pymongo.collection.Collection` when connected to MongoDB >=
3.2. Note that using an elevated write concern with this command may
be slower compared to using the default write concern.
.. versionadded:: 3.0'

def find_one_and_update(self, filter, update, projection=None, sort=None, upsert=False, return_document=ReturnDocument.BEFORE, **kwargs):

    common.validate_ok_for_update(update)
    kwargs['update'] = update
    return self.__find_and_modify(filter, projection, sort, upsert, return_document, **kwargs)
