Skip to content

Commit 666698d

Browse files
authored
update delete from cypher to delete (#737)
1 parent d65e70d commit 666698d

File tree

1 file changed

+38
-43
lines changed

1 file changed

+38
-43
lines changed

src/memos/graph_dbs/polardb.py

Lines changed: 38 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4792,35 +4792,35 @@ def delete_node_by_prams(
47924792
# Build user_name condition from writable_cube_ids (OR relationship - match any cube_id)
47934793
user_name_conditions = []
47944794
for cube_id in writable_cube_ids:
4795-
# Escape single quotes in cube IDs
4796-
escaped_cube_id = str(cube_id).replace("'", "\\'")
4797-
user_name_conditions.append(f"n.user_name = '{escaped_cube_id}'")
4795+
# Use agtype_access_operator with VARIADIC ARRAY format for consistency
4796+
user_name_conditions.append(
4797+
f"agtype_access_operator(VARIADIC ARRAY[properties, '\"user_name\"'::agtype]) = '\"{cube_id}\"'::agtype"
4798+
)
47984799

47994800
# Build WHERE conditions separately for memory_ids and file_ids
48004801
where_conditions = []
48014802

4802-
# Handle memory_ids: query n.id
4803+
# Handle memory_ids: query properties.id
48034804
if memory_ids and len(memory_ids) > 0:
48044805
memory_id_conditions = []
48054806
for node_id in memory_ids:
4806-
# Escape single quotes in node IDs
4807-
escaped_id = str(node_id).replace("'", "\\'")
4808-
memory_id_conditions.append(f"'{escaped_id}'")
4807+
memory_id_conditions.append(
4808+
f"ag_catalog.agtype_access_operator(properties, '\"id\"'::agtype) = '\"{node_id}\"'::agtype"
4809+
)
48094810
if memory_id_conditions:
4810-
where_conditions.append(f"n.id IN [{', '.join(memory_id_conditions)}]")
4811+
where_conditions.append(f"({' OR '.join(memory_id_conditions)})")
48114812

4812-
# Handle file_ids: query n.file_ids field
4813-
# All file_ids must be present in the array field (AND relationship)
4813+
# Check if any file_id is in the file_ids array field (OR relationship)
48144814
if file_ids and len(file_ids) > 0:
4815-
file_id_and_conditions = []
4815+
file_id_conditions = []
48164816
for file_id in file_ids:
4817-
# Escape single quotes in file IDs
4818-
escaped_id = str(file_id).replace("'", "\\'")
4819-
# Check if this file_id is in the file_ids array field
4820-
file_id_and_conditions.append(f"'{escaped_id}' IN n.file_ids")
4821-
if file_id_and_conditions:
4822-
# Use AND to require all file_ids to be present
4823-
where_conditions.append(f"({' OR '.join(file_id_and_conditions)})")
4817+
# Format: agtype_in_operator(agtype_access_operator(VARIADIC ARRAY[properties, '"file_ids"'::agtype]), '"file_id"'::agtype)
4818+
file_id_conditions.append(
4819+
f"agtype_in_operator(agtype_access_operator(VARIADIC ARRAY[properties, '\"file_ids\"'::agtype]), '\"{file_id}\"'::agtype)"
4820+
)
4821+
if file_id_conditions:
4822+
# Use OR to match any file_id in the array
4823+
where_conditions.append(f"({' OR '.join(file_id_conditions)})")
48244824

48254825
# Query nodes by filter if provided
48264826
filter_ids = set()
@@ -4846,11 +4846,11 @@ def delete_node_by_prams(
48464846
if filter_ids:
48474847
filter_id_conditions = []
48484848
for node_id in filter_ids:
4849-
# Escape single quotes in node IDs
4850-
escaped_id = str(node_id).replace("'", "\\'")
4851-
filter_id_conditions.append(f"'{escaped_id}'")
4849+
filter_id_conditions.append(
4850+
f"ag_catalog.agtype_access_operator(properties, '\"id\"'::agtype) = '\"{node_id}\"'::agtype"
4851+
)
48524852
if filter_id_conditions:
4853-
where_conditions.append(f"n.id IN [{', '.join(filter_id_conditions)}]")
4853+
where_conditions.append(f"({' OR '.join(filter_id_conditions)})")
48544854

48554855
# If no conditions (except user_name), return 0
48564856
if not where_conditions:
@@ -4865,26 +4865,21 @@ def delete_node_by_prams(
48654865

48664866
# Then, combine with user_name condition using AND (must match user_name AND one of the data conditions)
48674867
user_name_where = " OR ".join(user_name_conditions)
4868-
ids_where = f"{user_name_where} AND ({data_conditions})"
4868+
where_clause = f"({user_name_where}) AND ({data_conditions})"
48694869

4870-
# Use Cypher DELETE query
4870+
# Use SQL DELETE query for better performance
48714871
# First count matching nodes to get accurate count
48724872
count_query = f"""
4873-
SELECT * FROM cypher('{self.db_name}_graph', $$
4874-
MATCH (n:Memory)
4875-
WHERE {ids_where}
4876-
RETURN count(n) AS node_count
4877-
$$) AS (node_count agtype)
4873+
SELECT COUNT(*)
4874+
FROM "{self.db_name}_graph"."Memory"
4875+
WHERE {where_clause}
48784876
"""
48794877
logger.info(f"[delete_node_by_prams] count_query: {count_query}")
48804878

48814879
# Then delete nodes
48824880
delete_query = f"""
4883-
SELECT * FROM cypher('{self.db_name}_graph', $$
4884-
MATCH (n:Memory)
4885-
WHERE {ids_where}
4886-
DELETE n
4887-
$$) AS (result agtype)
4881+
DELETE FROM "{self.db_name}_graph"."Memory"
4882+
WHERE {where_clause}
48884883
"""
48894884

48904885
logger.info(
@@ -4899,20 +4894,20 @@ def delete_node_by_prams(
48994894
with conn.cursor() as cursor:
49004895
# Count nodes before deletion
49014896
cursor.execute(count_query)
4902-
count_results = cursor.fetchall()
4903-
expected_count = 0
4904-
if count_results and len(count_results) > 0:
4905-
count_str = str(count_results[0][0])
4906-
count_str = count_str.strip('"').strip("'")
4907-
expected_count = int(count_str) if count_str.isdigit() else 0
4897+
count_result = cursor.fetchone()
4898+
expected_count = count_result[0] if count_result else 0
4899+
4900+
logger.info(
4901+
f"[delete_node_by_prams] Found {expected_count} nodes matching the criteria"
4902+
)
49084903

49094904
# Delete nodes
49104905
cursor.execute(delete_query)
4911-
# Use the count from before deletion as the actual deleted count
4912-
deleted_count = expected_count
4906+
# Use rowcount to get actual deleted count
4907+
deleted_count = cursor.rowcount
49134908
elapsed_time = time.time() - batch_start_time
49144909
logger.info(
4915-
f"[delete_node_by_prams] execute_values completed successfully in {elapsed_time:.2f}s"
4910+
f"[delete_node_by_prams] Deletion completed successfully in {elapsed_time:.2f}s, deleted {deleted_count} nodes"
49164911
)
49174912
except Exception as e:
49184913
logger.error(f"[delete_node_by_prams] Failed to delete nodes: {e}", exc_info=True)

0 commit comments

Comments
 (0)