PyMongo: Using MongoDB from Python
Use PyMongo to work with MongoDB from Python: install it in a virtual environment, insert test documents, query them with find and find_one, and update fields.

I wrote this post in Spanish in 2022 and adapted it to English in 2026.
This tutorial picks up where a previous one left off: the MongoDB getting started tutorial, where I show you how to install MongoDB using Docker.
The goal of this tutorial, "PyMongo: Using MongoDB from Python", is to create some test data and insert it into the MongoDB we installed in the previous tutorial.
To pull all this off, we'll use PyMongo, a Python library that lets you create connections to MongoDB.
How to Install PyMongo? #
Before installing this library, the first thing is to get organized. Use this terminal command to create a folder that keeps the scripts and the virtual environment we'll use in this tutorial in one place.
$ mkdir ~/pymongo_tutorial && cd ~/pymongo_tutorial && python3 -m venv pymongo_venv && source pymongo_venv/bin/activate
The command above creates the pymongo_tutorial folder in your home directory, goes into that folder, creates a virtual environment called pymongo_venv and activates it. Your terminal should now show (pymongo_venv) in parentheses, meaning the virtual environment is active.
Installing PyMongo in the virtual environment
To install PyMongo, all that's left is to run this command in the terminal:
python3 -m pip install pymongo
And that's it. PyMongo is now available and you can start writing scripts that connect to Mongo (careful: as long as this virtual environment is active, or PyMongo is installed in the virtual environment you're using).
Time for the party to continue: let's start putting documents in your MongoDB. For that, we'll create some documents to test with, thanks to the magic of Python.
Creating and Inserting Test Data #
To connect to MongoDB using PyMongo, we'll write a small Python script that does the job.
First, create the file we'll be working with by running this command in the terminal:
touch mongo_writer.py
Once that's done, open the file with your favorite text editor by picking one of these commands:
code mongo_writer.py #(recommended)
nano mongo_writer.py #(advanced)
vim mongo_writer.py #(for geeks like me)
The goal of the script we're going to write is to create 10 JSON documents and insert them into the MongoDB we created in the previous tutorial on how to install MongoDB.
So the first thing we'll do is connect to MongoDB, and for that we need to import a couple of utilities from PyMongo.
import pymongo
from pymongo import MongoClient
Now we can create the connection to MongoDB:
client = MongoClient('mongodb://localhost:27018/')
db = client["db_pruebas"]
collection = db["coleccion_pruebas"]
The MongoClient argument is the MongoDB we'll connect to. In this case, the address localhost:27018/ tells it to use our local machine on port 27018.
Now, with a for loop, we'll create the 10 JSON documents and insert them into our MongoDB one by one.
for i in range(10):
doc = {}
doc["titulo"] = f"Titulo de pruebas número {i}"
doc["numero"] = str(i)
doc["contenido"] = f"Este es el contenido del documento número {i}"
collection.insert_one(doc) # this is where the documents get inserted into MongoDB
Let me remind you that in the previous tutorial I mentioned MongoDB's "flexibility" as a document-oriented database.
In this script we're connecting to the db_pruebas database and the collection called coleccion_pruebas, but neither one exists in our MongoDB yet.
And that flexibility I talked about in the previous tutorial is what comes into play here: if MongoDB can't find the database or collection you're asking for, it just creates it, no questions asked.
All of the above together in one script looks like this:
import pymongo
from pymongo import MongoClient
client = MongoClient('mongodb://localhost:27018/')
db = client["db_pruebas"]
collection = db["coleccion_pruebas"]
for i in range(10):
doc = {}
doc["titulo"] = f"Titulo de pruebas número {i}"
doc["numero"] = str(i)
doc["contenido"] = f"Este es el contenido del documento número {i}"
collection.insert_one(doc)
All that's left is to save the script and run this in the terminal:
python3 mongo_writer.py
With that, you'll have 10 JSON documents stored in your MongoDB, in the collection called coleccion_pruebas inside the db_pruebas database.
Some MongoDB Queries with PyMongo #
Moving on with the tutorial, we'll now look at a couple of queries so you can search for documents in your MongoDB.
These queries need to be adapted to the shape of your documents, in other words, to the fields they contain, because the ones we'll use in this tutorial fit the test documents we created in the previous section.
First, let's open the Python console with the virtual environment active and enter the commands for the Mongo connection.
>>> import pymongo
>>> from pymongo import MongoClient
>>> client = MongoClient('mongodb://localhost:27018/')
>>> db = client["db_pruebas"]
>>> collection = db["coleccion_pruebas"]
With all that in place, we can start querying our coleccion_pruebas and see the documents stored there. For that, just do:
>>> docs = collection.find()
The find(query) command, with an empty query, returns every document in the collection. Be careful with this command, because if there are millions of documents you might end up knocking over your MongoDB.
Let's see what type of data the docs variable holds now:
>>> type(docs)
<class 'pymongo.cursor.Cursor'>
As you can see, it's a "Cursor". This cursor holds a sort of "list" with all the documents the query found. If it found none, it returns NoneType.
Let's see which methods you can use on this "Cursor".
>>> dir(docs)
['_Cursor__address', '_Cursor__allow_disk_use',
'_Cursor__batch_size', '_Cursor__check_okay_to_chain',
'_Cursor__codec_options', '_Cursor__collation',
'_Cursor__collection', '_Cursor__collname',
'_Cursor__comment', '_Cursor__data', '_Cursor__dbname',
'_Cursor__die', '_Cursor__empty', '_Cursor__exhaust',
'_Cursor__explain', '_Cursor__explicit_session',
'_Cursor__has_filter', '_Cursor__hint', '_Cursor__id',
'_Cursor__killed', '_Cursor__let', '_Cursor__limit',
'_Cursor__max', '_Cursor__max_await_time_ms',
'_Cursor__max_scan', '_Cursor__max_time_ms', '_Cursor__min',
'_Cursor__ordering', '_Cursor__projection',
'_Cursor__query_flags', '_Cursor__query_spec',
'_Cursor__read_concern', '_Cursor__read_preference',
'_Cursor__retrieved', '_Cursor__return_key',
'_Cursor__send_message', '_Cursor__session',
'_Cursor__set_hint', '_Cursor__show_record_id',
'_Cursor__skip', '_Cursor__snapshot', '_Cursor__sock_mgr',
'_Cursor__spec', '__class__', '__class_getitem__',
'__copy__', '__deepcopy__', '__del__', '__delattr__',
'__dict__', '__dir__', '__doc__', '__enter__', '__eq__',
'__exit__', '__format__', '__ge__', '__getattribute__',
'__getitem__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__iter__', '__le__', '__lt__',
'__module__', '__ne__', '__new__', '__next__',
'__orig_bases__', '__parameters__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
'__slots__', '__str__', '__subclasshook__', '__weakref__',
'_clone', '_clone_base', '_deepcopy', '_getmore_class',
'_is_protocol', '_query_class', '_read_preference',
'_refresh', '_unpack_response', 'add_option', 'address',
'alive', 'allow_disk_use', 'batch_size', 'clone', 'close',
'collation', 'collection', 'comment', 'cursor_id',
'distinct', 'explain', 'hint', 'limit', 'max',
'max_await_time_ms', 'max_scan', 'max_time_ms', 'min',
'next', 'remove_option', 'retrieved', 'rewind', 'session',
'skip', 'sort', 'where']
As you can see, they all have to do with handling documents (order, limit, etc.) and connection times with MongoDB.
Like I said before, the Cursor is a sort of "list" we can iterate over to see our documents. So let's use a for loop to see what we created with the script that inserted the documents.
>>> for doc in docs:
... print(doc)
...
All the documents should have shown up in your terminal. Here I'll show just one, to keep the explanation practical:
{'_id': ObjectId('6342e0d5bddca892967fc006')
, 'titulo': 'Titulo de pruebas número 0'
, 'numero': '0'
, 'contenido': 'Este es el contenido del documento número 0'}
Using the methods PyMongo's Cursor allows, we can change the query's output, for example by limiting the number of results to 3:
>>> docs = collection.find().limit(3)
Now docs holds 3 documents instead of 10. To find out how many documents a PyMongo Cursor has, just do:
>>> len(list(docs))
3
>>>
Now let's try a couple of queries to search for documents in MongoDB using PyMongo.
Say I want the document whose numero has a value of 5. The query would be:
query = {'numero':'5'}
And to search for it, we'll use find_one instead of find:
doc5 = collection.find_one(query)
In the console, it would look like this:
>>> query = {'numero':'5'}
>>> doc5 = collection.find_one(query)
>>> doc5['numero']
'5'
>>>
We can search for several documents at once using find and a query that returns multiple results. For example:
Now say I need the documents whose numero field is 1, 7 or 9. The query would be:
query = {'numero':{'$in':['1','7','9']}}
And to search for the documents, we use find:
docs_1_7_9 = collection.find(query)
In the console, it would look something like:
>>> query = {'numero':{'$in':['1','7','9']}}
>>> docs_1_7_9 = collection.find(query)
>>> for i in docs_1_7_9:
... print(i['numero'])
...
1
7
9
>>>
Queries can be as complex as you need, or as your documents allow. That's up to your imagination and/or needs. For now, let's keep moving through the tutorial.
Updating MongoDB Documents with PyMongo #
As the last section of this intro to PyMongo, I'll show you how to update documents inside a collection.
The first thing is knowing how to find the document you want to update, and in the previous section I showed you how to run queries.
To save time, we'll use the last query from the previous example, which gave us a Cursor with the documents whose number field was 1, 7 or 9.
Say we want to change the number field on these documents. For this particular example, we'll add ten to each one (we'll add 10 to each number).
In the console, it would look something like:
>>> query = {'numero':{'$in':['1','7','9']}}
>>> docs_1_7_9 = collection.find(query)
>>> for i in docs_1_7_9:
... new_num = int(i["numero"]) + 10
... collection.update_one({"_id":i["_id"]},{"$set":{"numero":new_num}},upsert=False)
...
<pymongo.results.UpdateResult object at 0x7f885867ef10>
<pymongo.results.UpdateResult object at 0x7f885867ef40>
<pymongo.results.UpdateResult object at 0x7f885867ef10>
>>>
To check the change, just search again for the documents whose number is 1, 7 or 9, and you'll see they no longer exist (because we changed them).
>>> docs_1_7_9 = collection.find(query)
>>> len(list(docs_1_7_9))
0
>>>
Now they're documents with the numero field 11, 17 or 19. To check this, just change the query like this:
>>> query = {'numero':{'$in':[11,17,19]}}
>>> docs_11_17_19 = collection.find(query)
>>> len(list(docs_11_17_19))
3
>>>
As you may have noticed, the quotes around the numbers disappeared from the query. That's because when we updated the field, we changed its data type from string to int.
This same way of updating with update_one plus {"$set":{"field":"value"}} can be used to add new fields to documents. For example, we can add the new field nuevo_campo ("new field") to our freshly updated documents:
>>> docs_11_17_19 = collection.find(query)
>>> for i in docs_11_17_19:
... collection.update_one({"_id":i["_id"]},{"$set":{"nuevo_campo":"Hola Mundo"}},upsert=False)
...
<pymongo.results.UpdateResult object at 0x7f8858612ac0>
<pymongo.results.UpdateResult object at 0x7f8858612550>
<pymongo.results.UpdateResult object at 0x7f8858612c40>
>>> docs_11_17_19 = collection.find(query)
>>> for i in docs_11_17_19:
... print(i["nuevo_campo"])
...
Hola Mundo
Hola Mundo
Hola Mundo
>>>
And we'll leave the tutorial here. I don't want to sign off without stressing that we declared the docs variable holding the PyMongo Cursor every time we were about to use it, because the Cursor is an iterator and it's used up every time you iterate over it.
Now I'll say goodbye, hoping you'll read the next tutorial in this MongoDB series, where I show you how to use Studio 3T to view the documents in that IDE.


