Find RAW¶
We have a special classmethod called find_raw.
We can use this classmethod as a raw find function provided by PyMongo.
The find_raw method will return the Cursor of PyMongo.
If we iterate over the result, then we should get a dictionary-type item.
The find_raw is a very thin layer on top of the find from PyMongo.
Behind the hood, multiple classmethods of MongoDB-ODM use find_raw for simplicity.
Database¶
We will start with the same database structure and the same amount of data as previously.
Filter Collection¶
We can filter documents using find_raw.
# Code omitted above
def filter_documents():
players = Player.find_raw(filter={Player.rating: {"$gte": 10}})
for player in players:
print(player)
print()
# Code omitted below
Full file preview
import os
from typing import Optional
from mongodb_odm import ASCENDING, Document, IndexModel, apply_indexes, connect
from pymongo import MongoClient
class Player(Document):
name: str
country_code: str
rating: Optional[int] = None
class ODMConfig(Document.ODMConfig):
indexes = [
IndexModel([("rating", ASCENDING)]),
]
def configuration():
connect(os.environ.get("MONGO_URL", "mongodb://localhost:27017/testdb"))
apply_indexes()
def create_players():
Player(name="Pelé", country_code="BRA", rating=98).create()
Player(name="Diego Maradona", country_code="ARG", rating=97).create()
Player(name="Zinedine Zidane", country_code="FRA", rating=94).create()
Player(name="Ronaldo", country_code="BRA", rating=94).create()
Player(name="Neymar", country_code="BRA", rating=89).create()
Player(name="Lionel Messi", country_code="ARG", rating=91).create()
Player(name="Ángel Di María", country_code="ARG", rating=84).create()
Player(name="Karim Benzema", country_code="FRA", rating=89).create()
Player(name="Antoine Griezmann", country_code="FRA", rating=85).create()
Player(name="Kylian Mbappé", country_code="FRA", rating=91).create()
Player(name="Gerd Müller", country_code="GER").create()
Player(name="Miroslav Klose", country_code="GER", rating=91).create()
Player(name="Thomas Müller", country_code="GER", rating=87).create()
Player(name="Cristiano Ronaldo", country_code="POR", rating=87).create()
Player(name="Eusébio", country_code="POR", rating=93).create()
Player(name="Diogo Jota", country_code="POR", rating=85).create()
Player(name="David Beckham", country_code="ENG", rating=89).create()
Player(name="Wayne Rooney", country_code="ENG", rating=80).create()
Player(name="Harry Kane", country_code="ENG", rating=89).create()
def filter_documents():
players = Player.find_raw(filter={Player.rating: {"$gte": 10}})
for player in players:
print(player)
print()
def pymongo_find_and_find_raw_comparison():
filter = {Player.rating: {"$gte": 10}}
connection_url = os.environ.get("MONGO_URL", "mongodb://localhost:27017/testdb")
db = MongoClient(connection_url).get_database()
py_players = db.player.find(filter)
odm_players = Player.find_raw(filter)
print(py_players, odm_players)
def main():
configuration()
create_players()
filter_documents()
pymongo_find_and_find_raw_comparison()
if __name__ == "__main__":
main()
Same as PyMongo find¶
Let's see a comparison of find_raw with find from PyMongo.
# Code omitted above
def pymongo_find_and_find_raw_comparison():
filter = {Player.rating: {"$gte": 10}}
connection_url = os.environ.get("MONGO_URL", "mongodb://localhost:27017/testdb")
db = MongoClient(connection_url).get_database()
py_players = db.player.find(filter)
odm_players = Player.find_raw(filter)
# Code omitted below
Full file preview
import os
from typing import Optional
from mongodb_odm import ASCENDING, Document, IndexModel, apply_indexes, connect
from pymongo import MongoClient
class Player(Document):
name: str
country_code: str
rating: Optional[int] = None
class ODMConfig(Document.ODMConfig):
indexes = [
IndexModel([("rating", ASCENDING)]),
]
def configuration():
connect(os.environ.get("MONGO_URL", "mongodb://localhost:27017/testdb"))
apply_indexes()
def create_players():
Player(name="Pelé", country_code="BRA", rating=98).create()
Player(name="Diego Maradona", country_code="ARG", rating=97).create()
Player(name="Zinedine Zidane", country_code="FRA", rating=94).create()
Player(name="Ronaldo", country_code="BRA", rating=94).create()
Player(name="Neymar", country_code="BRA", rating=89).create()
Player(name="Lionel Messi", country_code="ARG", rating=91).create()
Player(name="Ángel Di María", country_code="ARG", rating=84).create()
Player(name="Karim Benzema", country_code="FRA", rating=89).create()
Player(name="Antoine Griezmann", country_code="FRA", rating=85).create()
Player(name="Kylian Mbappé", country_code="FRA", rating=91).create()
Player(name="Gerd Müller", country_code="GER").create()
Player(name="Miroslav Klose", country_code="GER", rating=91).create()
Player(name="Thomas Müller", country_code="GER", rating=87).create()
Player(name="Cristiano Ronaldo", country_code="POR", rating=87).create()
Player(name="Eusébio", country_code="POR", rating=93).create()
Player(name="Diogo Jota", country_code="POR", rating=85).create()
Player(name="David Beckham", country_code="ENG", rating=89).create()
Player(name="Wayne Rooney", country_code="ENG", rating=80).create()
Player(name="Harry Kane", country_code="ENG", rating=89).create()
def filter_documents():
players = Player.find_raw(filter={Player.rating: {"$gte": 10}})
for player in players:
print(player)
print()
def pymongo_find_and_find_raw_comparison():
filter = {Player.rating: {"$gte": 10}}
connection_url = os.environ.get("MONGO_URL", "mongodb://localhost:27017/testdb")
db = MongoClient(connection_url).get_database()
py_players = db.player.find(filter)
odm_players = Player.find_raw(filter)
print(py_players, odm_players)
def main():
configuration()
create_players()
filter_documents()
pymongo_find_and_find_raw_comparison()
if __name__ == "__main__":
main()
Here the variables py_players and odm_players are both 100% identical.
We can use limit, sort, skip, etc on both of the variables. Visit PyMongo for more details.
Why find_raw is Needed¶
- MongoDB is a very flexible and dynamic database. Data can change very frequently.
- Sometimes static type ODM becomes problematic though it has great auto-completion.
- In some scenarios, we may need projection on the query to optimize network bandwidth. But the find classmethod was not fully serving the purpose because some fields are required in the Class Model.
- And lots of other cases where we don't want to use a static modeling system
In the above scenario, find_raw becomes very useful.
Note¶
Behind the scenes, find, find_one, get and get_or_create use the find_raw classmethod to pull data from the database.