MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

MongoDB $indexOfBytes

In MongoDB der $indexOfBytes Der Aggregations-Pipeline-Operator durchsucht eine Zeichenfolge nach einem Vorkommen einer Teilzeichenfolge und gibt den UTF-8-Byteindex des ersten Vorkommens zurück.

Der UTF-Byte-Index ist nullbasiert (d. h. er beginnt bei 0 ).

Syntax

Die Syntax sieht so aus:

{ $indexOfBytes: [ <string expression>, <substring expression>, <start>, <end> ] }

Wo:

  • <string expression> ist die Zeichenfolge, nach der gesucht werden soll.
  • <substring expression> ist die Teilzeichenfolge, die Sie in der Zeichenfolge finden möchten.
  • <start> ist ein optionales Argument, das eine Startindexposition für die Suche angibt. Kann ein beliebiger gültiger Ausdruck sein, der sich in eine nicht negative ganze Zahl auflösen lässt.
  • <end> ist ein optionales Argument, das eine Endindexposition für die Suche angibt. Kann ein beliebiger gültiger Ausdruck sein, der sich in eine nicht negative ganze Zahl auflösen lässt.

Wenn der angegebene Wert nicht gefunden wird, $indexOfBytes gibt -1 zurück .

Wenn mehrere Instanzen des angegebenen Werts vorhanden sind, wird nur die erste zurückgegeben.

Beispiel

Angenommen, wir haben eine Sammlung namens test mit folgenden Dokumenten:

{ "_id" : 1, "data" : "c 2021" }
{ "_id" : 2, "data" : "© 2021" }
{ "_id" : 3, "data" : "ไม้เมือง" }

Hier ist ein Beispiel für die Anwendung von $indexOfBytes zu diesen Dokumenten:

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "2021" ] }
          }
     }
   ]
)

Ergebnis:

{ "data" : "c 2021", "result" : 2 }
{ "data" : "© 2021", "result" : 3 }
{ "data" : "ไม้เมือง", "result" : -1 }

Wir können sehen, dass die ersten beiden Dokumente unterschiedliche Ergebnisse lieferten, obwohl die Teilzeichenfolge für jedes Dokument an derselben Position zu sein scheint. Im ersten Dokument wurde der Teilstring an der Byte-Indexposition 2 gefunden , während das zweite Dokument es bei 3 hatte .

Der Grund dafür ist, dass das Copyright-Zeichen (© ) im zweiten Dokument nimmt 2 Bytes ein. Das c Zeichen (im ersten Dokument) verwendet nur 1 Byte. Das Leerzeichen belegt ebenfalls 1 Byte.

Das Ergebnis von $indexOfBytes ist nullbasiert (der Index beginnt bei 0 ), und so erhalten wir als Ergebnis 2 und 3 bzw..

In Bezug auf das dritte Dokument wurde der Teilstring überhaupt nicht gefunden, daher ist das Ergebnis -1 .

Hier ist ein weiteres Beispiel, außer dass wir dieses Mal nach einem thailändischen Zeichen suchen:

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "เ" ] }
          }
     }
   ]
)

Ergebnis:

{ "data" : "c 2021", "result" : -1 }
{ "data" : "© 2021", "result" : -1 }
{ "data" : "ไม้เมือง", "result" : 9 }

In diesem Fall haben wir nach einem Zeichen gesucht, das im dritten Dokument an dritter Stelle erscheint, und sein UTF-8-Byte-Index kommt als 9 zurück .

Dies liegt daran, dass in diesem Fall jedes Zeichen 3 Bytes belegt. Aber das zweite Zeichen hat ein diakritisches Zeichen, das ebenfalls 3 Byte groß ist. Daher verwenden die ersten beiden Zeichen (einschließlich des diakritischen Zeichens) 9 Bytes. Angesichts der nullbasierten Indizierung reichen ihre UTF-8-Byte-Indizes von 0 bis 8 . Das bedeutet, dass das dritte Zeichen an Position 9 beginnt .

Siehe MongoDB $strLenBytes für ein Beispiel, das die Anzahl der Bytes für jedes Zeichen in dieser bestimmten Zeichenfolge zurückgibt.

Geben Sie eine Startposition an

Sie können ein drittes Argument angeben, um eine Startindexposition für die Suche anzugeben.

Angenommen, wir haben das folgende Dokument:

{ "_id" : 4, "data" : "ABC XYZ ABC" }

Hier ist ein Beispiel für die Anwendung von $indexOfBytes mit einer Startposition:

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 4 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "ABC", 1 ] }
          }
     }
   ]
)

Ergebnis:

