MongoDB beginnt mit Abfrage

Tahseen Tauseef 20 Juni 2023
  1. MongoDB beginnt mit Abfrage mit $regex
  2. . Punktzeichen für Übereinstimmung mit neuer Zeile
MongoDB beginnt mit Abfrage

In diesem MongoDB-Artikel lernt der Benutzer, mit einer Abfrage mit $regex zu beginnen. Es bietet Funktionen für reguläre Ausdrücke zum Musterabgleich von Zeichenfolgen in Abfragen.

MongoDB beginnt mit Abfrage mit $regex

Wenn Sie $regex verwenden möchten, verwenden Sie eine der folgenden Syntaxen.

{ <field>: { $regex: /pattern/, $options: '<options>' } }
{ <field>: { $regex: 'pattern', $options: '<options>' } }
{ <field>: { $regex: /pattern/<options> } }

In MongoDB kann der Benutzer auch reguläre Ausdrucksobjekte (d. h. /pattern/) verwenden, um reguläre Ausdrücke anzugeben.

{ <field>: /pattern/<options> }

Der Benutzer kann reguläre Ausdrücke mit den folgenden <Optionen> verwenden.

Möglichkeit Beschreibung Syntaxbeschränkungen
i Groß- und Kleinschreibung wird nicht beachtet.
m Suchen Sie bei Zeichenfolgen mit mehrzeiligen Werten am Anfang oder Ende jeder Zeile nach Mustern, die Anker wie ^ am Anfang und $ am Ende enthalten. Die Option m hat keine Wirkung, wenn das Muster keine Anker hat oder wenn der String-Wert keine Zeilenumbrüche enthält (z. B. \n).
x Alle Leerzeichen im Muster $regex werden ignoriert, es sei denn, sie sind maskiert oder in einer Zeichenklasse enthalten. Es ignoriert auch Zeichen in der Mitte und enthält ein nicht maskiertes Raute-/Pfundzeichen (#) und den folgenden Zeilenumbruch, sodass Sie Kommentare in komplexen Mustern hinzufügen können. Leerzeichen erscheinen möglicherweise nicht innerhalb von Sonderzeichenfolgen in einem Muster; dies betrifft nur Datenzeichen. Die Option x wirkt sich nicht darauf aus, wie das VT-Zeichen behandelt wird (d. h. Code 11). Es wird $regex mit $options-Syntax benötigt
s Das Punktzeichen (.) kann mit jedem Zeichen übereinstimmen, einschließlich Zeilenumbrüchen. Benötigt $regex mit $options-Syntax

Der Operator $regex unterstützt den globalen Suchmodifikator g nicht.

der $in-Ausdruck

Nur JavaScript-Objekte für reguläre Ausdrücke (d. h. /pattern/) können verwendet werden, um einen regulären Ausdruck in den Abfrageausdruck $in einzufügen. Betrachten Sie das folgende Beispiel.

{ name: { $in: [ /^acme/i, /^ack/ ] } }

Innerhalb von $in können Sie keine $regex-Operatorausdrücke verwenden.

Implizite UND-Bedingungen für das Feld

Verwenden Sie den Operator $regex, um einen regulären Ausdruck in eine kommagetrennte Liste von Abfragekriterien für das Feld einzufügen. Betrachten Sie das folgende Beispiel.

{ name: { $regex: /acme.*corp/i, $nin: [ 'acmeblahcorp' ] } }
{ name: { $regex: /acme.*corp/, $options: 'i', $nin: [ 'acmeblahcorp' ] } }
{ name: { $regex: 'acme.*corp', $options: 'i', $nin: [ 'acmeblahcorp' ] } }

der Operator $regex mit x und s

Der Benutzer sollte den Operator $regex mit dem Operator $options verwenden, um die Optionen x oder s zu verwenden. Um beispielsweise die Optionen i und s anzugeben, müssen Sie $options verwenden.

{ name: { $regex: /acme.*corp/, $options: "si" } }
{ name: { $regex: 'acme.*corp', $options: "si" } }

PCRE vs. JavaScript

Der Benutzer sollte den Operatorausdruck $regex mit dem Muster als Zeichenfolge verwenden, um PCRE-unterstützte Funktionen im Regex-Muster zu nutzen, die in JavaScript nicht unterstützt werden.

Beispielsweise müssen Sie den Operator $regex mit dem Muster als Zeichenfolge verwenden, um (?i) und (?-i) im Muster zu verwenden, um die Groß-/Kleinschreibung für das verbleibende Muster zu aktivieren.

{ name: { $regex: '(?i)a(?-i)cme' } }

$regex und $not

Ab Version 4.0.7 kann der Operator $not eine logische NOT-Operation auf beiden ausführen:

  1. Objekte regulärer Ausdrücke (z. B. /Muster/)

    Zum Beispiel:

db.inventory.find( { item: { $not: /^p.*/ } } )
  1. $regex-Operatorausdrücke (ab MongoDB 4.0.7).

    Zum Beispiel:

db.inventory.find( { item: { $not: { $regex: "^p.*" } } } )
db.inventory.find( { item: { $not: { $regex: /^p.*/ } } } )

In Version 4.0.6 und früher konnten Sie den $not-Operator mit regulären Ausdrucksobjekten (d. h. /pattern/) verwenden, aber nicht mit den $regex-Operatorausdrücken.

Wenn das Feld einen Index hat, vergleicht MongoDB den regulären Ausdruck mit den Werten im Index, was bei Abfragen mit regulären Ausdrücken, bei denen die Groß-/Kleinschreibung beachtet werden muss, schneller sein kann als ein Sammlungsscan.

Eine weitere Optimierung ist möglich, wenn der reguläre Ausdruck einen Präfixausdruck hat, der anzeigt, dass alle potenziellen Übereinstimmungen mit der exakten Zeichenfolge beginnen. Dadurch kann MongoDB einen Bereich aus dem Präfix erstellen und nur mit Indexwerten innerhalb dieses Bereichs abgleichen.

Wenn ein regulärer Ausdruck mit einem Caretzeichen (^) oder einem linken Anker (\A) beginnt, gefolgt von einer Reihe einfacher Symbole, wird er als Präfixausdruck bezeichnet. Beispielsweise wird die Regex /^abc.*/ optimiert, indem sie nur mit Indexwerten abgeglichen wird, die mit abc beginnen.

Obwohl /^a/, /^a.*/ und /^a.*$/ alle mit vergleichbaren Zeichenfolgen übereinstimmen, ist ihre Leistung unterschiedlich.

Wenn ein passender Index existiert, verwenden alle diese Ausdrücke ihn; trotzdem sind /^a.*/ und /^a.*$/ langsamer. Nach Übereinstimmung mit dem Präfix kann /^a/ die Suche beenden.

Abfragen mit regulären Ausdrücken, bei denen die Groß-/Kleinschreibung nicht beachtet wird, können Indizes nicht effizient nutzen. Die $regex-Implementierung ist beispielsweise nicht kollationsbewusst und kann daher keine Indizes ohne Berücksichtigung der Groß-/Kleinschreibung verwenden.

Beispiele:

Die folgenden Beispiele verwenden eine Sammlung namens Produkte mit den folgenden Dokumenten.

{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." },
{ "_id" : 101, "ski" : "abc789", "description" : "First line\nSecond line" },
{ "_id" : 102, "ski" : "xyz456", "description" : "Many spaces before     line" },
{ "_id" : 103, "ski" : "xyz789", "description" : "Multiple\nline description" }

die LIKE-Anweisung

Dieses Beispiel stimmt mit allen Dokumenten überein, in denen das Feld ski wie "%789" lautet.

db.products.find( { ski: { $regex: /789$/ } } )

Das Beispiel ähnelt der folgenden SQL LIKE-Anweisung.

SELECT * FROM products
WHERE ski like "%789";

Übereinstimmung mit regulären Ausdrücken ohne Berücksichtigung der Groß-/Kleinschreibung

Das folgende Beispiel verwendet die Option i und führt einen Vergleich ohne Berücksichtigung der Groß-/Kleinschreibung für Dokumente mit einem ski-Wert durch, der mit ABC beginnt.

db.products.find( { ski: { $regex: /^ABC/i } } )

Die Abfrage stimmt mit den folgenden Dokumenten überein.

{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "ski" : "abc789", "description" : "First line\nSecond line" }

Mehrzeilige Übereinstimmung

Die Option m wird im folgenden Beispiel verwendet, um Zeilen, die mit dem Buchstaben S beginnen, in mehrzeiligen Zeichenfolgen abzugleichen.

db.products.find( { description: { $regex: /^S/, $options: 'm' } } )

Die Abfrage stimmt mit den unten angegebenen Dokumenten überein.

{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "ski" : "abc789", "description" : "First line\nSecond line" }

Ohne die Option m würde die Abfrage nur auf das folgende Dokument passen.

{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }

Wenn das Muster $regex keinen Anker enthält, wird das Muster wie im folgenden Beispiel auf den gesamten String angewendet.

db.products.find( { description: { $regex: /S/ } } )

Dann würde der $regex mit beiden Dokumenten übereinstimmen.

{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "ski" : "abc789", "description" : "First line\nSecond line" }

. Punktzeichen für Übereinstimmung mit neuer Zeile

Die Option s lässt zu, dass das Punktzeichen (.) mit allen Zeichen übereinstimmt, einschließlich der neuen Zeile, und die Option i ermöglicht eine Übereinstimmung ohne Berücksichtigung der Groß-/Kleinschreibung.

db.products.find( { description: { $regex: /m.*line/, $options: 'si' } } )

Die Abfrage stimmt mit den folgenden Dokumenten überein.

{ "_id" : 102, "ski" : "xyz456", "description" : "Many spaces before     line" }
{ "_id" : 103, "ski" : "xyz789", "description" : "Multiple\nline description" }

Ohne die Option s würde die Abfrage nur auf das folgende Dokument passen.

{ "_id" : 102, "ski" : "xyz456", "description" : "Many spaces before     line" }

Leerzeichen in einem Muster

Im Vergleichsmuster ignoriert die Option x Leerzeichen und Kommentare, die mit # gekennzeichnet sind, und endet mit dem n:..

var pattern = "abc #category code\n123 #item number"
db.products.find( { ski: { $regex: pattern, $options: "x" } } )

Die Abfrage stimmt mit dem folgenden Dokument überein.

{ "_id" : 100, "ski" : "abc123", "description" : "Single line description." }