Skip to content

Instantly share code, notes, and snippets.

@arshamalh
Last active March 23, 2022 11:04
Show Gist options
  • Save arshamalh/db10f489582a6e361fb1ac3fb0d65bf9 to your computer and use it in GitHub Desktop.
Save arshamalh/db10f489582a6e361fb1ac3fb0d65bf9 to your computer and use it in GitHub Desktop.
Pymongo Assistant
"""
Written by Arsham Arya
Some snippets around pymongo package to prevent my confusion.
"""
from pymongo import MongoClient
# Initializing
client = MongoClient("mongodb://username:password@host:port/default_db?authSource=admin")
database = client.get_database("db_name")
collection = database.get_collection("collection_name")
# Creating a unique index
collection.create_index("field_name", unique=True)
# Inserting
result = collection.insert_one({
"name": "Arsham",
"family": "Arya",
"age": 22
})
print(result.inserted_id) # ObjectId("595590494")
print(result.acknowledged) # True
# Updating
result = collection.update_one(
{"name": "Arsham"},
{"$set": {"profession": "programmer"}}
)
print(result.upserted_id) # None
print(result.acknowledged) # True
print(result.raw_result) # {'n': 1, 'nModified': 1, 'ok': 1.0, 'updatedExisting': True}
print(result.matched_count) # 1
print(result.modified_count) # 1
# Run code above again and only change will be modified_count which is 0
# upserted_id is None because we didn't set upsert=True in arguments.
# Inserting items to array field
# If you want also duplicated values, you should use $push instead of $addToSet
result = collection.update_one(
{"name": "Arsham"},
{"$addToSet": {"loved_numbers": {"$each": [32, 24, 12]}}}
)
# Don't doubt that $each is necessary!
# And if you ommit that, there will be a nested array instead.
# Aggregating
results = collection.aggregate([
{"$match": {"$and": [{"age": 22}, {"profession": "programmer"}]}},
{"$addFields": {"lovely_number": "$loved_numbers"}},
{"$project": {"name": 1, "family": 1, "lovely_number": 1}},
{"$unwind": "$lovely_number"},
])
for item in results:
print(type(item), item)
# <class 'dict'> {'_id': ObjectId('620a16e0f599d4631d0b1635'), 'name': 'Arsham', 'family': 'Arya', 'lovely_number': 32}
# <class 'dict'> {'_id': ObjectId('620a16e0f599d4631d0b1635'), 'name': 'Arsham', 'family': 'Arya', 'lovely_number': 24}
# <class 'dict'> {'_id': ObjectId('620a16e0f599d4631d0b1635'), 'name': 'Arsham', 'family': 'Arya', 'lovely_number': 12}
# Find also has same output as aggregate
# Be careful! pymongo won't return "None" for aggregate or find results,
# it will return a Cursor class that is a iterable even if there are nothing to iterate.
# find_one has a dictionary output and will return "None" if there is no record.
results = collection.aggregate([{"$match": {"age": 748}}])
# results won't be None.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment