add bulk delete (#837)

* add bulk delete

* Update graphiti_core/edges.py

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

* Update graphiti_core/edges.py

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

* Update graphiti_core/edges.py

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

---------

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
This commit is contained in:
Preston Rasmussen 2025-08-15 12:15:07 -04:00 committed by GitHub
parent 0a5000af7b
commit 1278f877d8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 49 additions and 10 deletions

View file

@ -64,6 +64,21 @@ class Edge(BaseModel, ABC):
return result
@classmethod
async def delete_by_uuids(cls, driver: GraphDriver, uuids: list[str]):
result = await driver.execute_query(
"""
MATCH (n)-[e:MENTIONS|RELATES_TO|HAS_MEMBER]->(m)
WHERE e.uuid IN $uuids
DELETE e
""",
uuids=uuids,
)
logger.debug(f'Deleted Edges: {uuids}')
return result
def __hash__(self):
return hash(self.uuid)

View file

@ -28,6 +28,7 @@ from graphiti_core.driver.driver import GraphDriver
from graphiti_core.driver.neo4j_driver import Neo4jDriver
from graphiti_core.edges import (
CommunityEdge,
Edge,
EntityEdge,
EpisodicEdge,
create_entity_edge_embeddings,
@ -46,6 +47,7 @@ from graphiti_core.nodes import (
EntityNode,
EpisodeType,
EpisodicNode,
Node,
create_entity_node_embeddings,
)
from graphiti_core.search.search import SearchConfig, search
@ -1066,12 +1068,7 @@ class Graphiti:
if record['episode_count'] == 1:
nodes_to_delete.append(node)
await semaphore_gather(
*[node.delete(self.driver) for node in nodes_to_delete],
max_coroutines=self.max_coroutines,
)
await semaphore_gather(
*[edge.delete(self.driver) for edge in edges_to_delete],
max_coroutines=self.max_coroutines,
)
await Node.delete_by_uuids(self.driver, [node.uuid for node in nodes_to_delete])
await Edge.delete_by_uuids(self.driver, [edge.uuid for edge in edges_to_delete])
await episode.delete(self.driver)

View file

@ -142,6 +142,33 @@ class Node(BaseModel, ABC):
batch_size=batch_size,
)
@classmethod
async def delete_by_uuids(cls, driver: GraphDriver, uuids: list[str], batch_size: int = 100):
if driver.provider == GraphProvider.FALKORDB:
for label in ['Entity', 'Episodic', 'Community']:
await driver.execute_query(
f"""
MATCH (n:{label})
WHERE n.uuid IN $uuids
DETACH DELETE n
""",
uuids=uuids,
)
else:
async with driver.session() as session:
await session.run(
"""
MATCH (n:Entity|Episodic|Community)
WHERE n.uuid IN $uuids
CALL {
WITH n
DETACH DELETE n
} IN TRANSACTIONS OF $batch_size ROWS
""",
uuids=uuids,
batch_size=batch_size,
)
@classmethod
async def get_by_uuid(cls, driver: GraphDriver, uuid: str): ...

View file

@ -1,7 +1,7 @@
[project]
name = "graphiti-core"
description = "A temporal graph building library"
version = "0.18.6"
version = "0.18.7"
authors = [
{ name = "Paul Paliychuk", email = "paul@getzep.com" },
{ name = "Preston Rasmussen", email = "preston@getzep.com" },

2
uv.lock generated
View file

@ -746,7 +746,7 @@ wheels = [
[[package]]
name = "graphiti-core"
version = "0.18.6"
version = "0.18.7"
source = { editable = "." }
dependencies = [
{ name = "diskcache" },