Skip to content

Commit

Permalink
Search by linked documents fields (#171)
Browse files Browse the repository at this point in the history
  • Loading branch information
roman-right authored Dec 17, 2021
1 parent b007327 commit 112cc0d
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 13 deletions.
2 changes: 1 addition & 1 deletion beanie/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from beanie.odm.utils.general import init_beanie
from beanie.odm.documents import Document

__version__ = "1.8.7"
__version__ = "1.8.8"
__all__ = [
# ODM
"Document",
Expand Down
13 changes: 6 additions & 7 deletions beanie/odm/queries/find.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,12 +560,9 @@ def _set_cache(self, data):
@property
def motor_cursor(self):
if self.fetch_links:
aggregation_pipeline: List[Dict[str, Any]] = [
{"$match": self.get_filter_query()}
]
aggregation_pipeline += construct_lookup_queries(
self.document_model
)
aggregation_pipeline: List[
Dict[str, Any]
] = construct_lookup_queries(self.document_model)
sort_pipeline = {
"$sort": {i[0]: i[1] for i in self.sort_expressions}
}
Expand All @@ -575,10 +572,12 @@ def motor_cursor(self):
aggregation_pipeline.append({"$skip": self.skip_number})
if self.limit_number != 0:
aggregation_pipeline.append({"$limit": self.limit_number})

aggregation_pipeline.append({"$match": self.get_filter_query()})

aggregation_pipeline.append(
{"$project": get_projection(self.projection_model)}
)

return self.document_model.get_motor_collection().aggregate(
aggregation_pipeline, session=self.session
)
Expand Down
10 changes: 9 additions & 1 deletion docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

Beanie project changes

## [1.8.8] - 2021-12-17

### Added

- Search by linked documents fields (for pre-fetching search only)

## [1.8.7] - 2021-12-12

### Fixed
Expand Down Expand Up @@ -611,4 +617,6 @@ how specific type should be presented in the database

[1.8.6]: https://pypi.org/project/beanie/1.8.6

[1.8.7]: https://pypi.org/project/beanie/1.8.7
[1.8.7]: https://pypi.org/project/beanie/1.8.7

[1.8.8]: https://pypi.org/project/beanie/1.8.8
20 changes: 20 additions & 0 deletions docs/tutorial/relations.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,26 @@ If a direct link is referred to a non-existent document, after the fetching it w

Fetching will ignore non-existent documents for the list of links fields.

####Search by linked documents fields:

If the `fetch_links` parameter is set to `True` searching by linked documents fields is available.

By field of the direct link:
```python
houses = await House.find(
House.door.height == 2,
fetch_links=True
).to_list()
```

List of links:
```python
houses = await House.find(
House.windows.x > 10,
fetch_links=True
).to_list()
```

### On-demand fetch

If you don't use prefetching, linked documents will be presented as objects of the `Link` class. You can fetch them manually then.
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "beanie"
version = "1.8.7"
version = "1.8.8"
description = "Asynchronous Python ODM for MongoDB"
authors = ["Roman <[email protected]>"]
license = "Apache-2.0"
Expand Down
16 changes: 14 additions & 2 deletions tests/odm/test_relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ async def houses():
for i in range(10):
roof = Roof() if i % 2 == 0 else None
house = await House(
door=Door(),
windows=[Window(x=10, y=10), Window(x=11, y=11)],
door=Door(t=i),
windows=[Window(x=10, y=10 + i), Window(x=11, y=11 + i)],
roof=roof,
name="test",
height=i,
Expand Down Expand Up @@ -88,6 +88,18 @@ async def test_prefetch_find_many(self, houses):
await houses[0].fetch_link(House.door)
assert isinstance(houses[0].door, Link)

houses = await House.find_many(
House.door.t > 5, fetch_links=True
).to_list()

assert len(houses) == 3

houses = await House.find_many(
House.windows.y == 15, fetch_links=True
).to_list()

assert len(houses) == 2

async def test_prefetch_find_one(self, house):
house = await House.find_one(House.name == "test")
for window in house.windows:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_beanie.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@


def test_version():
assert __version__ == "1.8.7"
assert __version__ == "1.8.8"

0 comments on commit 112cc0d

Please sign in to comment.