1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
# Views
Virtual views are aggregation pipelines stored in MongoDB that act as collections for reading operations.
You can use the `View` class the same way as `Document` for `find` and `aggregate` operations.
## Here are some examples.
Create a view:
```python
from pydantic import Field
from beanie import Document, View
class Bike(Document):
type: str
frame_size: int
is_new: bool
class Metrics(View):
type: str = Field(alias="_id")
number: int
new: int
class Settings:
source = Bike
pipeline = [
{
"$group": {
"_id": "$type",
"number": {"$sum": 1},
"new": {"$sum": {"$cond": ["$is_new", 1, 0]}}
}
},
]
```
Initialize Beanie:
```python
from pymongo import AsyncMongoClient
from beanie import init_beanie
async def main():
uri = "mongodb://beanie:beanie@localhost:27017"
client = AsyncMongoClient(uri)
db = client.bikes
await init_beanie(
database=db,
document_models=[Bike, Metrics],
recreate_views=True,
)
```
Create bikes:
```python
await Bike(type="Mountain", frame_size=54, is_new=True).insert()
await Bike(type="Mountain", frame_size=60, is_new=False).insert()
await Bike(type="Road", frame_size=52, is_new=True).insert()
await Bike(type="Road", frame_size=54, is_new=True).insert()
await Bike(type="Road", frame_size=58, is_new=False).insert()
```
Find metrics for `type == "Road"`
```python
results = await Metrics.find(Metrics.type == "Road").to_list()
print(results)
>> [Metrics(type='Road', number=3, new=2)]
```
Aggregate over metrics to get the count of all the new bikes:
```python
results = await Metrics.aggregate([{
"$group": {
"_id": None,
"new_total": {"$sum": "$new"}
}
}]).to_list()
print(results)
>> [{'_id': None, 'new_total': 3}]
```
A better result can be achieved by using find query aggregation syntactic sugar:
```python
results = await Metrics.all().sum(Metrics.new)
print(results)
>> 3
```
|