In MongoDB is de $indexOfBytes
aggregatiepijplijnoperator zoekt in een tekenreeks naar een exemplaar van een subtekenreeks en retourneert de UTF-8-byte-index van het eerste exemplaar.
De UTF-byte-index is gebaseerd op nul (d.w.z. hij begint bij 0
).
Syntaxis
De syntaxis gaat als volgt:
{ $indexOfBytes: [ <string expression>, <substring expression>, <start>, <end> ] }
Waar:
<string expression>
is de tekenreeks om te zoeken.<substring expression>
is de substring die je in de string wilt vinden.<start>
is een optioneel argument dat een startindexpositie voor de zoekopdracht specificeert. Kan elke geldige uitdrukking zijn die oplost in een niet-negatief geheel getal.<end>
is een optioneel argument dat een eindindexpositie voor de zoekopdracht specificeert. Kan elke geldige uitdrukking zijn die oplost in een niet-negatief geheel getal.
Als de opgegeven waarde niet wordt gevonden, $indexOfBytes
retourneert -1
.
Als er meerdere exemplaren van de opgegeven waarde zijn, wordt alleen de eerste geretourneerd.
Voorbeeld
Stel dat we een verzameling hebben met de naam test
met de volgende documenten:
{ "_id" : 1, "data" : "c 2021" } { "_id" : 2, "data" : "© 2021" } { "_id" : 3, "data" : "ไม้เมือง" }
Hier is een voorbeeld van het toepassen van $indexOfBytes
naar die documenten:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "2021" ] }
}
}
]
)
Resultaat:
{ "data" : "c 2021", "result" : 2 } { "data" : "© 2021", "result" : 3 } { "data" : "ไม้เมือง", "result" : -1 }
We kunnen zien dat de eerste twee documenten verschillende resultaten opleverden, ook al lijkt de substring voor elk document op dezelfde positie te staan. In het eerste document werd de substring gevonden op byte-indexpositie 2
, terwijl het tweede document het had op 3
.
De reden hiervoor is dat het copyright-symbool (©
) in het tweede document neemt 2 bytes in beslag. De c
karakter (in het eerste document) gebruikt slechts 1 byte. Het spatieteken gebruikt ook 1 byte.
Het resultaat van $indexOfBytes
is gebaseerd op nul (de index begint bij 0
), en dus eindigen we met een resultaat van 2
en 3
respectievelijk.
Wat betreft het derde document, de substring werd helemaal niet gevonden, en dus is het resultaat -1
.
Hier is nog een voorbeeld, maar deze keer zoeken we naar een Thais karakter:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "เ" ] }
}
}
]
)
Resultaat:
{ "data" : "c 2021", "result" : -1 } { "data" : "© 2021", "result" : -1 } { "data" : "ไม้เมือง", "result" : 9 }
In dit geval hebben we gezocht naar een teken dat op de derde positie in het derde document staat, en de UTF-8 byte-index komt terug als 9
.
Dit komt omdat in dit geval elk teken 3 bytes gebruikt. Maar het tweede teken heeft een diakritisch teken, dat ook 3 bytes is. Daarom gebruiken de eerste twee tekens (inclusief het diakritische teken) 9 bytes. Gezien de op nul gebaseerde indexering, variëren hun UTF-8-byte-indexen van 0
tot 8
. Dit betekent dat het derde teken begint op positie 9
.
Zie MongoDB $strLenBytes
voor een voorbeeld dat het aantal bytes voor elk teken in deze specifieke tekenreeks retourneert.
Geef een startpositie op
U kunt een derde argument opgeven om een startindexpositie voor de zoekopdracht op te geven.
Stel dat we het volgende document hebben:
{ "_id" : 4, "data" : "ABC XYZ ABC" }
Hier is een voorbeeld van het toepassen van $indexOfBytes
met een startpositie:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "ABC", 1 ] }
}
}
]
)
Resultaat:
{ "data" : "ABC XYZ ABC", "result" : 8 }
In dit geval is het tweede exemplaar van de subtekenreeks geretourneerd. Dit komt omdat we de zoekopdracht zijn begonnen op positie 1
, en de eerste instantie van de substring begint op positie 0
(vóór de startpositie voor de zoekopdracht).
Als de startpositie een getal is dat groter is dan de bytelengte van de tekenreeks of groter is dan de eindpositie, $indexOfBytes
retourneert -1
.
Als het een negatief getal is, $indexOfBytes
geeft een fout terug.
Geef een eindpositie op
U kunt ook een vierde argument opgeven om de eindindexpositie voor de zoekopdracht te specificeren.
Als u dit argument geeft, moet u ook een startpositie opgeven. Als u dit niet doet, wordt dit argument als het startpunt geïnterpreteerd.
Voorbeeld:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ", 0, 5 ] }
}
}
]
)
Resultaat:
{ "data" : "ABC XYZ ABC", "result" : -1 }
Het resultaat is -1
wat betekent dat de substring niet is gevonden. Dat komt omdat we onze zoektocht begonnen op positie 0
en eindigde op positie 5
, dus de substring niet vastleggen.
Dit is wat er gebeurt als we de eindindexpositie verhogen:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ", 0, 7 ] }
}
}
]
)
Resultaat:
{ "data" : "ABC XYZ ABC", "result" : 4 }
Deze keer werd de waarde opgenomen en keerde de indexpositie terug.
Als de eindpositie een getal kleiner is dan de beginpositie, $indexOfBytes
retourneert -1
.
Als het een negatief getal is, $indexOfBytes
geeft een fout terug.
Ontbrekende velden
Als het veld niet in het document staat, $indexOfBytes
retourneert null
.
Stel dat we het volgende document hebben:
{ "_id" : 5 }
Dit is wat er gebeurt als we $indexOfBytes
toepassen :
db.test.aggregate(
[
{ $match: { _id: { $in: [ 5 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ" ] }
}
}
]
)
Resultaat:
{ "result" : null }
Null-waarden
Als het eerste argument null
. is , $indexOfBytes
retourneert null
.
Stel dat we het volgende document hebben:
{ "_id" : 6, "data" : null }
Dit is wat er gebeurt als we $indexOfBytes
toepassen :
db.test.aggregate(
[
{ $match: { _id: { $in: [ 6 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ" ] }
}
}
]
)
Resultaat:
{ "data" : null, "result" : null }
Echter, wanneer het tweede argument (d.w.z. de substring) null
. is , er wordt een fout geretourneerd:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", null ] }
}
}
]
)
Resultaat:
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
Onjuist gegevenstype
Als het eerste argument het verkeerde gegevenstype is (d.w.z. het wordt niet omgezet in een tekenreeks), $indexOfBytes
geeft een fout terug.
Stel dat we het volgende document hebben:
{ "_id" : 7, "data" : 123 }
Dit is wat er gebeurt als we $indexOfBytes
toepassen naar dat document:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 7 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ" ] }
}
}
]
)
Resultaat:
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
Zoals de foutmelding aangeeft, vereist $indexOfBytes requires a string as the first argument
.