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
.