Wikiup:Technik/Cloud/quarry

aus Wikipedia, der freien Enzyklopädie

{{Wikipedia:Technik/Cloud/Helferlein/!header

    |Shortcuts=WP:HT/quarry
    |Info=Datenbankabfragen
    |Logo=Quarry-logo-icon.svg
    |PfadQuery=
    |VPS=1
    |wmcloud=
    |Labs=
    |offline=0}}[1] ist eine seit 2014 verfügbare Schnittstelle, mit der alle angemeldeten WMF-Benutzer via SQL Datenbankabfragen zu den Wikis ausführen können.

Die Bot-Betreiber haben gute Kenntnisse in SQL und können ggf. unter Bots/Anfragen konkrete Abfragen erstellen.

Erreichbare Informationen

Die Anfrage geht nicht an die produktiven Wiki-Versionen, sondern an Replikate, die mit leichter Verzögerung oder auch mal größerer Verspätung aktualisiert werden.

Nicht verfügbar sind die eigentlichen textlichen Inhalte der Seiten; hingegen alle Meta-Informationen über das Projekt und die enthaltenen Seiten, namentlich:

  • Seiteninformationen
  • Versionsgeschichte nebst Bearbeitungskommentaren
  • Außenwirkung einer Seite, wie:
  • Logbuch-Informationen
  • Benutzerinfos
  • Allgemeine Projektkonfiguration und Statistik

Nicht enthalten sind bewusst für die Öffentlichkeit gesperrte Informationen, wie Versionslöschungen usw.

Benutzeranmeldung

Der Zugang erfolgt über OAuth, wodurch der Quarry-Zugriff mit dem Wikipedia-Benutzerkonto verbunden wird.

Registrierung als normaler Wiki-Benutzer:

Benutzerprofil

Jeder Benutzer kann die persönlichen Abfragen, Entwürfe dazu sowie publizierte Abfragen individuell verwalten.

Abfragen

Über New Query gelangt man in den Eingabemodus. Unten auf schwarzem Hintergrund befindet sich die interaktive Konsole.

Konsole

Die deutschsprachige Wikipedia[2] muss zunächst ausgewählt werden mittels:

USE dewiki_p;

Die Abfrage kann dann mittels Submit Query gestartet werden.

Im weiteren Verlauf erhält man Statusmeldungen über den Bearbeitungsstand; schließlich hoffentlich auch das Ergebnis.

Speichern

Eine Abfrage kann zur Wiederverwendung abgespeichert werden.

  • Dazu sollte sie mit einem aussagekräftigen Titel und auch mit einer Kurzbeschreibung des Zwecks in menschlicher Sprache ausgestattet werden.
  • Jede Abfrage erhält eine laufende Nummer, unter der sie erneut ausgeführt und modifiziert werden kann.
  • Die Abfragen können öffentlich gemacht werden.
  • Quarry:query/runs/all – kürzliche Abfragen.
  • Eine Verlinkung ist mit [[Quarry:]] möglich; auf einzelne Abfragen oder mit Quarry: auf das ganze Projekt.

Ergebnisse herunterladen

Zur Weiterverarbeitung können die Ergebnisse in den Formaten CSV, TSV (Tabulator-Separated Values) oder JSON aktualisiert und lokal gespeichert werden.

URL:

http://quarry.wmflabs.org/run/Abfragenummer/output/Lauf-Nummer/Formatierung

mit

Formatierung – eine von csv tsv json

Ergebnisse verlinken

Die Verlinkung von gespeicherten Abfragen ist über [[quarry:]] möglich, wobei als „Seitenname“ die Abfragenummer anzugeben ist.

Datenstrukturen

Beispielabfragen

Wer waren die ersten 100 Benutzer der deutschsprachigen Wikipedia?

USE dewiki_p;
SELECT user_id, user_name, user_editcount
FROM user
LIMIT 100;
  • Die erste Zeile wählt die deutschsprachige Wikipedia als Grundlage aus.
  • SELECT nennt drei Felder, die aufgelistet werden sollen.
  • FROM gibt eine Tabelle an, der die Felder entnommen werden sollen.
    • Groß- und Kleinschreibung des Tabellennamens user ist hier ohne Bedeutung und erfolgt in der vorstehenden Darstellung automatisch.
  • LIMIT beschränkt die Abfrage auf die ersten 100 Treffer.
  • Die Abfrage enthält die folgende Grammatik: SELECT … FROM … LIMIT …;
  • Der SQL-Code enthält zwei Statements, deren jedes traditionell mit einem Semikolon ; abgeschlossen ist; funktionieren würde es auch ohne.

Das Ergebnis ist als Quarry:query/1470 unter Nummer 1470 gespeichert.

Verknüpfte Tabellen

Die nachstehende Abfrage verknüpft die beiden Tabellen page und redirect über die in beiden vorhandene Seitenkennnummer miteinander.

  • Ziel ist es, alle enzyklopädischen Artikel aufzulisten, die eine Weiterleitung in einen anderen Namensraum darstellen.

