-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
238 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
# Queries | ||
|
||
Making queries is a must when using an ODM and being able to make complex queries is even better | ||
when allowed. | ||
|
||
MongDB is known for its performance when querying a database and it is very fast. T | ||
|
||
When making queries in a [document][document], the ODM allow two different possible ways of querying. | ||
One is using its internal **manager** and the second its internal **queryset**. | ||
|
||
In reality, the `manager` and `queryset` are very similar but for internal purposes it was decided | ||
to call both in this way to be clear in the way the queries can be done. | ||
|
||
If you haven't yet seen the [documents][document] section, now would be a great time to have a look | ||
and get yourself acquainted . | ||
|
||
For the purpose of this documentation, we will be showing how to query using both the `manager` and | ||
the `queryset`. | ||
|
||
Both queryset and manager work really well also when combibed. In the end is up to the developer | ||
to decide which one it prefers better. | ||
|
||
## QuerySet and Manager | ||
|
||
When making queries within Mongoz, this return or an object if you want only one result or a | ||
`queryset`/`manager` which is the internal representation of the results. | ||
|
||
If you are familiar with Django querysets, this is **almost** the same and by almost is because | ||
mongoz restricts loosely queryset variable assignments. | ||
|
||
Let us get familar with queries. | ||
|
||
Let us assume you have the following `User` document defined. | ||
|
||
```python | ||
{!> ../docs_src/queries/document.py !} | ||
``` | ||
|
||
As mentioned before, Mongoz allows to use two ways of querying. Via `manager` and via `queryset`. | ||
Both allow chain calls, for instance, `sort()` with a `limit()` combined. | ||
|
||
For instance, let us create a user. | ||
|
||
=== "Manager" | ||
|
||
```python | ||
user = await User.objects.create( | ||
first_name="Mongoz", last_name="ODM", email="[email protected]", | ||
password="Compl3x!pa$$" | ||
) | ||
``` | ||
|
||
=== "QuerySet" | ||
|
||
```python | ||
user = await User( | ||
first_name="Mongoz", last_name="ODM", email="[email protected]", | ||
password="Compl3x!pa$$" | ||
).create() | ||
``` | ||
|
||
As you can see, the **manager** uses the `objects` to access the operations and the `queryset` does | ||
it in a different way. | ||
|
||
For those familiar with Django, the `manager` follows the same lines. | ||
|
||
Let us now query the database to obtain a simple record but filtering it by `email` and `first_name`. | ||
We want this to return a list since we are using a `filter`. | ||
|
||
=== "Manager" | ||
|
||
```python | ||
users = await User.objects.filter( | ||
email="[email protected]", first_name="Mongo" | ||
) | ||
``` | ||
|
||
=== "QuerySet" | ||
|
||
```python | ||
users = await User.query(User.email == "[email protected]").query( | ||
User.first_name == "Mongo" | ||
).all() | ||
``` | ||
|
||
Quite simple right? Well yes, although preferably we would recommend the use of the `manager` for | ||
almost everything you can do with Mongoz, sometimes using the `queryset` can be also useful if | ||
you like different syntaxes. This syntax was inspired by Mongox. | ||
|
||
## Returning managers/querysets | ||
|
||
There are many operations you can do with the managers/querysets and then you can also leverage those | ||
for your use cases. | ||
|
||
The following operators return `managers`/`querysets` which means you can combine different | ||
operators at the same time. | ||
|
||
|
||
|
||
[document]: ./documents.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import mongoz | ||
|
||
database_uri = "mongodb://localhost:27017" | ||
registry = mongoz.Registry(database_uri) | ||
|
||
|
||
class User(mongoz.Document): | ||
is_active: bool = mongoz.Boolean(default=True) | ||
first_name: str = mongoz.String(max_length=50) | ||
last_name: str = mongoz.String(max_length=50) | ||
email: str = mongoz.Email(max_lengh=100) | ||
password: str = mongoz.String(max_length=1000) | ||
|
||
class Meta: | ||
registry = registry | ||
database = "my_db" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
import asyncio | ||
|
||
import mongoz | ||
|
||
database_uri = "mongodb://localhost:27017" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
from typing import AsyncGenerator, List, Optional | ||
|
||
import pydantic | ||
import pytest | ||
from tests.conftest import client | ||
|
||
import mongoz | ||
from mongoz import Document, Index, IndexType, ObjectId, Order | ||
|
||
pytestmark = pytest.mark.anyio | ||
pydantic_version = pydantic.__version__[:3] | ||
|
||
indexes = [ | ||
Index("name", unique=True), | ||
Index(keys=[("year", Order.DESCENDING), ("genre", IndexType.HASHED)]), | ||
] | ||
|
||
|
||
class Movie(Document): | ||
name: str = mongoz.String() | ||
year: int = mongoz.Integer() | ||
tags: Optional[List[str]] = mongoz.Array(str, null=True) | ||
uuid: Optional[ObjectId] = mongoz.ObjectId(null=True) | ||
|
||
class Meta: | ||
registry = client | ||
database = "test_db" | ||
indexes = indexes | ||
|
||
|
||
@pytest.fixture(scope="function", autouse=True) | ||
async def prepare_database() -> AsyncGenerator: | ||
await Movie.drop_indexes(force=True) | ||
await Movie.objects.delete() | ||
await Movie.create_indexes() | ||
yield | ||
await Movie.drop_indexes(force=True) | ||
await Movie.objects.delete() | ||
await Movie.create_indexes() | ||
|
||
|
||
async def test_model_exclude() -> None: | ||
batman = await Movie.objects.create(name="Batman", year=2022) | ||
await Movie.objects.create(name="Barbie", year=2023) | ||
await Movie.objects.create(name="Oppenheimer", year=2023) | ||
|
||
movies = await Movie.objects.exclude(pk=batman.id) | ||
|
||
assert len(movies) == 2 | ||
|
||
|
||
async def xtest_models_exclude() -> None: | ||
await Movie.objects.create(name="Batman", year=2022) | ||
await Movie.objects.create(name="Barbie", year=2023) | ||
await Movie.objects.create(name="Oppenheimer", year=2023) | ||
|
||
movies = await Movie.objects.exclude(year__gt=2019) | ||
|
||
assert len(movies) == 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters