Datalog-Patterns Cookbook··5 Rezepte für mium-Power-User
Kopierbare Queries, ehrliche Gotchas
- Du liest und parametrierst die fünf Cookbook-Queries für Deinen eigenen Vault. ·· Erfolgskriterium: Du passt Q-Fenster, Tag-Namespace und Limit in drei Rezepten korrekt an, ohne die Syntax zu brechen.
- Du benennst je Rezept die ehrliche Stelle, an der es nicht trägt, und ihre Voraussetzung. ·· Erfolgskriterium: Du ordnest fünf Gotchas (Datumsformat, Kanten-Zählung, History, Namespace, not-join-Kosten) fehlerfrei ihrem Rezept zu.
- Du entscheidest, wann eine Datalog-Query das falsche Mittel ist und ein anderer Weg zieht. ·· Erfolgskriterium: Du erkennst in fünf Fällen, ob Datalog, Volltext-Index oder Graph-View die richtige Antwort gibt.
Dieses Cookbook richtet sich an mium-Power-User und Dev-Profile, die mit [[advanced-query-datalog]] schon Berührung hatten und konkrete, kopierbare Beispiele suchen. Fünf Rezepte, jedes self-contained — wer nur den Orphan-Detektor braucht, springt direkt zu Rezept 5. Datalog selbst ist eine Logik-Programmiersprache aus den 1970ern; Rich Hickey hat sie mit Datomic (Cognitect, seit 2012) für den praktischen Datenbank-Alltag wiederentdeckt. mium nutzt einen Datalog-Dialekt für die Abfrage des eigenen Block-Index.
Rezepte
Die fünf Rezepte sind unabhängig voneinander. Cherry-pick, was Du brauchst, oder lies linear — beide Reihenfolgen funktionieren. Jedes Rezept hat: ein Problem, eine Query, optional eine Gotcha-Callout.
Rezept 1··Offene Tasks mit Frist im aktuellen Quartal
Standard-Sprint-Frage: welche Tasks sind offen und müssen bis zum Quartalsende geliefert sein? Die Query filtert über `frist::` im Q-Fenster und `status:: offen`, gibt Owner zurück.
[:find ?block ?frist ?owner
:where [?block :frist ?frist]
[?block :status "offen"]
[(>= ?frist "2026-04-01")]
[(<= ?frist "2026-06-30")]
[?block :owner ?owner]]Rezept 2··Top-10 Backlink-Hubs
Welche Blöcke werden am häufigsten referenziert? Die Top-10 nach eingehenden `:links-to`-Kanten sind die zentralen Knoten Deines Vaults — oft Begriffe, Personen, Projekte.
[:find (count ?backlink) ?target
:where [?backlink :links-to ?target]
:order-by [(count ?backlink) :desc]
:limit 10]Rezept 3··Audit-Trail eines Blocks
Wer hat wann was an einem Block geändert? Die Query liest die Transaction-History reverse für eine gegebene Block-ID und gibt `tx`, `attr`, `value`, `added`-Flag zurück.
[:find ?tx ?attr ?value ?added
:where [?block :db/id "<((uuid))>"]
[?tx :tx/affected-block ?block]
[?tx :tx/attr ?attr]
[?tx :tx/value ?value]
[?tx :tx/added ?added]]Rezept 4··Cross-Vault Tag-Aggregation
Wie häufig tritt jeder Kunden-Tag über alle Vaults hinweg auf? Die Query gruppiert über `tags::` mit Namespace-Präfix `#kunde-` und liefert eine sortierte Häufigkeitsliste.
[:find (count ?block) ?tag
:where [?block :tags ?tag]
[(re-pattern "^#kunde-") ?tag]
:group-by ?tag
:order-by [(count ?block) :desc]]Rezept 5··Orphan-Notiz-Detektor
Welche Notizen haben keine eingehenden Backlinks und sind nicht archiviert? Diese Orphans sind die toten Enden des Vaults — Kandidaten für Aufräumen, Verknüpfen oder Archivieren.
[:find ?block ?title
:where [?block :title ?title]
[?block :archiv? false]
(not-join [?block]
[?other :links-to ?block])]Wann diese Rezepte NICHT passen
Datalog-Queries sind kein Universalwerkzeug. Drei Situationen, in denen diese Rezepte nicht tragen:
- Volltext-Suche im Block-Inhalt — Datalog filtert über Properties und Kanten, nicht über Prosa. Für „finde alle Blöcke, die `Auftragsbestätigung` im Text enthalten“ ist der mium-Full-Text-Index das richtige Werkzeug, nicht eine Datalog-Query.
- Sehr unstrukturierte Vaults ohne Property-Disziplin — alle fünf Rezepte setzen voraus, dass `frist::`, `status::`, `owner::`, `tags::` konsistent gepflegt sind. In einem Vault, in dem 80 % der Blöcke keine Properties tragen, liefern die Queries leere Mengen, nicht Erkenntnis. Property-Disziplin ist Vorarbeit, nicht Nebeneffekt.
- Ad-hoc-Explorationen mit unklarer Fragestellung — Datalog belohnt präzise Fragen. Wer „mal schauen, was im Vault so steht“ will, ist mit Graph-View oder Backlink-Browsing schneller als mit einer Query, die erst noch entworfen werden muss.
Ehrliche Frage
Welches der fünf Rezepte hat bei Dir gepasst, welches lief ins Leere? Falls Du eines davon produktiv einsetzt: was hast Du anders parametriert — Q-Fenster verschoben, Tag-Namespace verändert, Limit erhöht? Und falls keines passt: an welcher Stelle haben wir die Lücke übersehen? Cookbook-Rezepte leben davon, dass sie an realen Vaults reiben — Rückmeldungen, welches Rezept #6 hier fehlt, sind willkommen. Weiterführend in dieser Wave: [[advanced-query-datalog]] für die Sprach-Grundlagen, [[simple-query]] für den einfacheren Einstieg ohne Datalog-Syntax.
- Nimm Rezept 1 und passe es an Dein aktuelles Quartal und Deine Property-Namen an. Prüfe vorab mit einem re-pattern-Filter, ob Deine Frist-Werte überhaupt konsistent als YYYY-MM-DD gepflegt sind — und notiere, wie viele Blöcke durch das Raster fallen.⏱ 15 min
💡 Führe zuerst nur die beiden Datums-Vergleiche ohne Status-Filter aus. Bleibt das Ergebnis leer, obwohl Du offene Fristen hast, liegt es fast immer am Datumsformat, nicht an der Logik.
Musterlösung: Das Q-Fenster wird auf die eigenen Quartalsgrenzen gesetzt (etwa 2026-07-01 bis 2026-09-30), die Property-Namen an die eigene Konvention angepasst. Der Vorab-Filter über re-pattern deckt die Mischformate auf — typisch tauchen einige Blöcke mit 15.07.2026 oder Jul 15 auf, die vor der Query auf YYYY-MM-DD normalisiert werden müssen. Erst danach trägt der Frist-Filter zuverlässig. - Lass Rezept 5 (Orphan-Detektor) einmal über Deinen Vault laufen und zähl die Treffer. Entscheide pro Orphan, ob er verknüpft, archiviert oder gelöscht gehört — und überlege, ob der Lauf bei Dir interaktiv tragbar ist oder in einen Cron-Job gehört.⏱ 20 min
💡 Wenn die Query interaktiv spürbar hängt, ist Dein Vault groß genug für die not-join-Kosten. Dann pflege stattdessen eine has-backlinks?-Property und filtere direkt darauf.
Musterlösung: Die Orphan-Liste ist der ehrlichste Spiegel des Vaults: echte tote Enden werden verknüpft oder archiviert, bewusste Einzelnotizen (Inbox, Tagebuch) bleiben. Auf kleinen Vaults läuft das Rezept interaktiv; ab etwa fünfzigtausend Blöcken wandert es in einen nächtlichen Cron-Lauf oder wird durch eine gepflegte has-backlinks?-Property ersetzt, die den teuren not-join vermeidet.
Warum liefert Rezept 1 (Frist-Filter) bei gemischten Datumsformaten eine leere Menge statt eines Fehlers?
Was zählt Rezept 2 (Backlink-Hubs) standardmäßig mit, was man bewusst herausfiltern müsste?
Wann ist eine Datalog-Query das falsche Mittel?
Warum gehört der Orphan-Detektor (Rezept 5) auf großen Vaults in einen nächtlichen Cron-Lauf?