Wie versteht die Datenbank Ihre Abfrage und wie führt sie sie aus?
Titelbild
Dieser Artikel wurde von Angela Ni verfasst.
Eine Vektorabfrage in Milvus ist der Prozess des Abrufs von Vektoren mittels skalarer Filterung auf der Grundlage eines booleschen Ausdrucks. Mit skalarer Filterung können Benutzer ihre Abfrageergebnisse mit bestimmten Bedingungen einschränken, die auf Datenattribute angewendet werden. Wenn ein Benutzer beispielsweise nach Filmen sucht, die zwischen 1990 und 2010 veröffentlicht wurden und eine Bewertung von mehr als 8,5 haben, werden nur Filme angezeigt, deren Attribute (Erscheinungsjahr und Bewertung) die Bedingung erfüllen.
In diesem Beitrag soll untersucht werden, wie eine Abfrage in Milvus von der Eingabe eines Abfrageausdrucks bis zur Erstellung des Abfrageplans und der Ausführung der Abfrage abgeschlossen wird.
Springe zu:
Abfrageausdruck
Der Ausdruck einer Abfrage mit Attributfilterung in Milvus verwendet die EBNF-Syntax (Erweiterte Backus-Naur-Form). Die Abbildung unten zeigt die Ausdrucksregeln in Milvus.
Ausdrucks-Syntax
Logische Ausdrücke können durch die Kombination von binären logischen Operatoren, unären logischen Operatoren, logischen Ausdrücken und einzelnen Ausdrücken erstellt werden. Da die EBNF-Syntax selbst rekursiv ist, kann ein logischer Ausdruck das Ergebnis einer Kombination oder Teil eines größeren logischen Ausdrucks sein. Ein logischer Ausdruck kann viele sub-logische Ausdrücke enthalten. Die gleiche Regel gilt in Milvus. Wenn ein Benutzer die Attribute der Ergebnisse mit vielen Bedingungen filtern muss, kann er seinen eigenen Satz von Filterbedingungen erstellen, indem er verschiedene logische Operatoren und Ausdrücke kombiniert.
Boolescher Ausdruck
Das Bild oben zeigt einen Teil der Regeln für boolesche Ausdrücke in Milvus. Unäre logische Operatoren können zu einem Ausdruck hinzugefügt werden. Derzeit unterstützt Milvus nur den unären logischen Operator "not", der anzeigt, dass das System die Vektoren nehmen muss, deren skalare Feldwerte die Berechnungsergebnisse nicht erfüllen. Zu den binären logischen Operatoren gehören "und" und "oder". Einzelne Ausdrücke umfassen Termausdrücke und Vergleichsausdrücke.
Grundlegende arithmetische Berechnungen wie Addition, Subtraktion, Multiplikation und Division werden bei einer Abfrage in Milvus ebenfalls unterstützt. Die folgende Abbildung veranschaulicht die Rangfolge der Operationen. Die Operatoren sind von oben nach unten in absteigender Rangfolge aufgeführt.
Vorrangigkeit
Wie wird ein Abfrageausdruck zu bestimmten Filmen in Milvus verarbeitet?
Angenommen, in Milvus ist eine Fülle von Filmdaten gespeichert und der Benutzer möchte bestimmte Filme abfragen. Jeder in Milvus gespeicherte Film hat zum Beispiel die folgenden fünf Felder: Film-ID, Erscheinungsjahr, Filmtyp, Filmmusik und Filmplakat. In diesem Beispiel ist der Datentyp der Film-ID und des Erscheinungsjahres int64, während die Filmpunkte Fließkommadaten sind. Auch Filmplakate werden im Format von Fließkomma-Vektoren und der Filmtyp im Format von String-Daten gespeichert. Die Unterstützung von String-Daten ist eine neue Funktion in Milvus 2.1.
Wenn ein Benutzer zum Beispiel die Filme mit einer Bewertung von mehr als 8,5 abfragen möchte. Die Filme sollten außerdem in einem Jahrzehnt vor 2000 bis zu einem Jahrzehnt nach 2000 veröffentlicht worden sein, oder ihr Typ sollte entweder eine Komödie oder ein Actionfilm sein, muss der Benutzer den folgenden Prädikatsausdruck eingeben: score > 8.5 && (2000 - 10 < release_year < 2000 + 10 || type in [comedy,action])
.
Nachdem das System den Abfrageausdruck erhalten hat, wird es ihn in der folgenden Reihenfolge ausführen:
- Abfrage nach Filmen mit einer Bewertung von mehr als 8,5. Die Abfrageergebnisse werden "result1" genannt.
- Berechnen Sie 2000 - 10, um "Ergebnis2" (1990) zu erhalten.
- Berechnen Sie 2000 + 10, um "result3" (2010) zu erhalten.
- Suchen Sie nach Filmen, deren Wert auf
release_year
größer als "result2" und kleiner als "result3" ist. Das heißt, dass das System nach Filmen suchen muss, die zwischen 1990 und 2010 veröffentlicht wurden. Die Abfrageergebnisse werden als "result4" bezeichnet. - Abfrage nach Filmen, die entweder Komödien oder Actionfilme sind. Die Abfrageergebnisse werden als "result5" bezeichnet.
- Kombinieren Sie "result4" und "result5", um Filme zu erhalten, die entweder zwischen 1990 und 2010 veröffentlicht wurden oder zur Kategorie der Komödie oder des Actionfilms gehören. Die Ergebnisse werden als "result6" bezeichnet.
- Nehmen Sie den gemeinsamen Teil in "result1" und "result6", um die endgültigen Ergebnisse zu erhalten, die alle Bedingungen erfüllen.
Beispiel für einen Film
AST-Generierung planen
Milvus nutzt das Open-Source-Tool ANTLR (ANother Tool for Language Recognition) für die Generierung von Plan-AST (Abstract Syntax Tree). ANTLR ist ein leistungsfähiger Parser-Generator zum Lesen, Verarbeiten, Ausführen oder Übersetzen von Strukturtext- oder Binärdateien. Genauer gesagt kann ANTLR einen Parser zum Aufbau und zur Abarbeitung von Parse-Bäumen auf der Grundlage einer vordefinierten Syntax oder von Regeln erzeugen. Das folgende Bild ist ein Beispiel, in dem der Eingabeausdruck "SP=100;" lautet. LEXER, die integrierte Spracherkennungsfunktion in ANTLR, erzeugt vier Token für den Eingabeausdruck - "SP", "=", "100" und ";". Anschließend analysiert das Tool die vier Token weiter, um den entsprechenden Parse-Baum zu erzeugen.
Parse-Baum
Der Walker-Mechanismus ist ein wichtiger Bestandteil des ANTLR-Tools. Er soll alle Parse-Bäume durchlaufen, um zu prüfen, ob jeder Knoten den Syntaxregeln gehorcht, oder um bestimmte sensible Wörter zu erkennen. Einige der relevanten APIs sind in der folgenden Abbildung aufgeführt. Da ANTLR vom Wurzelknoten ausgeht und jeden Unterknoten bis zum Ende durchläuft, ist es nicht notwendig, die Reihenfolge des Durchlaufs des Parse-Baums zu unterscheiden.
Parse-Baum-Walker
Milvus generiert den PlanAST für Abfragen auf ähnliche Weise wie ANTLR. Die Verwendung von ANTLR erfordert jedoch die Neudefinition von ziemlich komplizierten Syntaxregeln. Daher übernimmt Milvus eine der am weitesten verbreiteten Regeln - die Regeln für boolesche Ausdrücke - und hängt vom Expr-Paket ab, das auf GitHub zur Verfügung steht, um die Syntax von Abfrageausdrücken abzufragen und zu parsen.
Bei einer Abfrage mit Attributfilterung generiert Milvus nach Erhalt des Abfrageausdrucks einen primitiven, ungelösten Planbaum mithilfe von ant-parser, der von Expr bereitgestellten Parsing-Methode. Der primitive Planbaum, den wir erhalten, ist ein einfacher binärer Baum. Dann wird der Planbaum durch Expr und den eingebauten Optimierer in Milvus fein abgestimmt. Der Optimierer in Milvus ist dem bereits erwähnten Walker-Mechanismus sehr ähnlich. Da die von Expr zur Verfügung gestellte Funktionalität zur Optimierung des Planbaums ziemlich ausgefeilt ist, wird die Belastung des in Milvus eingebauten Optimierers weitgehend gemindert. Letztendlich analysiert der Analyzer den optimierten Planbaum in einer rekursiven Weise, um einen Plan-AST in der Struktur von Protokollpuffern (protobuf) zu erzeugen.
Plan-AST-Arbeitsablauf
Ausführung der Abfrage
Die Ausführung der Abfrage ist im Grunde die Ausführung des in den vorherigen Schritten generierten Plan-AST.
In Milvus wird ein Plan AST in einer Proto-Struktur definiert. Die Abbildung unten zeigt eine Nachricht mit der protobuf-Struktur. Es gibt sechs Arten von Ausdrücken, darunter binäre Ausdrücke und unäre Ausdrücke, die auch binäre logische Ausdrücke und unäre logische Ausdrücke enthalten können.
protobuf1
protobuf2
Die folgende Abbildung ist eine UML-Darstellung des Abfrageausdrucks. Es zeigt die Basisklasse und die abgeleitete Klasse eines jeden Ausdrucks. Jede Klasse verfügt über eine Methode zur Annahme von Besucherparametern. Dies ist ein typisches Besucherentwurfsmuster. Milvus verwendet dieses Muster, um den Plan AST auszuführen, da sein größter Vorteil darin besteht, dass die Benutzer nichts an den primitiven Ausdrücken ändern müssen, sondern direkt auf eine der Methoden in den Mustern zugreifen können, um bestimmte Abfrageausdrucksklassen und relevante Elemente zu ändern.
UML
Bei der Ausführung eines Plan-AST erhält Milvus zunächst einen Plan-Knoten vom Typ Proto. Dann wird über den internen C++-Proto-Parser ein Plan-Knoten vom Typ Segcore ermittelt. Nach Erhalt der beiden Arten von Planknoten akzeptiert Milvus eine Reihe von Klassenzugriffen und modifiziert dann die interne Struktur der Planknoten und führt sie aus. Schließlich durchsucht Milvus alle Knoten des Ausführungsplans, um die gefilterten Ergebnisse zu erhalten. Die Endergebnisse werden im Format einer Bitmaske ausgegeben. Eine Bitmaske ist ein Array von Bitnummern ("0" und "1"). Die Daten, die die Filterbedingungen erfüllen, werden in der Bitmaske als "1" markiert, während die Daten, die die Anforderungen nicht erfüllen, in der Bitmaske als "0" markiert werden.
Arbeitsablauf ausführen
Über die Deep Dive-Reihe
Mit der offiziellen Ankündigung der allgemeinen Verfügbarkeit von Milvus 2.0 haben wir diese Milvus-Deep-Dive-Blogserie ins Leben gerufen, um eine tiefgehende Interpretation der Milvus-Architektur und des Quellcodes zu bieten. Die Themen dieser Blogserie umfassen:
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word