I MongoDB, $indexOfBytes
aggregeringspipeline-operatorn söker i en sträng efter en förekomst av en delsträng och returnerar UTF-8-byteindex för den första förekomsten.
UTF-byteindexet är nollbaserat (dvs. det börjar vid 0
).
Syntax
Syntaxen ser ut så här:
{ $indexOfBytes: [ <string expression>, <substring expression>, <start>, <end> ] }
Var:
är strängen att söka.
är den delsträng du vill hitta i strängen.är ett valfritt argument som anger en startindexposition för sökningen. Kan vara vilket giltigt uttryck som helst som löser sig till ett icke-negativt heltal.
är ett valfritt argument som anger en slutindexposition för sökningen. Kan vara vilket giltigt uttryck som helst som löser sig till ett icke-negativt heltal.
Om det angivna värdet inte hittas, $indexOfBytes
returnerar -1
.
Om det finns flera instanser av det angivna värdet, returneras bara den första.
Exempel
Anta att vi har en samling som heter test
med följande dokument:
{ "_id" : 1, "data" : "c 2021" } { "_id" : 2, "data" : "© 2021" } { "_id" : 3, "data" : "ไม้เมือง" }
Här är ett exempel på hur du använder $indexOfBytes
till dessa dokument:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "2021" ] }
}
}
]
)
Resultat:
{ "data" : "c 2021", "result" : 2 } { "data" : "© 2021", "result" : 3 } { "data" : "ไม้เมือง", "result" : -1 }
Vi kan se att de två första dokumenten gav olika resultat, även om delsträngen verkar vara i samma position för varje dokument. I det första dokumentet hittades understrängen vid byteindexposition 2
, medan det andra dokumentet hade det på 3
.
Anledningen till detta är att copyright-symbolen (©
) i det andra dokumentet tar upp 2 byte. c
tecken (i det första dokumentet) använder bara 1 byte. Mellanslagstecknet använder också 1 byte.
Resultatet av $indexOfBytes
är nollbaserat (indexet börjar på 0
), och så får vi resultatet 2
och 3
respektive.
När det gäller det tredje dokumentet hittades inte understrängen alls, så resultatet är -1
.
Här är ett annat exempel, förutom den här gången söker vi efter ett thailändskt tecken:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "เ" ] }
}
}
]
)
Resultat:
{ "data" : "c 2021", "result" : -1 } { "data" : "© 2021", "result" : -1 } { "data" : "ไม้เมือง", "result" : 9 }
I det här fallet sökte vi efter ett tecken som visas på den tredje positionen i det tredje dokumentet, och dess UTF-8-byteindex kommer tillbaka som 9
.
Detta beror på att i det här fallet använder varje tecken 3 byte. Men det andra tecknet har ett diakritiskt tecken, som också är 3 byte. Därför använder de två första tecknen (inklusive diakritiken) 9 byte. Med tanke på den nollbaserade indexeringen sträcker sig deras UTF-8-byteindex från 0
till 8
. Det betyder att det tredje tecknet börjar på position 9
.
Se MongoDB $strLenBytes
för ett exempel som returnerar antalet byte för varje tecken i just den här strängen.
Ange en startposition
Du kan ange ett tredje argument för att ange en startindexposition för sökningen.
Anta att vi har följande dokument:
{ "_id" : 4, "data" : "ABC XYZ ABC" }
Här är ett exempel på hur du använder $indexOfBytes
med en startposition:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "ABC", 1 ] }
}
}
]
)
Resultat:
{ "data" : "ABC XYZ ABC", "result" : 8 }
I det här fallet returnerades den andra instansen av delsträngen. Detta beror på att vi startade sökningen vid position 1
, och den första instansen av delsträngen börjar vid position 0
(före startpositionen för sökningen).
Om startpositionen är ett tal större än strängens bytelängd eller större än slutpositionen, $indexOfBytes
returnerar -1
.
Om det är ett negativt tal, $indexOfBytes
returnerar ett fel.
Ange en slutposition
Du kan också ange ett fjärde argument för att ange slutindexpositionen för sökningen.
Om du ger detta argument måste du också ange en utgångsposition. Underlåtenhet att göra det kommer att resultera i att detta argument tolkas som utgångspunkten.
Exempel:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ", 0, 5 ] }
}
}
]
)
Resultat:
{ "data" : "ABC XYZ ABC", "result" : -1 }
Resultatet är -1
vilket betyder att delsträngen inte hittades. Det beror på att vi började vår sökning på position 0
och avslutade den på position 5
, därför inte fånga understrängen.
Så här händer om vi ökar slutindexpositionen:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ", 0, 7 ] }
}
}
]
)
Resultat:
{ "data" : "ABC XYZ ABC", "result" : 4 }
Den här gången inkluderades värdet och dess indexposition returnerades.
Om slutpositionen är ett nummer mindre än startpositionen, $indexOfBytes
returnerar -1
.
Om det är ett negativt tal, $indexOfBytes
returnerar ett fel.
Fält saknas
Om fältet inte finns i dokumentet, $indexOfBytes
returnerar null
.
Anta att vi har följande dokument:
{ "_id" : 5 }
Det här är vad som händer när vi använder $indexOfBytes
:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 5 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ" ] }
}
}
]
)
Resultat:
{ "result" : null }
Nullvärden
Om det första argumentet är null
, $indexOfBytes
returnerar null
.
Anta att vi har följande dokument:
{ "_id" : 6, "data" : null }
Det här är vad som händer när vi använder $indexOfBytes
:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 6 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ" ] }
}
}
]
)
Resultat:
{ "data" : null, "result" : null }
Men när det andra argumentet (d.v.s. delsträngen) är null
, returneras ett fel:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", null ] }
}
}
]
)
Resultat:
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
Fel datatyp
Om det första argumentet är fel datatyp (dvs. det löser sig inte till en sträng), $indexOfBytes
returnerar ett fel.
Anta att vi har följande dokument:
{ "_id" : 7, "data" : 123 }
Det här är vad som händer när vi använder $indexOfBytes
till det dokumentet:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 7 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ" ] }
}
}
]
)
Resultat:
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
Som felmeddelandet säger kräver $indexOfBytes en sträng som första argument
.