V MongoDB, $indexOfBytes
Operátor agregačního kanálu hledá v řetězci výskyt podřetězce a vrací UTF-8 bajtový index prvního výskytu.
Bajtový index UTF je založen na nule (tj. začíná na 0
).
Syntaxe
Syntaxe vypadá takto:
{ $indexOfBytes: [ <string expression>, <substring expression>, <start>, <end> ] }
Kde:
<string expression>
je řetězec, který se má hledat.<substring expression>
je podřetězec, který chcete v řetězci najít.<start>
je volitelný argument, který určuje počáteční pozici indexu pro vyhledávání. Může to být jakýkoli platný výraz, který se převádí na nezáporné celé číslo.<end>
je volitelný argument, který určuje koncovou pozici indexu pro vyhledávání. Může to být jakýkoli platný výraz, který se převádí na nezáporné celé číslo.
Pokud zadaná hodnota není nalezena, $indexOfBytes
vrátí -1
.
Pokud existuje více instancí zadané hodnoty, vrátí se pouze první.
Příklad
Předpokládejme, že máme kolekci nazvanou test
s následujícími dokumenty:
{ "_id" : 1, "data" : "c 2021" } { "_id" : 2, "data" : "© 2021" } { "_id" : 3, "data" : "ไม้เมือง" }
Zde je příklad použití $indexOfBytes
k těm dokumentům:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "2021" ] }
}
}
]
)
Výsledek:
{ "data" : "c 2021", "result" : 2 } { "data" : "© 2021", "result" : 3 } { "data" : "ไม้เมือง", "result" : -1 }
Můžeme vidět, že první dva dokumenty přinesly různé výsledky, i když se zdá, že podřetězec je u každého dokumentu na stejné pozici. V prvním dokumentu byl podřetězec nalezen na pozici indexu bajtu 2
, zatímco druhý dokument měl hodnotu 3
.
Důvodem je, že symbol autorských práv (©
) ve druhém dokumentu zabírá 2 bajty. c
znak (v prvním dokumentu) používá pouze 1 bajt. Znak mezery také používá 1 bajt.
Výsledek $indexOfBytes
je založen na nule (index začíná na 0
), a tak skončíme s výsledkem 2
a 3
respektive.
Pokud jde o třetí dokument, podřetězec nebyl vůbec nalezen, takže výsledek je -1
.
Zde je další příklad, ale tentokrát hledáme thajský znak:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "เ" ] }
}
}
]
)
Výsledek:
{ "data" : "c 2021", "result" : -1 } { "data" : "© 2021", "result" : -1 } { "data" : "ไม้เมือง", "result" : 9 }
V tomto případě jsme hledali znak, který se objevuje na třetí pozici ve třetím dokumentu, a jeho UTF-8 bajtový index se vrátí jako 9
.
V tomto případě totiž každý znak používá 3 bajty. Ale druhý znak má diakritické znaménko, které má také 3 bajty. Proto první dva znaky (včetně diakritiky) používají 9 bajtů. Vzhledem k indexování založenému na nule se jejich indexy UTF-8 bajtů pohybují od 0
až 8
. To znamená, že třetí znak začíná na pozici 9
.
Viz MongoDB $strLenBytes
pro příklad, který vrací počet bajtů pro každý znak v tomto konkrétním řetězci.
Určete počáteční pozici
Můžete zadat třetí argument pro určení počáteční pozice indexu pro vyhledávání.
Předpokládejme, že máme následující dokument:
{ "_id" : 4, "data" : "ABC XYZ ABC" }
Zde je příklad použití $indexOfBytes
s výchozí pozicí:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "ABC", 1 ] }
}
}
]
)
Výsledek:
{ "data" : "ABC XYZ ABC", "result" : 8 }
V tomto případě byla vrácena druhá instance podřetězce. Důvodem je, že jsme zahájili vyhledávání na pozici 1
a první výskyt podřetězce začíná na pozici 0
(před výchozí pozicí pro vyhledávání).
Pokud je počáteční pozice číslo větší než bajtová délka řetězce nebo větší než koncová pozice, $indexOfBytes
vrátí -1
.
Pokud je to záporné číslo, $indexOfBytes
vrátí chybu.
Určete koncovou pozici
Můžete také zadat čtvrtý argument pro určení koncové pozice indexu pro vyhledávání.
Pokud uvedete tento argument, musíte také uvést výchozí pozici. Pokud tak neučiníte, bude tento argument interpretován jako výchozí bod.
Příklad:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ", 0, 5 ] }
}
}
]
)
Výsledek:
{ "data" : "ABC XYZ ABC", "result" : -1 }
Výsledek je -1
což znamená, že podřetězec nebyl nalezen. Je to proto, že jsme zahájili vyhledávání na pozici 0
a skončil na pozici 5
, tudíž nezachycuje podřetězec.
Pokud zvýšíme koncovou pozici indexu, stane se toto:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ", 0, 7 ] }
}
}
]
)
Výsledek:
{ "data" : "ABC XYZ ABC", "result" : 4 }
Tentokrát byla hodnota zahrnuta a její indexová pozice byla vrácena.
Pokud je koncová pozice o číslo menší než počáteční pozice, $indexOfBytes
vrátí -1
.
Pokud je to záporné číslo, $indexOfBytes
vrátí chybu.
Chybějící pole
Pokud pole není v dokumentu, $indexOfBytes
vrátí null
.
Předpokládejme, že máme následující dokument:
{ "_id" : 5 }
Zde je to, co se stane, když použijeme $indexOfBytes
:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 5 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ" ] }
}
}
]
)
Výsledek:
{ "result" : null }
Nulové hodnoty
Pokud je první argument null
, $indexOfBytes
vrátí null
.
Předpokládejme, že máme následující dokument:
{ "_id" : 6, "data" : null }
Zde je to, co se stane, když použijeme $indexOfBytes
:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 6 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ" ] }
}
}
]
)
Výsledek:
{ "data" : null, "result" : null }
Pokud je však druhý argument (tj. podřetězec) null
, je vrácena chyba:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", null ] }
}
}
]
)
Výsledek:
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
Nesprávný datový typ
Pokud je prvním argumentem nesprávný datový typ (tj. nelze jej přeložit na řetězec), $indexOfBytes
vrátí chybu.
Předpokládejme, že máme následující dokument:
{ "_id" : 7, "data" : 123 }
Zde je to, co se stane, když použijeme $indexOfBytes
k tomuto dokumentu:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 7 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ" ] }
}
}
]
)
Výsledek:
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
Jak uvádí chybová zpráva, $indexOfBytes requires a string as the first argument
.