Effizientes Datenbankmodell zum Speichern von mit n-Gramm indizierten Daten

12

Ich arbeite an einer Anwendung, für die eine sehr große Datenbank mit n-Gramm erstellt werden muss, die in einem großen Textkorpus vorhanden ist.

Ich benötige drei effiziente Operationstypen: Nachschlagen und Einfügen, indiziert durch das n-Gramm selbst, und Abfragen aller n-Gramme, die ein Sub-n-Gramm enthalten.

Das klingt für mich so, als ob die Datenbank ein gigantischer Dokumentenbaum sein sollte und Dokumentendatenbanken, z. B. Mongo, in der Lage sein sollten, die Arbeit gut zu erledigen, aber ich habe sie nie im Maßstab verwendet.

In Kenntnis des Stack Exchange-Fragenformats möchte ich klarstellen, dass ich nicht nach Vorschlägen für bestimmte Technologien frage, sondern nach einer Art Datenbank, nach der ich Ausschau halten sollte, um so etwas in großem Maßstab zu implementieren.

Phonon
quelle
2
Ich denke, die Struktur, die Sie implementieren möchten, ist ein "Versuch" - ob Sie eine Datenbank finden können, die mit dieser Struktur effizient funktioniert, oder ob Sie Ihre eigene in RDBMS Ihrer Wahl rollen müssen, kann ich nicht sagen.
Neil Slater

Antworten:

9

Sehen Lucene NGramTokenizer

Sind Sie sicher, dass Sie nicht nur Lucene oder ähnliche Indizierungstechniken verwenden können?

Invertierte Indizes speichern das n-Gramm nur einmal, dann nur die Dokument-IDs, die das n-Gramm enthalten. Sie speichern dies nicht als hochredundanten Rohtext.

Was das Finden von n-Grammen betrifft, die Ihr Abfrage-Sub-n-Gramm enthalten, würde ich einen Index für die beobachteten n-Gramme erstellen, z. B. unter Verwendung eines zweiten Lucene-Index oder beliebiger anderer Teilkette Index wie zum Beispiel eines Trie oder Suffix - Baum. Wenn Ihre Daten dynamisch sind, ist wahrscheinlich Lucene eine vernünftige Wahl. Verwenden Sie Phrasenabfragen, um Ihre n-Gramme zu finden.

Hat aufgehört - Anony-Mousse
quelle
3

Grundsätzlich können Sie für diese Aufgabe jede SQL-Datenbank mit guter Unterstützung von B + Tree-basierten Indizes effizient nutzen (MySQL wird Ihnen genau das bieten, was Sie brauchen).

Erstelle 3 Tabellen:

  1. Dokumententabelle, Spalten: ID / Dokument
  2. N-Gramm-Tabelle: n_gram_id / n_gram
  3. Zuordnung zwischen n-Gramm und Dokumenten: document_id / n_gram_id

Erstellen Sie Indizes für die N-Gramm-Tabelle / n_gram-Zeichenfolge und die Zuordnungstabelle / n_gram_id. Außerdem werden Primärschlüssel standardmäßig gut indiziert.

Ihre Operationen werden effizient sein:

  1. Einfügen eines Dokuments: Extrahieren Sie einfach alle n-Gramme und fügen Sie sie in die Dokumententabelle und die N-Gramme-Tabelle ein
  2. Die Suche nach in_gram erfolgt schnell mit Unterstützung von index
  3. Abfrage aller n-Gramme, die ein Sub-n-Gramm enthalten: in 2 Schritten - fragen Sie alle n-Gramme, die Sub-n-Gramme aus der 2. Tabelle enthalten, anhand des Index ab. Dann - alle entsprechenden Dokumente für jedes dieser n-Gramm abrufen.

Sie müssen nicht einmal Joins verwenden, um alle diese Vorgänge auszuführen, damit Indizes viel helfen. Auch wenn die Daten nicht auf einem Computer gespeichert werden - Sie können ein Sharding-Schema implementieren, beispielsweise das Speichern von n_grams, die von einem auf einem Server gestartet wurden, und oz auf einem anderen oder einem anderen geeigneten Schema.

Sie können auch MongoDB verwenden, aber ich bin nicht sicher, wie genau Sie das Indexierungsschema implementieren müssen. Für MongoDB erhalten Sie ein kostenloses Sharding-Schema, da es bereits integriert ist.

Maxim Galushka
quelle
1

Ich habe das noch nie gemacht, aber es klingt wie ein Job für eine Grafikdatenbank, wenn man die gewünschte Funktionalität hat. Hier ist eine Demo in neo4j .

Emre
quelle