fix(infinity): parent_kwd incorrectly split as keyword list causing orphaned clusters (#17475)

…rphaned clusters

### Summary

**Problem**
When deleting a document from the knowledge base, the parent cluster
could never be located and was therefore never cleaned up, leaving
orphaned clusters in Infinity indefinitely.

**Root Cause**
InfinityConnection.field_keyword() treats all _kwd-suffixed columns as
keyword lists and applies .split("###") to them in get_fields().
parent_kwd was missing from the exclusion list. This caused a parent
cluster name like "Toronto Transit & Authority Control 5e8d5eb6" to
become ['Toronto Transit & Authority Control 5e8d5eb6'] (a
single-element list). When that list was fed into _nav_cluster_id(), it
produced a different hash than the actual cluster's hash (computed from
the plain string), so every deletion-time cluster lookup silently
failed.

**Fix**
Added "parent_kwd" to the exclusion list in field_keyword(), alongside
docnm_kwd, important_kwd, question_kwd, etc.
This commit is contained in:
qinling0210
2026-07-28 15:26:40 +08:00
committed by GitHub
parent 19b60132da
commit ad2102c1a8

View File

@@ -72,11 +72,11 @@ class InfinityConnection(InfinityConnectionBase):
@staticmethod
def field_keyword(field_name: str):
# Treat "*_kwd" tag-like columns as keyword lists except knowledge_graph_kwd; source_id is also keyword-like.
# Treat "*_kwd" tag-like columns as keyword lists except for the fields in the exclusion list; source_id is also keyword-like.
# source_doc_ids / source_chunk_ids are multi-valued provenance lists (artifact/wiki rows) and must be
# stored/read/updated as keyword lists so the delete-time ref-count (remove one id, drop row when empty) works.
if field_name in ("source_id", "source_doc_ids", "source_chunk_ids") or (
field_name.endswith("_kwd") and field_name not in ["knowledge_graph_kwd", "docnm_kwd", "important_kwd", "question_kwd"]
field_name.endswith("_kwd") and field_name not in ["knowledge_graph_kwd", "docnm_kwd", "important_kwd", "question_kwd", "parent_kwd"]
):
return True
return False