Dazu wird wie folgt vorgegangen:

  • In SELECT werden drei Datenfelder aufgelistet, die die drei angezeigten Spalten ergeben werden.
  • FROM gibt die beiden zu nutzenden Tabellen an. Jetzt ist es erforderlich, die exakte Notation der Tabellenbezeichener – also die Kleinschreibung – zu verwenden.
  • Auf WHERE folgen vier mittels AND verknüpfte Bedingungen, die die Reultate immer weiter eingrenzen:
    1. page_is_redirect = 1   die Seite ist eine Weiterleitung.
    2. page_namespace = 0   die Seite ist ein enzyklopädischer Artikel; 0 ist die Nummer des ANR.
    3. rd_from = page_id   der Eintrag in der Tabelle aller Weiterleitungen soll die gleiche Seitenkennnummer haben wie die festgestellte Artikel-Weiterleitung.
    4. rd_namespace <> 0   das Ziel der Weiterleitung liegt nicht im ANR, weil die Nummer des Namensraums ungleich 0 ist.
USE dewiki_p;
SELECT page_title, rd_namespace, rd_title
FROM page, redirect
WHERE page_is_redirect = 1
      AND page_namespace = 0
      AND rd_from = page_id
      AND rd_namespace <> 0;

Es dürfen nur drei Weiterleitungen auf 4:Hauptseite resultieren.

In MediaWiki wurden die Bezeichner der Felder so gewählt, dass sie innerhalb der gesamten Datenbank nur einmal vorkommen. Das ist nicht zwingend notwendig; klassisch würde man in jeder Tabelle das Feld mit der Seitenkennnummer nur pageid nennen und das für die Nummer des Namensraums überall ns. Dann müste zur Unterscheidung immer der Name der Tabelle vorangestellt werden; also page.pageid und page.ns gegen redirect.pageid und redirect.ns. Das funktioniert hier auch und würde wie folgt aussehen:

USE dewiki_p;
SELECT page.page_title, redirect.rd_namespace, redirect.rd_title
FROM page, redirect
WHERE page.page_is_redirect = 1
      AND page.page_namespace = 0
      AND redirect.rd_from = page.page_id
      AND redirect.rd_namespace <> 0;

Verknüpfte Tabellen mit JOIN

Die nachstehende Abfrage verknüpft die beiden Tabellen page und pagelinks miteinander.

  • Ziel ist es, alle Kategoriebeschreibungsseiten aufzulisten, die ein redlink enthalten.

Ein Lösungsansatz ist der folgende:

  • Es wird eine Pseudo-Tabelle pjoin gebildet mit der Forderung LEFT JOIN. Es handelt sich um eine Form des sogenannten outer join.
  • Diese Pseudo-Tabelle enthält alle Datensätze, bei denen die Paarung namespace/title von page und pagelinks übereinstimmt, und bildet wie im vorigen Beispiel eine Art kombinierten Datensatz daraus.
  • Mit dieser Pseudo-Tabelle wird eine weitere namens pg gebildet.
    • Sie enthält die Kategorieseiten über die Nummer 14 des Namensraums.
    • Sie ist über die Bedingung eingeschränkt, dass eine verlinkte Zielseite nicht existiert, was über pjoin.page_namespace IS NULL realisiert wurde; bei einer existierenden Zielseite (und Fundstelle in pjoin) wäre das eine Zahl.
  • Schließlich werden (nicht unbedingt sortiert) aufgelistet: Der Titel der Kategorie, die Namensraum-Nummer und der Titel des Wikilinks.
USE dewiki_p;
SELECT pg.page_title, pl_namespace, pl_title
FROM ( pagelinks LEFT JOIN page pjoin
                 ON pl_namespace = pjoin.page_namespace
                    AND pl_title = pjoin.page_title
     ) LEFT JOIN page pg
       ON pl_from = pg.page_id
       WHERE pl_from_namespace = 14
             AND pjoin.page_namespace IS NULL;

Funktionsaufruf und sub-SELECT

Die gleiche Aufgabenstellung wie im vorherigen Beispiel kann auch noch auf einem anderen Weg gelöst werden (aber vermutlich weniger effizient):

  • Ein sub-SELECT zählt mittels der Funktion COUNT() alle Datensätze in page, die eine von pagelinks vorgegebene Bedingung zu namespace/title erfüllen.
    • Weil es nur einen einzigen Treffer geben kann, wird der Zählvorgang nach der ersten Fundstelle mittels LIMIT 1 abgebrochen.
    • Das in Klammern gesetzte Ergebnis ist der Funktionswert von COUNT() und kann einen der Werte 1 oder 0 annehmen.
  • Ansonsten wird im ersten SELECT wieder die gleiche Bedingung formuliert:
    • Kategorieseite.
    • Verknüpfung der beiden Tabellen über die Seitenkennnummer.
    • „Redlink“ über sub-SELECT.
USE dewiki_p;
SELECT page_title, pl_namespace, pl_title
FROM page, pagelinks
WHERE pl_from_namespace = 14
      AND page_id = pl_from
      AND ( SELECT COUNT(*)
            FROM page
            WHERE page_title = pl_title
                  AND page_namespace = pl_namespace
            LIMIT 1 ) = 0;

Weitere Informationen

Meta-Wiki: Research:Quarry – Infos (englisch)
Wikibooks: SQL – Einführung (deutsch)
Phabricator – Workboard: #Quarry

Alternative Methoden

  • API – andere Abfragetechnik, direkt online; gleiche Daten und zusätzlich alle Textinhalte, aber weniger Möglichkeiten zur Auswertung in der Abfrage selbst
  • Cirrus – fortgeschrittene Möglichkeiten zur Suche in den aktuellen Textinhalten

Anmerkungen

  1. englisch für ‚Fundgrube‘, auch ‚Steinbruch‘; Wortspiel mit query – dem Kernstück aller Datenbankabfragen
  2. Zu weiteren Wikis siehe „Datenbankname