From e42f36d2067e47eea596aa83839395696916bd30 Mon Sep 17 00:00:00 2001 From: Ido Shraga Date: Thu, 21 Sep 2023 13:48:27 +0300 Subject: [PATCH 01/12] array_filters --- docs/changelog.rst | 1 + docs/guide/querying.rst | 18 ++++++++++ mongoengine/queryset/base.py | 6 +++- tests/queryset/test_queryset.py | 60 +++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index a11745e5a..8b8a1b404 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -8,6 +8,7 @@ Development =========== - (Fill this out as you fix issues and develop your features). - Fix for uuidRepresentation not read when provided in URI #2741 +- Add option to user array_filters https://www.mongodb.com/docs/manual/reference/operator/update/positional-filtered/ Changes in 0.27.0 ================= diff --git a/docs/guide/querying.rst b/docs/guide/querying.rst index b9afb60e1..194e2a676 100644 --- a/docs/guide/querying.rst +++ b/docs/guide/querying.rst @@ -252,6 +252,24 @@ and provide the pipeline as a list .. versionadded:: 0.23.2 +Update with Array Operator +-------------------------------- +It is possible to update specific value in array by use array_filters (arrayFilters) operator. +This is done by using ``__raw__`` keyword argument to the update method and provide the arrayFilters as a list. + +`Update with Array Operator `_ +:: + + # 'tags' field == ['test1', 'test2', 'test3'] + Page.objects().update(__raw__= + {'$set': {"tags.$[element]": 'test11111'}}, + array_filters=[{"element": {'$eq': 'test2'}}], + + # 'tags' field == ['test1', 'test11111', 'test3'] + + ) + + Sorting/Ordering results ======================== It is possible to order the results by 1 or more keys using :meth:`~mongoengine.queryset.QuerySet.order_by`. diff --git a/mongoengine/queryset/base.py b/mongoengine/queryset/base.py index d33e7b1e3..149c11b18 100644 --- a/mongoengine/queryset/base.py +++ b/mongoengine/queryset/base.py @@ -530,6 +530,7 @@ def update( write_concern=None, read_concern=None, full_result=False, + array_filters=None, **update, ): """Perform an atomic update on the fields matched by the query. @@ -545,6 +546,7 @@ def update( :param read_concern: Override the read concern for the operation :param full_result: Return the associated ``pymongo.UpdateResult`` rather than just the number updated items + :param array_filters: A list of filters specifying which array elements an update should apply. :param update: Django-style update keyword arguments :returns the number of updated documents (unless ``full_result`` is True) @@ -565,6 +567,8 @@ def update( for u in update["__raw__"] ] else: + if 'array_filters' in update: + array_filters = update.pop('array_filters') update = transform.update(queryset._document, **update) # If doing an atomic upsert on an inheritable class # then ensure we add _cls to the update operation @@ -580,7 +584,7 @@ def update( update_func = collection.update_one if multi: update_func = collection.update_many - result = update_func(query, update, upsert=upsert) + result = update_func(query, update, upsert=upsert, array_filters=array_filters) if full_result: return result elif result.raw_result: diff --git a/tests/queryset/test_queryset.py b/tests/queryset/test_queryset.py index d1cae3415..0854aacf5 100644 --- a/tests/queryset/test_queryset.py +++ b/tests/queryset/test_queryset.py @@ -591,6 +591,66 @@ class Blog(Document): Blog.drop_collection() + def test_update_array_filters(self): + """Ensure that updating by array_filters works. + """ + + class Comment(EmbeddedDocument): + comment_tags = ListField(StringField()) + + class Blog(Document): + tags = ListField(StringField()) + comments = EmbeddedDocumentField(Comment) + + Blog.drop_collection() + + # update one + Blog.objects.create(tags=['test1', 'test2', 'test3']) + + Blog.objects().update_one(__raw__= + {'$set': {"tags.$[element]": 'test11111'}}, + array_filters=[{"element": {'$eq': 'test2'}}], + ) + testc_blogs = Blog.objects(tags="test11111") + + assert testc_blogs.count() == 1 + + Blog.drop_collection() + + # update one inner list + comments = Comment(comment_tags=['test1', 'test2', 'test3']) + Blog.objects.create(comments=comments) + + Blog.objects().update_one(__raw__= + {'$set': {"comments.comment_tags.$[element]": 'test11111'}}, + array_filters=[{"element": {'$eq': 'test2'}}], + ) + testc_blogs = Blog.objects(comments__comment_tags="test11111") + + assert testc_blogs.count() == 1 + + # update many + Blog.drop_collection() + + Blog.objects.create(tags=['test1', 'test2', 'test3', 'test_all']) + Blog.objects.create(tags=['test4', 'test5', 'test6', 'test_all']) + + Blog.objects().update(__raw__= + {'$set': {"tags.$[element]": 'test11111'}}, + array_filters=[{"element": {'$eq': 'test2'}}], + ) + testc_blogs = Blog.objects(tags="test11111") + + assert testc_blogs.count() == 1 + + Blog.objects().update(__raw__= + {'$set': {"tags.$[element]": 'test_all1234577'}}, + array_filters=[{"element": {'$eq': 'test_all'}}], + ) + testc_blogs = Blog.objects(tags="test_all1234577") + + assert testc_blogs.count() == 2 + def test_update_using_positional_operator(self): """Ensure that the list fields can be updated using the positional operator.""" From a81bc51264987b37b37d8cfa35d23820e792c2e1 Mon Sep 17 00:00:00 2001 From: Ido Shraga Date: Thu, 21 Sep 2023 13:50:56 +0300 Subject: [PATCH 02/12] pre commit --- mongoengine/queryset/base.py | 8 +++--- tests/queryset/test_queryset.py | 43 ++++++++++++++++----------------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/mongoengine/queryset/base.py b/mongoengine/queryset/base.py index 149c11b18..95bb2d6b9 100644 --- a/mongoengine/queryset/base.py +++ b/mongoengine/queryset/base.py @@ -567,8 +567,8 @@ def update( for u in update["__raw__"] ] else: - if 'array_filters' in update: - array_filters = update.pop('array_filters') + if "array_filters" in update: + array_filters = update.pop("array_filters") update = transform.update(queryset._document, **update) # If doing an atomic upsert on an inheritable class # then ensure we add _cls to the update operation @@ -584,7 +584,9 @@ def update( update_func = collection.update_one if multi: update_func = collection.update_many - result = update_func(query, update, upsert=upsert, array_filters=array_filters) + result = update_func( + query, update, upsert=upsert, array_filters=array_filters + ) if full_result: return result elif result.raw_result: diff --git a/tests/queryset/test_queryset.py b/tests/queryset/test_queryset.py index 0854aacf5..7a1649873 100644 --- a/tests/queryset/test_queryset.py +++ b/tests/queryset/test_queryset.py @@ -592,8 +592,7 @@ class Blog(Document): Blog.drop_collection() def test_update_array_filters(self): - """Ensure that updating by array_filters works. - """ + """Ensure that updating by array_filters works.""" class Comment(EmbeddedDocument): comment_tags = ListField(StringField()) @@ -605,12 +604,12 @@ class Blog(Document): Blog.drop_collection() # update one - Blog.objects.create(tags=['test1', 'test2', 'test3']) + Blog.objects.create(tags=["test1", "test2", "test3"]) - Blog.objects().update_one(__raw__= - {'$set': {"tags.$[element]": 'test11111'}}, - array_filters=[{"element": {'$eq': 'test2'}}], - ) + Blog.objects().update_one( + __raw__={"$set": {"tags.$[element]": "test11111"}}, + array_filters=[{"element": {"$eq": "test2"}}], + ) testc_blogs = Blog.objects(tags="test11111") assert testc_blogs.count() == 1 @@ -618,13 +617,13 @@ class Blog(Document): Blog.drop_collection() # update one inner list - comments = Comment(comment_tags=['test1', 'test2', 'test3']) + comments = Comment(comment_tags=["test1", "test2", "test3"]) Blog.objects.create(comments=comments) - Blog.objects().update_one(__raw__= - {'$set': {"comments.comment_tags.$[element]": 'test11111'}}, - array_filters=[{"element": {'$eq': 'test2'}}], - ) + Blog.objects().update_one( + __raw__={"$set": {"comments.comment_tags.$[element]": "test11111"}}, + array_filters=[{"element": {"$eq": "test2"}}], + ) testc_blogs = Blog.objects(comments__comment_tags="test11111") assert testc_blogs.count() == 1 @@ -632,21 +631,21 @@ class Blog(Document): # update many Blog.drop_collection() - Blog.objects.create(tags=['test1', 'test2', 'test3', 'test_all']) - Blog.objects.create(tags=['test4', 'test5', 'test6', 'test_all']) + Blog.objects.create(tags=["test1", "test2", "test3", "test_all"]) + Blog.objects.create(tags=["test4", "test5", "test6", "test_all"]) - Blog.objects().update(__raw__= - {'$set': {"tags.$[element]": 'test11111'}}, - array_filters=[{"element": {'$eq': 'test2'}}], - ) + Blog.objects().update( + __raw__={"$set": {"tags.$[element]": "test11111"}}, + array_filters=[{"element": {"$eq": "test2"}}], + ) testc_blogs = Blog.objects(tags="test11111") assert testc_blogs.count() == 1 - Blog.objects().update(__raw__= - {'$set': {"tags.$[element]": 'test_all1234577'}}, - array_filters=[{"element": {'$eq': 'test_all'}}], - ) + Blog.objects().update( + __raw__={"$set": {"tags.$[element]": "test_all1234577"}}, + array_filters=[{"element": {"$eq": "test_all"}}], + ) testc_blogs = Blog.objects(tags="test_all1234577") assert testc_blogs.count() == 2 From aacc333237bf338ecaa5a30d4de22ea077b55a82 Mon Sep 17 00:00:00 2001 From: Ido Shraga <35264146+idoshr@users.noreply.github.com> Date: Sat, 16 Dec 2023 19:52:59 +0200 Subject: [PATCH 03/12] Update querying.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastien Gérard --- docs/guide/querying.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/querying.rst b/docs/guide/querying.rst index 194e2a676..7a524093c 100644 --- a/docs/guide/querying.rst +++ b/docs/guide/querying.rst @@ -263,7 +263,7 @@ This is done by using ``__raw__`` keyword argument to the update method and prov # 'tags' field == ['test1', 'test2', 'test3'] Page.objects().update(__raw__= {'$set': {"tags.$[element]": 'test11111'}}, - array_filters=[{"element": {'$eq': 'test2'}}], + 'array_filters': [{"element": {'$eq': 'test2'}}], # 'tags' field == ['test1', 'test11111', 'test3'] From ee766bfdaabe4dfd8bc6f5cdccdfb8b57c02a079 Mon Sep 17 00:00:00 2001 From: Ido Shraga <35264146+idoshr@users.noreply.github.com> Date: Sat, 16 Dec 2023 19:53:23 +0200 Subject: [PATCH 04/12] Update querying.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastien Gérard --- docs/guide/querying.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/querying.rst b/docs/guide/querying.rst index 7a524093c..b0333caf7 100644 --- a/docs/guide/querying.rst +++ b/docs/guide/querying.rst @@ -260,7 +260,7 @@ This is done by using ``__raw__`` keyword argument to the update method and prov `Update with Array Operator `_ :: - # 'tags' field == ['test1', 'test2', 'test3'] + # assuming an initial 'tags' field == ['test1', 'test2', 'test3'] Page.objects().update(__raw__= {'$set': {"tags.$[element]": 'test11111'}}, 'array_filters': [{"element": {'$eq': 'test2'}}], From 71de2a796bc7d850b3bb3e8b375fc1fa7eb1a6af Mon Sep 17 00:00:00 2001 From: Ido Shraga <35264146+idoshr@users.noreply.github.com> Date: Sat, 16 Dec 2023 19:53:30 +0200 Subject: [PATCH 05/12] Update querying.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastien Gérard --- docs/guide/querying.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/querying.rst b/docs/guide/querying.rst index b0333caf7..cf9e41779 100644 --- a/docs/guide/querying.rst +++ b/docs/guide/querying.rst @@ -265,7 +265,7 @@ This is done by using ``__raw__`` keyword argument to the update method and prov {'$set': {"tags.$[element]": 'test11111'}}, 'array_filters': [{"element": {'$eq': 'test2'}}], - # 'tags' field == ['test1', 'test11111', 'test3'] + # updated 'tags' field == ['test1', 'test11111', 'test3'] ) From cd504a830f7808c92581e5ac14be1b1981b71725 Mon Sep 17 00:00:00 2001 From: Ido Shraga Date: Thu, 21 Sep 2023 13:48:27 +0300 Subject: [PATCH 06/12] array_filters --- docs/changelog.rst | 1 + docs/guide/querying.rst | 18 ++++++++++ mongoengine/queryset/base.py | 6 +++- tests/queryset/test_queryset.py | 60 +++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 2a724094b..1374229b2 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -11,6 +11,7 @@ Development - Add tests against MongoDB 6.0 and MongoDB 7.0 in the pipeline - Fix validate() not being called when inheritance is used in EmbeddedDocument and validate is overriden #2784 - Add support for readPreferenceTags in connection parameters #2644 +- Add option to user array_filters https://www.mongodb.com/docs/manual/reference/operator/update/positional-filtered/ Changes in 0.27.0 ================= diff --git a/docs/guide/querying.rst b/docs/guide/querying.rst index b9afb60e1..194e2a676 100644 --- a/docs/guide/querying.rst +++ b/docs/guide/querying.rst @@ -252,6 +252,24 @@ and provide the pipeline as a list .. versionadded:: 0.23.2 +Update with Array Operator +-------------------------------- +It is possible to update specific value in array by use array_filters (arrayFilters) operator. +This is done by using ``__raw__`` keyword argument to the update method and provide the arrayFilters as a list. + +`Update with Array Operator `_ +:: + + # 'tags' field == ['test1', 'test2', 'test3'] + Page.objects().update(__raw__= + {'$set': {"tags.$[element]": 'test11111'}}, + array_filters=[{"element": {'$eq': 'test2'}}], + + # 'tags' field == ['test1', 'test11111', 'test3'] + + ) + + Sorting/Ordering results ======================== It is possible to order the results by 1 or more keys using :meth:`~mongoengine.queryset.QuerySet.order_by`. diff --git a/mongoengine/queryset/base.py b/mongoengine/queryset/base.py index d33e7b1e3..149c11b18 100644 --- a/mongoengine/queryset/base.py +++ b/mongoengine/queryset/base.py @@ -530,6 +530,7 @@ def update( write_concern=None, read_concern=None, full_result=False, + array_filters=None, **update, ): """Perform an atomic update on the fields matched by the query. @@ -545,6 +546,7 @@ def update( :param read_concern: Override the read concern for the operation :param full_result: Return the associated ``pymongo.UpdateResult`` rather than just the number updated items + :param array_filters: A list of filters specifying which array elements an update should apply. :param update: Django-style update keyword arguments :returns the number of updated documents (unless ``full_result`` is True) @@ -565,6 +567,8 @@ def update( for u in update["__raw__"] ] else: + if 'array_filters' in update: + array_filters = update.pop('array_filters') update = transform.update(queryset._document, **update) # If doing an atomic upsert on an inheritable class # then ensure we add _cls to the update operation @@ -580,7 +584,7 @@ def update( update_func = collection.update_one if multi: update_func = collection.update_many - result = update_func(query, update, upsert=upsert) + result = update_func(query, update, upsert=upsert, array_filters=array_filters) if full_result: return result elif result.raw_result: diff --git a/tests/queryset/test_queryset.py b/tests/queryset/test_queryset.py index d1cae3415..0854aacf5 100644 --- a/tests/queryset/test_queryset.py +++ b/tests/queryset/test_queryset.py @@ -591,6 +591,66 @@ class Blog(Document): Blog.drop_collection() + def test_update_array_filters(self): + """Ensure that updating by array_filters works. + """ + + class Comment(EmbeddedDocument): + comment_tags = ListField(StringField()) + + class Blog(Document): + tags = ListField(StringField()) + comments = EmbeddedDocumentField(Comment) + + Blog.drop_collection() + + # update one + Blog.objects.create(tags=['test1', 'test2', 'test3']) + + Blog.objects().update_one(__raw__= + {'$set': {"tags.$[element]": 'test11111'}}, + array_filters=[{"element": {'$eq': 'test2'}}], + ) + testc_blogs = Blog.objects(tags="test11111") + + assert testc_blogs.count() == 1 + + Blog.drop_collection() + + # update one inner list + comments = Comment(comment_tags=['test1', 'test2', 'test3']) + Blog.objects.create(comments=comments) + + Blog.objects().update_one(__raw__= + {'$set': {"comments.comment_tags.$[element]": 'test11111'}}, + array_filters=[{"element": {'$eq': 'test2'}}], + ) + testc_blogs = Blog.objects(comments__comment_tags="test11111") + + assert testc_blogs.count() == 1 + + # update many + Blog.drop_collection() + + Blog.objects.create(tags=['test1', 'test2', 'test3', 'test_all']) + Blog.objects.create(tags=['test4', 'test5', 'test6', 'test_all']) + + Blog.objects().update(__raw__= + {'$set': {"tags.$[element]": 'test11111'}}, + array_filters=[{"element": {'$eq': 'test2'}}], + ) + testc_blogs = Blog.objects(tags="test11111") + + assert testc_blogs.count() == 1 + + Blog.objects().update(__raw__= + {'$set': {"tags.$[element]": 'test_all1234577'}}, + array_filters=[{"element": {'$eq': 'test_all'}}], + ) + testc_blogs = Blog.objects(tags="test_all1234577") + + assert testc_blogs.count() == 2 + def test_update_using_positional_operator(self): """Ensure that the list fields can be updated using the positional operator.""" From da15e8d3002684c8cf240b3d5a00cbc9d9d5b3ad Mon Sep 17 00:00:00 2001 From: Ido Shraga Date: Thu, 21 Sep 2023 13:50:56 +0300 Subject: [PATCH 07/12] pre commit --- mongoengine/queryset/base.py | 8 +++--- tests/queryset/test_queryset.py | 43 ++++++++++++++++----------------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/mongoengine/queryset/base.py b/mongoengine/queryset/base.py index 149c11b18..95bb2d6b9 100644 --- a/mongoengine/queryset/base.py +++ b/mongoengine/queryset/base.py @@ -567,8 +567,8 @@ def update( for u in update["__raw__"] ] else: - if 'array_filters' in update: - array_filters = update.pop('array_filters') + if "array_filters" in update: + array_filters = update.pop("array_filters") update = transform.update(queryset._document, **update) # If doing an atomic upsert on an inheritable class # then ensure we add _cls to the update operation @@ -584,7 +584,9 @@ def update( update_func = collection.update_one if multi: update_func = collection.update_many - result = update_func(query, update, upsert=upsert, array_filters=array_filters) + result = update_func( + query, update, upsert=upsert, array_filters=array_filters + ) if full_result: return result elif result.raw_result: diff --git a/tests/queryset/test_queryset.py b/tests/queryset/test_queryset.py index 0854aacf5..7a1649873 100644 --- a/tests/queryset/test_queryset.py +++ b/tests/queryset/test_queryset.py @@ -592,8 +592,7 @@ class Blog(Document): Blog.drop_collection() def test_update_array_filters(self): - """Ensure that updating by array_filters works. - """ + """Ensure that updating by array_filters works.""" class Comment(EmbeddedDocument): comment_tags = ListField(StringField()) @@ -605,12 +604,12 @@ class Blog(Document): Blog.drop_collection() # update one - Blog.objects.create(tags=['test1', 'test2', 'test3']) + Blog.objects.create(tags=["test1", "test2", "test3"]) - Blog.objects().update_one(__raw__= - {'$set': {"tags.$[element]": 'test11111'}}, - array_filters=[{"element": {'$eq': 'test2'}}], - ) + Blog.objects().update_one( + __raw__={"$set": {"tags.$[element]": "test11111"}}, + array_filters=[{"element": {"$eq": "test2"}}], + ) testc_blogs = Blog.objects(tags="test11111") assert testc_blogs.count() == 1 @@ -618,13 +617,13 @@ class Blog(Document): Blog.drop_collection() # update one inner list - comments = Comment(comment_tags=['test1', 'test2', 'test3']) + comments = Comment(comment_tags=["test1", "test2", "test3"]) Blog.objects.create(comments=comments) - Blog.objects().update_one(__raw__= - {'$set': {"comments.comment_tags.$[element]": 'test11111'}}, - array_filters=[{"element": {'$eq': 'test2'}}], - ) + Blog.objects().update_one( + __raw__={"$set": {"comments.comment_tags.$[element]": "test11111"}}, + array_filters=[{"element": {"$eq": "test2"}}], + ) testc_blogs = Blog.objects(comments__comment_tags="test11111") assert testc_blogs.count() == 1 @@ -632,21 +631,21 @@ class Blog(Document): # update many Blog.drop_collection() - Blog.objects.create(tags=['test1', 'test2', 'test3', 'test_all']) - Blog.objects.create(tags=['test4', 'test5', 'test6', 'test_all']) + Blog.objects.create(tags=["test1", "test2", "test3", "test_all"]) + Blog.objects.create(tags=["test4", "test5", "test6", "test_all"]) - Blog.objects().update(__raw__= - {'$set': {"tags.$[element]": 'test11111'}}, - array_filters=[{"element": {'$eq': 'test2'}}], - ) + Blog.objects().update( + __raw__={"$set": {"tags.$[element]": "test11111"}}, + array_filters=[{"element": {"$eq": "test2"}}], + ) testc_blogs = Blog.objects(tags="test11111") assert testc_blogs.count() == 1 - Blog.objects().update(__raw__= - {'$set': {"tags.$[element]": 'test_all1234577'}}, - array_filters=[{"element": {'$eq': 'test_all'}}], - ) + Blog.objects().update( + __raw__={"$set": {"tags.$[element]": "test_all1234577"}}, + array_filters=[{"element": {"$eq": "test_all"}}], + ) testc_blogs = Blog.objects(tags="test_all1234577") assert testc_blogs.count() == 2 From d2bf8fe6077e46765a52cc06587a7f925c618c1a Mon Sep 17 00:00:00 2001 From: Ido Shraga <35264146+idoshr@users.noreply.github.com> Date: Sat, 16 Dec 2023 19:52:59 +0200 Subject: [PATCH 08/12] Update querying.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastien Gérard --- docs/guide/querying.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/querying.rst b/docs/guide/querying.rst index 194e2a676..7a524093c 100644 --- a/docs/guide/querying.rst +++ b/docs/guide/querying.rst @@ -263,7 +263,7 @@ This is done by using ``__raw__`` keyword argument to the update method and prov # 'tags' field == ['test1', 'test2', 'test3'] Page.objects().update(__raw__= {'$set': {"tags.$[element]": 'test11111'}}, - array_filters=[{"element": {'$eq': 'test2'}}], + 'array_filters': [{"element": {'$eq': 'test2'}}], # 'tags' field == ['test1', 'test11111', 'test3'] From 3d35419b776508acc77ef25f62c31d7fee88113b Mon Sep 17 00:00:00 2001 From: Ido Shraga <35264146+idoshr@users.noreply.github.com> Date: Sat, 16 Dec 2023 19:53:23 +0200 Subject: [PATCH 09/12] Update querying.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastien Gérard --- docs/guide/querying.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/querying.rst b/docs/guide/querying.rst index 7a524093c..b0333caf7 100644 --- a/docs/guide/querying.rst +++ b/docs/guide/querying.rst @@ -260,7 +260,7 @@ This is done by using ``__raw__`` keyword argument to the update method and prov `Update with Array Operator `_ :: - # 'tags' field == ['test1', 'test2', 'test3'] + # assuming an initial 'tags' field == ['test1', 'test2', 'test3'] Page.objects().update(__raw__= {'$set': {"tags.$[element]": 'test11111'}}, 'array_filters': [{"element": {'$eq': 'test2'}}], From d6cc0b94917722d0e5c7c474f04ae0e109719638 Mon Sep 17 00:00:00 2001 From: Ido Shraga <35264146+idoshr@users.noreply.github.com> Date: Sat, 16 Dec 2023 19:53:30 +0200 Subject: [PATCH 10/12] Update querying.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastien Gérard --- docs/guide/querying.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/querying.rst b/docs/guide/querying.rst index b0333caf7..cf9e41779 100644 --- a/docs/guide/querying.rst +++ b/docs/guide/querying.rst @@ -265,7 +265,7 @@ This is done by using ``__raw__`` keyword argument to the update method and prov {'$set': {"tags.$[element]": 'test11111'}}, 'array_filters': [{"element": {'$eq': 'test2'}}], - # 'tags' field == ['test1', 'test11111', 'test3'] + # updated 'tags' field == ['test1', 'test11111', 'test3'] ) From 0b69e8316170b0ef7d9d9aa88bd796e86d618837 Mon Sep 17 00:00:00 2001 From: Ido Shraga Date: Sat, 6 Jan 2024 10:48:07 +0200 Subject: [PATCH 11/12] CR --- docs/changelog.rst | 2 +- docs/guide/querying.rst | 5 ++--- mongoengine/queryset/base.py | 4 +--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index f9fff416e..42e325285 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -8,7 +8,7 @@ Development =========== - (Fill this out as you fix issues and develop your features). - Fix for uuidRepresentation not read when provided in URI #2741 -- Add option to user array_filters https://www.mongodb.com/docs/manual/reference/operator/update/positional-filtered/ +- Add option to user array_filters https://www.mongodb.com/docs/manual/reference/operator/update/positional-filtered/ #2769 - Fix combination of __raw__ and mongoengine syntax #2773 - Add tests against MongoDB 6.0 and MongoDB 7.0 in the pipeline - Fix validate() not being called when inheritance is used in EmbeddedDocument and validate is overriden #2784 diff --git a/docs/guide/querying.rst b/docs/guide/querying.rst index 0d791e8f2..d5ac70b07 100644 --- a/docs/guide/querying.rst +++ b/docs/guide/querying.rst @@ -261,9 +261,8 @@ This is done by using ``__raw__`` keyword argument to the update method and prov :: # assuming an initial 'tags' field == ['test1', 'test2', 'test3'] - Page.objects().update(__raw__= - {'$set': {"tags.$[element]": 'test11111'}}, - 'array_filters': [{"element": {'$eq': 'test2'}}], + Page.objects().update(__raw__={'$set': {"tags.$[element]": 'test11111'}}, + array_filters=[{"element": {'$eq': 'test2'}}], # updated 'tags' field == ['test1', 'test11111', 'test3'] diff --git a/mongoengine/queryset/base.py b/mongoengine/queryset/base.py index 1ea189960..e91eef9b9 100644 --- a/mongoengine/queryset/base.py +++ b/mongoengine/queryset/base.py @@ -562,14 +562,12 @@ def update( queryset = self.clone() query = queryset._query - if "__raw__" in update and isinstance(update["__raw__"], list): + if "__raw__" in update and isinstance(update["__raw__"], list): # Case of Update with Aggregation Pipeline update = [ transform.update(queryset._document, **{"__raw__": u}) for u in update["__raw__"] ] else: - if "array_filters" in update: - array_filters = update.pop("array_filters") update = transform.update(queryset._document, **update) # If doing an atomic upsert on an inheritable class # then ensure we add _cls to the update operation From 70636a2b4eaf10b3b4e597ef8f9ddb90282554f3 Mon Sep 17 00:00:00 2001 From: Ido Shraga Date: Sat, 6 Jan 2024 14:49:26 +0200 Subject: [PATCH 12/12] pre commit --- mongoengine/queryset/base.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mongoengine/queryset/base.py b/mongoengine/queryset/base.py index e91eef9b9..e0fb9cb26 100644 --- a/mongoengine/queryset/base.py +++ b/mongoengine/queryset/base.py @@ -562,7 +562,9 @@ def update( queryset = self.clone() query = queryset._query - if "__raw__" in update and isinstance(update["__raw__"], list): # Case of Update with Aggregation Pipeline + if "__raw__" in update and isinstance( + update["__raw__"], list + ): # Case of Update with Aggregation Pipeline update = [ transform.update(queryset._document, **{"__raw__": u}) for u in update["__raw__"]