diff --git a/app/frontend/ui_graph_service.py b/app/frontend/ui_graph_service.py index e5dbfb0..1aeeaba 100644 --- a/app/frontend/ui_graph_service.py +++ b/app/frontend/ui_graph_service.py @@ -246,23 +246,44 @@ class GraphExplorerService: extended_filter = models.Filter( must=[models.FieldCondition(key="kind", match=models.MatchExcept(**{"except": SYSTEM_EDGES}))] ) - # Limit: Balance zwischen Vollständigkeit und Performance - # Bei großen Graphen könnte dies langsam sein, aber notwendig für vollständige Ergebnisse - res_extended, _ = self.client.scroll(self.edges_col, scroll_filter=extended_filter, limit=10000, with_payload=True) + # WICHTIG: Wir müssen genug Kanten laden, um alle "Titel#Abschnitt" Varianten zu finden + # Verwende paginierte Suche, um sicherzustellen, dass wir alle Kanten durchsuchen + res_extended = [] + next_offset = None + max_iterations = 20 # Maximal 20 Iterationen (20 * 5000 = 100000 Kanten) + iteration = 0 + while iteration < max_iterations: + batch, next_offset = self.client.scroll( + self.edges_col, + scroll_filter=extended_filter, + limit=5000, + offset=next_offset, + with_payload=True + ) + if batch: + res_extended.extend(batch) + if next_offset is None or not batch: + break + iteration += 1 # Clientseitige Filterung: Finde Kanten, deren target_id mit einem unserer Titel beginnt + # WICHTIG: target_id ist der vollständige Wikilink-Text, z.B. "Meine Prinzipien 2025#P3 – Disziplin" + matched_count = 0 for edge in res_extended: tgt_id = edge.payload.get("target_id", "") - if tgt_id and edge.id not in existing_edge_ids: - # Prüfe, ob target_id mit einem unserer Titel beginnt - # target_id kann sein: "Titel", "Titel#Abschnitt", "Titel#Abschnitt (Details)" - for title in note_titles_to_search: - # Exakte Übereinstimmung ODER beginnt mit "Titel#" - # WICHTIG: startswith findet alle Varianten wie "Titel#P3 – Disziplin" - if tgt_id == title or tgt_id.startswith(title + "#"): - results.append(edge) - existing_edge_ids.add(edge.id) - break # Nur einmal hinzufügen, auch wenn mehrere Titel passen + if not tgt_id or edge.id in existing_edge_ids: + continue + + # Prüfe, ob target_id mit einem unserer Titel beginnt + # target_id kann sein: "Titel", "Titel#Abschnitt", "Titel#Abschnitt (Details)" + for title in note_titles_to_search: + # Exakte Übereinstimmung ODER beginnt mit "Titel#" + # WICHTIG: startswith findet alle Varianten wie "Titel#P3 – Disziplin" + if tgt_id == title or tgt_id.startswith(title + "#"): + results.append(edge) + existing_edge_ids.add(edge.id) + matched_count += 1 + break # Nur einmal hinzufügen, auch wenn mehrere Titel passen return results diff --git a/tests/debug_edge_search.py b/tests/debug_edge_search.py index 81a104b..c06ea5a 100644 --- a/tests/debug_edge_search.py +++ b/tests/debug_edge_search.py @@ -79,11 +79,12 @@ def find_edges_for_note(note_id: str, prefix: str = "mindnet"): # 4. Eingehende Kanten - Titel#Abschnitt Varianten print("🔍 EINGEHENDE KANTEN (target_id beginnt mit 'Titel#'):") if note_title: - # Lade alle Kanten und filtere clientseitig + # Lade alle Kanten und filtere clientseitig (wie Case D in ui_graph_service.py) all_filter = rest.Filter( must=[rest.FieldCondition(key="kind", match=rest.MatchExcept(**{"except": ["prev", "next", "belongs_to"]}))] ) - all_edges, _ = client.scroll(edges_col, scroll_filter=all_filter, limit=5000, with_payload=True) + all_edges, _ = client.scroll(edges_col, scroll_filter=all_filter, limit=10000, with_payload=True) + print(f" Gesamt geladen: {len(all_edges)} Kanten aus der Datenbank") # Clientseitige Filterung matched = [] @@ -100,6 +101,19 @@ def find_edges_for_note(note_id: str, prefix: str = "mindnet"): print(f" ... und {len(matched) - 10} weitere\n") else: print() + + # Zeige auch einige Beispiele von target_ids, die NICHT matchen + print(" 🔍 DEBUG: Beispiel target_ids die NICHT matchen (erste 10):") + non_matched = [] + for e in all_edges[:100]: # Nur erste 100 prüfen + tgt_id = e.payload.get("target_id", "") + if tgt_id and tgt_id != note_title and not tgt_id.startswith(note_title + "#"): + non_matched.append(tgt_id) + if len(non_matched) >= 10: + break + for i, tgt in enumerate(non_matched, 1): + print(f" {i}. '{tgt}'") + print() # 5. Zeige Beispiel target_ids aus der Datenbank print("📊 BEISPIEL target_ids aus der Datenbank (erste 20 mit #):")