diff --git a/aredis_om/model/model.py b/aredis_om/model/model.py index 07f6de14..3d81d0ed 100644 --- a/aredis_om/model/model.py +++ b/aredis_om/model/model.py @@ -1975,6 +1975,13 @@ async def page(self, offset=0, limit=10): exhaust_results=False ) + def find(self, *expressions: ExpressionOrNegated): + """Return a query with additional expressions combined using AND.""" + return self.copy( + expressions=[*self.expressions, *expressions], + knn=self.knn, + ) + def sort_by(self, *fields: str): if not fields: return self diff --git a/docs/querying.md b/docs/querying.md index 184b02c4..362372fe 100644 --- a/docs/querying.md +++ b/docs/querying.md @@ -40,6 +40,11 @@ customers = await Customer.find( Customer.last_name == "Brookins", Customer.age > 30 ).all() + +# Build dynamic filters incrementally (also combined with AND) +query = Customer.find(Customer.last_name == "Brookins") +query = query.find(Customer.age > 30) +customers = await query.all() ``` ## Expression Operators diff --git a/tests/test_find_query.py b/tests/test_find_query.py index 22da377b..b2f28dd3 100644 --- a/tests/test_find_query.py +++ b/tests/test_find_query.py @@ -446,3 +446,19 @@ async def test_find_query_monster(m): 1, 1, ] + + +@py_test_mark_asyncio +async def test_find_query_supports_chaining(members, m): + member1, member2, member3 = members + + base_query = m.Member.find(m.Member.last_name == "Brookins") + query = base_query.find(m.Member.age > 35) + actual = await query.sort_by("age").all() + + assert actual == [member1] + assert await base_query.sort_by("age").all() == [member2, member1] + + query = m.Member.find().find(m.Member.first_name == "Andrew") + query = query.find(m.Member.age > 50) + assert await query.all() == [member3]