async def delete_documents_and_chunks_by_filter(
        self,
        filters: dict[str, Any],
    ):
        """Delete chunks matching the given filters. If any documents are now
        empty (i.e., have no remaining chunks), delete those documents as well.

        Args:
            filters (dict[str, Any]): Filters specifying which chunks to delete.
            chunks_handler (PostgresChunksHandler): The handler for chunk operations.
            documents_handler (PostgresDocumentsHandler): The handler for document operations.
            graphs_handler: Handler for entity and relationship operations in the Graph.

        Returns:
            dict: A summary of what was deleted.
        """

        def transform_chunk_id_to_id(
            filters: dict[str, Any],
        ) -> dict[str, Any]:
            """Example transformation function if your filters use `chunk_id`
            instead of `id`.

            Recursively transform `chunk_id` to `id`.
            """
            if isinstance(filters, dict):
                transformed = {}
                for key, value in filters.items():
                    if key == "chunk_id":
                        transformed["id"] = value
                    elif key in ["$and", "$or"]:
                        transformed[key] = [
                            transform_chunk_id_to_id(item) for item in value
                        ]
                    else:
                        transformed[key] = transform_chunk_id_to_id(value)
                return transformed
            return filters

        # Transform filters if needed.
        transformed_filters = transform_chunk_id_to_id(filters)

        # Find chunks that match the filters before deleting
        interim_results = (
            await self.providers.database.chunks_handler.list_chunks(
                filters=transformed_filters,
                offset=0,
                limit=1_000,
                include_vectors=False,
            )
        )

        results = interim_results["results"]
        while interim_results["total_entries"] == 1_000:
            # If we hit the limit, we need to paginate to get all results

            interim_results = (
                await self.providers.database.chunks_handler.list_chunks(
                    filters=transformed_filters,
                    offset=interim_results["offset"] + 1_000,
                    limit=1_000,
                    include_vectors=False,
                )
            )
            results.extend(interim_results["results"])

        document_ids = set()
        owner_id = None

        if "$and" in filters:
            for condition in filters["$and"]:
                if "owner_id" in condition and "$eq" in condition["owner_id"]:
                    owner_id = condition["owner_id"]["$eq"]
                elif (
                    "document_id" in condition
                    and "$eq" in condition["document_id"]
                ):
                    document_ids.add(UUID(condition["document_id"]["$eq"]))
        elif "document_id" in filters:
            doc_id = filters["document_id"]
            if isinstance(doc_id, str):
                document_ids.add(UUID(doc_id))
            elif isinstance(doc_id, UUID):
                document_ids.add(doc_id)
            elif isinstance(doc_id, dict) and "$eq" in doc_id:
                value = doc_id["$eq"]
                document_ids.add(
                    UUID(value) if isinstance(value, str) else value
                )

        # Delete matching chunks from the database
        delete_results = await self.providers.database.chunks_handler.delete(
            transformed_filters
        )

        # Extract the document_ids that were affected.
        affected_doc_ids = {
            UUID(info["document_id"])
            for info in delete_results.values()
            if info.get("document_id")
        }
        document_ids.update(affected_doc_ids)

        # Check if the document still has any chunks left
        docs_to_delete = []
        for doc_id in document_ids:
            documents_overview_response = await self.providers.database.documents_handler.get_documents_overview(
                offset=0, limit=1, filter_document_ids=[doc_id]
            )
            if not documents_overview_response["results"]:
                raise R2RException(
                    status_code=404, message="Document not found"
                )

            document = documents_overview_response["results"][0]

            for collection_id in document.collection_ids:
                await self.providers.database.collections_handler.decrement_collection_document_count(
                    collection_id=collection_id
                )

            if owner_id and str(document.owner_id) != owner_id:
                raise R2RException(
                    status_code=404,
                    message="Document not found or insufficient permissions",
                )
            docs_to_delete.append(doc_id)

        # Delete documents that no longer have associated chunks
        for doc_id in docs_to_delete:
            # Delete related entities & relationships if needed:
            await self.providers.database.graphs_handler.entities.delete(
                parent_id=doc_id,
                store_type=StoreType.DOCUMENTS,
            )
            await self.providers.database.graphs_handler.relationships.delete(
                parent_id=doc_id,
                store_type=StoreType.DOCUMENTS,
            )

            # Finally, delete the document from documents_overview:
            await self.providers.database.documents_handler.delete(
                document_id=doc_id
            )

        return {
            "success": True,
            "deleted_chunks_count": len(delete_results),
            "deleted_documents_count": len(docs_to_delete),
            "deleted_document_ids": [str(d) for d in docs_to_delete],
        }
Delete chunks matching the given filters. If any documents are now
        empty (i.e., have no remaining chunks), delete those documents as well.

        Args:
            filters (dict[str, Any]): Filters specifying which chunks to delete.
            chunks_handler (PostgresChunksHandler): The handler for chunk operations.
            documents_handler (PostgresDocumentsHandler): The handler for document operations.
            graphs_handler: Handler for entity and relationship operations in the Graph.

        Returns:
            dict: A summary of what was deleted.
        
py/core/main/services/management_service.py