{ "data" : "ABC XYZ ABC", "result" : 8 }

In diesem Fall wurde die zweite Instanz der Teilzeichenfolge zurückgegeben. Das liegt daran, dass wir die Suche an Position 1 gestartet haben , und die erste Instanz der Teilzeichenfolge beginnt an Position 0 (vor der Startposition für die Suche).

Wenn die Startposition eine Zahl ist, die größer als die Bytelänge der Zeichenfolge oder größer als die Endposition ist, $indexOfBytes gibt -1 zurück .

Wenn es sich um eine negative Zahl handelt, $indexOfBytes gibt einen Fehler zurück.

Geben Sie eine Endposition an

Sie können auch ein viertes Argument angeben, um die letzte Indexposition für die Suche anzugeben.

Wenn Sie dieses Argument angeben, müssen Sie auch eine Ausgangsposition angeben. Andernfalls wird dieses Argument als Ausgangspunkt interpretiert.

Beispiel:

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 4 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "XYZ", 0, 5 ] }
          }
     }
   ]
)

Ergebnis:

{ "data" : "ABC XYZ ABC", "result" : -1 }

Das Ergebnis ist -1 was bedeutet, dass der Teilstring nicht gefunden wurde. Das liegt daran, dass wir unsere Suche an Position 0 gestartet haben und beendete es an Position 5 , daher wird der Teilstring nicht erfasst.

Folgendes passiert, wenn wir die Endindexposition erhöhen:

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 4 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "XYZ", 0, 7 ] }
          }
     }
   ]
)

Ergebnis:

{ "data" : "ABC XYZ ABC", "result" : 4 }

Dieses Mal wurde der Wert eingeschlossen und seine Indexposition zurückgegeben.

Wenn die Endposition eine Zahl kleiner als die Startposition ist, $indexOfBytes gibt -1 zurück .

Wenn es sich um eine negative Zahl handelt, $indexOfBytes gibt einen Fehler zurück.

Fehlende Felder

Wenn sich das Feld nicht im Dokument befindet, $indexOfBytes gibt null zurück .

Angenommen, wir haben das folgende Dokument:

{ "_id" : 5 }

Folgendes passiert, wenn wir $indexOfBytes anwenden :

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 5 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "XYZ" ] }
          }
     }
   ]
)

Ergebnis:

{ "result" : null }

Nullwerte

Wenn das erste Argument null ist , $indexOfBytes gibt null zurück .

Angenommen, wir haben das folgende Dokument:

{ "_id" : 6, "data" : null }

Folgendes passiert, wenn wir $indexOfBytes anwenden :

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 6 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "XYZ" ] }
          }
     }
   ]
)

Ergebnis:

{ "data" : null, "result" : null }

Wenn jedoch das zweite Argument (d. h. die Teilzeichenfolge) null ist , wird ein Fehler zurückgegeben:

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 1 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", null ] }
          }
     }
   ]
)

Ergebnis:

uncaught exception: Error: command failed: {
	"ok" : 0,
	"errmsg" : "$indexOfBytes requires a string as the second argument, found: null",
	"code" : 40092,
	"codeName" : "Location40092"
} : aggregate failed :
[email protected]/mongo/shell/utils.js:25:13
[email protected]/mongo/shell/assert.js:18:14
[email protected]/mongo/shell/assert.js:639:17
[email protected]/mongo/shell/assert.js:729:16
[email protected]/mongo/shell/db.js:266:5
[email protected]/mongo/shell/collection.js:1058:12
@(shell):1:1

Falscher Datentyp

Wenn das erste Argument den falschen Datentyp hat (d. h. es wird nicht in einen String aufgelöst), $indexOfBytes gibt einen Fehler zurück.

Angenommen, wir haben das folgende Dokument:

{ "_id" : 7, "data" : 123 }

Folgendes passiert, wenn wir $indexOfBytes anwenden zu diesem Dokument:

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 7 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "XYZ" ] }
          }
     }
   ]
)

Ergebnis:

uncaught exception: Error: command failed: {
	"ok" : 0,
	"errmsg" : "$indexOfBytes requires a string as the first argument, found: double",
	"code" : 40091,
	"codeName" : "Location40091"
} : aggregate failed :
[email protected]/mongo/shell/utils.js:25:13
[email protected]/mongo/shell/assert.js:18:14
[email protected]/mongo/shell/assert.js:639:17
[email protected]/mongo/shell/assert.js:729:16
[email protected]/mongo/shell/db.js:266:5
[email protected]/mongo/shell/collection.js:1058:12
@(shell):1:1

Wie die Fehlermeldung besagt, erfordert $indexOfBytes requires a string as the first argument .