From f313f0873b12269e59037bb153e432f1c8128fb7 Mon Sep 17 00:00:00 2001 From: Lars Date: Sun, 14 Dec 2025 14:50:06 +0100 Subject: [PATCH] ausgehende Kanten --- app/frontend/ui_graph.py | 5 ++-- app/frontend/ui_graph_service.py | 44 +++++++++++++++++--------------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/app/frontend/ui_graph.py b/app/frontend/ui_graph.py index 512e63d..e7920cc 100644 --- a/app/frontend/ui_graph.py +++ b/app/frontend/ui_graph.py @@ -14,6 +14,7 @@ def render_graph_explorer(graph_service): # Defaults für View & Physik setzen st.session_state.setdefault("graph_depth", 2) st.session_state.setdefault("graph_show_labels", True) + # Höhere Default-Werte für Abstand st.session_state.setdefault("graph_spacing", 250) st.session_state.setdefault("graph_gravity", -4000) @@ -78,7 +79,7 @@ def render_graph_explorer(graph_service): show_labels=st.session_state.graph_show_labels ) - # WICHTIG: Volle Daten inkl. Stitching für Editor holen + # WICHTIG: Daten für Editor holen (inkl. Pfad) note_data = graph_service.get_note_with_full_content(center_id) # Action Bar rendern @@ -122,7 +123,7 @@ def render_graph_explorer(graph_service): "solver": "barnesHut", "barnesHut": { "gravitationalConstant": st.session_state.graph_gravity, - "centralGravity": 0.005, + "centralGravity": 0.005, # Extrem wichtig für die Ausbreitung! "springLength": st.session_state.graph_spacing, "springConstant": 0.04, "damping": 0.09, diff --git a/app/frontend/ui_graph_service.py b/app/frontend/ui_graph_service.py index a32971a..01b8191 100644 --- a/app/frontend/ui_graph_service.py +++ b/app/frontend/ui_graph_service.py @@ -154,49 +154,53 @@ class GraphExplorerService: return previews def _find_connected_edges(self, note_ids, note_title=None): - """Findet eingehende und ausgehende Kanten für Nodes.""" + """Findet eingehende und ausgehende Kanten.""" results = [] - # 1. Chunk IDs ermitteln (da Edges oft an Chunks hängen) + # 1. OUTGOING EDGES (Der "Owner"-Fix) + # Wir suchen Kanten, die im Feld 'note_id' (Owner) eine unserer Notizen haben. + # Das findet ALLE ausgehenden Kanten, egal ob sie an einem Chunk oder der Note hängen. + if note_ids: + out_filter = models.Filter(must=[ + models.FieldCondition(key="note_id", match=models.MatchAny(any=note_ids)), + models.FieldCondition(key="kind", match=models.MatchExcept(**{"except": SYSTEM_EDGES})) + ]) + # Limit hoch, um alles zu finden + res_out, _ = self.client.scroll(self.edges_col, scroll_filter=out_filter, limit=500, with_payload=True) + results.extend(res_out) + + # 2. INCOMING EDGES (Ziel = Chunk ID oder Titel oder Note ID) + # Hier müssen wir Chunks auflösen, um Treffer auf Chunks zu finden. + + # Chunk IDs der aktuellen Notes holen chunk_ids = [] if note_ids: c_filter = models.Filter(must=[models.FieldCondition(key="note_id", match=models.MatchAny(any=note_ids))]) chunks, _ = self.client.scroll(self.chunks_col, scroll_filter=c_filter, limit=300) chunk_ids = [c.id for c in chunks] - - # 2. Outgoing Edges suchen - # Source kann sein: Eine Chunk ID ODER die Note ID selbst (bei direkten Links) - source_candidates = chunk_ids + note_ids - - if source_candidates: - out_f = models.Filter(must=[ - models.FieldCondition(key="source_id", match=models.MatchAny(any=source_candidates)), - # FIX: MatchExcept Workaround für Pydantic - models.FieldCondition(key="kind", match=models.MatchExcept(**{"except": SYSTEM_EDGES})) - ]) - res_out, _ = self.client.scroll(self.edges_col, scroll_filter=out_f, limit=500, with_payload=True) - results.extend(res_out) - # 3. Incoming Edges suchen - # Target kann sein: Chunk ID, Note ID, oder Note Titel (Wikilinks) shoulds = [] + # Case A: Edge zeigt auf einen unserer Chunks if chunk_ids: shoulds.append(models.FieldCondition(key="target_id", match=models.MatchAny(any=chunk_ids))) + # Case B: Edge zeigt direkt auf unsere Note ID if note_ids: shoulds.append(models.FieldCondition(key="target_id", match=models.MatchAny(any=note_ids))) + # Case C: Edge zeigt auf unseren Titel (Wikilinks) if note_title: shoulds.append(models.FieldCondition(key="target_id", match=models.MatchValue(value=note_title))) if shoulds: - in_f = models.Filter( + in_filter = models.Filter( must=[models.FieldCondition(key="kind", match=models.MatchExcept(**{"except": SYSTEM_EDGES}))], should=shoulds ) - res_in, _ = self.client.scroll(self.edges_col, scroll_filter=in_f, limit=500, with_payload=True) - results.extend(res_in) + res_in, _ = self.client.scroll(self.edges_col, scroll_filter=in_filter, limit=500, with_payload=True) + results.extend(res_in) + return results def _find_connected_edges_batch(self, note_ids):