@@ -1164,6 +1164,79 @@ def response_handler(resp: Response) -> Cursor:
11641164
11651165 return await self ._executor .execute (request , response_handler )
11661166
1167+ async def update_match (
1168+ self ,
1169+ filters : Json ,
1170+ body : T ,
1171+ limit : Optional [int | str ] = None ,
1172+ keep_none : Optional [bool ] = None ,
1173+ wait_for_sync : Optional [bool ] = None ,
1174+ merge_objects : Optional [bool ] = None ,
1175+ allow_dirty_read : Optional [bool ] = None ,
1176+ ) -> Result [int ]:
1177+ """Update matching documents.
1178+
1179+ Args:
1180+ filters (dict | None): Query filters.
1181+ body (dict): Full or partial document body with the updates.
1182+ limit (int | str | None): Maximum number of documents to return.
1183+ keep_none (bool | None): If set to `True`, fields with value `None` are
1184+ retained in the document. Otherwise, they are removed completely.
1185+ wait_for_sync (bool | None): Wait until operation has been synced to disk.
1186+ merge_objects (bool | None): If set to `True`, sub-dictionaries are merged
1187+ instead of the new one overwriting the old one.
1188+ allow_dirty_read (bool | None): Allow reads from followers in a cluster.
1189+
1190+ Returns:
1191+ int: Number of documents updated.
1192+
1193+ Raises:
1194+ DocumentUpdateError: If update fails.
1195+ """
1196+ if not self ._is_none_or_dict (filters ):
1197+ raise ValueError ("filters parameter must be a dict" )
1198+ if not (self ._is_none_or_int (limit ) or limit == "null" ):
1199+ raise ValueError ("limit parameter must be a non-negative int" )
1200+
1201+ # If the waitForSync parameter is not specified or set to false,
1202+ # then the collection’s default waitForSync behavior is applied.
1203+ sync = f", waitForSync: { wait_for_sync } " if wait_for_sync is not None else ""
1204+ query = f"""
1205+ FOR doc IN @@collection
1206+ { self ._build_filter_conditions (filters )}
1207+ { f"LIMIT { limit } " if limit is not None else "" }
1208+ UPDATE doc WITH @body IN @@collection
1209+ OPTIONS {{ keepNull: @keep_none, mergeObjects: @merge { sync } }}
1210+ """ # noqa: E201 E202
1211+ bind_vars = {
1212+ "@collection" : self .name ,
1213+ "body" : body ,
1214+ "keep_none" : keep_none ,
1215+ "merge" : merge_objects ,
1216+ }
1217+ data = {"query" : query , "bindVars" : bind_vars }
1218+ headers : RequestHeaders = {}
1219+ if allow_dirty_read is not None :
1220+ if allow_dirty_read is True :
1221+ headers ["x-arango-allow-dirty-read" ] = "true"
1222+ else :
1223+ headers ["x-arango-allow-dirty-read" ] = "false"
1224+
1225+ request = Request (
1226+ method = Method .POST ,
1227+ endpoint = "/_api/cursor" ,
1228+ data = self .serializer .dumps (data ),
1229+ headers = headers ,
1230+ )
1231+
1232+ def response_handler (resp : Response ) -> int :
1233+ if resp .is_success :
1234+ result = self .deserializer .loads (resp .raw_body )
1235+ return cast (int , result ["extra" ]["stats" ]["writesExecuted" ])
1236+ raise DocumentUpdateError (resp , request )
1237+
1238+ return await self ._executor .execute (request , response_handler )
1239+
11671240 async def insert_many (
11681241 self ,
11691242 documents : Sequence [T ],
0 commit comments