From aa9d38833722fa5b1c232b7815968396adc81e05 Mon Sep 17 00:00:00 2001 From: Lars Date: Sun, 28 Dec 2025 11:54:44 +0100 Subject: [PATCH] ui_update --- app/frontend/ui_graph_service.py | 51 ++++++++++++++++---------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/app/frontend/ui_graph_service.py b/app/frontend/ui_graph_service.py index b62b572..17f7fc2 100644 --- a/app/frontend/ui_graph_service.py +++ b/app/frontend/ui_graph_service.py @@ -258,6 +258,24 @@ class GraphExplorerService: # WICHTIG: Diese Suche ist nur für eingehende Kanten relevant # Für ausgehende Kanten werden alle über note_id gefunden, unabhängig vom target_id Format if note_titles_to_search: + # Normalisierungs-Funktion (außerhalb der Schleife für Performance) + def normalize_title(t): + if not t: + return "" + # Entferne Klammern und deren Inhalt (z.B. "(2025–2029)") + t = re.sub(r'\s*\([^)]*\)', '', t) + # Entferne Jahreszahlen (4-stellig, mit oder ohne Bindestrich/En-Dash) + # Beispiele: "2025", "2025–2029", "2025-2029" + t = re.sub(r'\s*\d{4}[\s–\-]*\d{0,4}', '', t) + # Entferne "Mein/Meine" Präfixe + t = re.sub(r'^(Mein|Meine)\s+', '', t, flags=re.IGNORECASE) + # Normalisiere Whitespace + t = re.sub(r'\s+', ' ', t).strip() + return t.lower() # Case-insensitive Vergleich + + # Normalisiere alle Note-Titel VORHER (Performance-Optimierung) + note_titles_normalized = {title: normalize_title(title) for title in note_titles_to_search} + # Erweiterte Suche: Lade alle relevanten Kanten und filtere clientseitig # Da target_id KEYWORD ist (nicht TEXT), können wir keine Präfix-Suche direkt machen # STRATEGIE: Lade alle Kanten (mit Limit) und filtere clientseitig nach target_id.startswith(title + "#") @@ -271,7 +289,6 @@ class GraphExplorerService: ) # WICHTIG: Wir müssen genug Kanten laden, um alle "Titel#Abschnitt" Varianten zu finden # Verwende paginierte Suche, um sicherzustellen, dass wir alle Kanten durchsuchen - # OPTIMIERUNG: Lade alle Kanten in einem Durchgang (falls möglich) res_extended = [] next_offset = None max_iterations = 50 # Maximal 50 Iterationen (50 * 5000 = 250000 Kanten) @@ -298,8 +315,8 @@ class GraphExplorerService: 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)" + # Prüfe, ob target_id mit einem unserer Titel beginnt (exakte Matches) + matched_exact = False for title in note_titles_to_search: # Exakte Übereinstimmung ODER beginnt mit "Titel#" # WICHTIG: startswith findet alle Varianten wie "Titel#P3 – Disziplin" @@ -307,39 +324,21 @@ class GraphExplorerService: results.append(edge) existing_edge_ids.add(edge.id) matched_count += 1 + matched_exact = True break # Nur einmal hinzufügen, auch wenn mehrere Titel passen - # ZUSÄTZLICH: Fuzzy-Matching für ähnliche Titel + # ZUSÄTZLICH: Fuzzy-Matching für ähnliche Titel (nur wenn kein exakter Match) # PROBLEM: Wikilinks können andere Titel verwenden als der gespeicherte Note-Titel # Beispiel: Note-Titel = "Persönliches Leitbild (2025–2029)", aber Wikilink = "Mein Persönliches Leitbild 2025" # STRATEGIE: Da target_id immer "Titel#Abschnitt" ist, nehmen wir einfach den Teil vor dem # # und normalisieren beide (Note-Titel und target_id-Basis) für Vergleich - if not any(tgt_id == t or tgt_id.startswith(t + "#") for t in note_titles_to_search): + if not matched_exact: # Extrahiere Basis-Titel aus target_id (Teil vor dem #) tgt_base = tgt_id.split("#")[0].strip() - - # Normalisierungs-Funktion: Entferne Klammern, Jahreszahlen, Präfixe - def normalize_title(t): - if not t: - return "" - # Entferne Klammern und deren Inhalt (z.B. "(2025–2029)") - t = re.sub(r'\s*\([^)]*\)', '', t) - # Entferne Jahreszahlen (4-stellig, mit oder ohne Bindestrich/En-Dash) - # Beispiele: "2025", "2025–2029", "2025-2029" - t = re.sub(r'\s*\d{4}[\s–\-]*\d{0,4}', '', t) - # Entferne "Mein/Meine" Präfixe - t = re.sub(r'^(Mein|Meine)\s+', '', t, flags=re.IGNORECASE) - # Normalisiere Whitespace - t = re.sub(r'\s+', ' ', t).strip() - return t.lower() # Case-insensitive Vergleich - - # Normalisiere target_id-Basis tgt_norm = normalize_title(tgt_base) - # Prüfe gegen alle Note-Titel (inkl. Aliases) - for title in note_titles_to_search: - title_norm = normalize_title(title) - + # Prüfe gegen alle normalisierten Note-Titel (inkl. Aliases) + for title, title_norm in note_titles_normalized.items(): # Prüfe auf Ähnlichkeit: Exakt gleich oder einer beginnt mit dem anderen if title_norm and tgt_norm and len(title_norm) > 5: if (title_norm == tgt_norm or