V MongoDB, $substrBytes
Operátor agregačního kanálu vrací podřetězec řetězce na základě zadaných indexů bajtů kódovaných UTF-8.
Syntaxe
Syntaxe vypadá takto:
{ $substrBytes: [ <string expression>, <byte index>, <byte count> ] }
Kde:
<string expression>
je řetězec. Může to být jakýkoli platný výraz, pokud se překládá na řetězec.<byte index>
je místo, kde začít podřetězec. Může to být jakýkoli platný výraz, pokud se převede na nezáporné celé číslo nebo číslo, které lze reprezentovat jako celé číslo.<byte count>
udává, kolik bajtů má podřetězec pokračovat. Může to být jakýkoli platný výraz, pokud se převede na nezáporné celé číslo nebo číslo, které lze reprezentovat jako celé číslo.
Příklad
Představte si, že máme kolekci nazvanou tests
s následujícím dokumentem:
{ "_id" : 1, "data" : "Red Firetruck" }
Můžeme použít $substrBytes
takhle:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrBytes: [ "$data", 0, 3 ] }
}
}
]
)
Výsledek:
{ "data" : "Red Firetruck", "result" : "Red" }
Index začíná na nule, takže náš podřetězec začal na začátku řetězce a pokračoval po dobu tří bajtů.
V tomto případě používáme anglické znaky a každý znak je jeden bajt. To nám usnadňuje spočítat, kolik bajtů použít.
Uveďme další příklad:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result_1: { $substrBytes: [ "$data", 4, 4 ] },
result_2: { $substrBytes: [ "$data", 8, 5 ] },
result_3: { $substrBytes: [ "$data", 8, 20 ] }
}
}
]
).pretty()
Výsledek:
{ "data" : "Red Firetruck", "result_1" : "Fire", "result_2" : "truck", "result_3" : "truck" }
Všimněte si, že v našem třetím výsledku jsme zadali více bajtů, než bylo k dispozici, ale jednoduše vrátil všechny znaky na konec řetězce.
Vícebajtové znaky
Některé znaky používají více než jeden bajt. Někdo používá dvě, někdo tři a někdo dokonce čtyři.
Zde je příklad dokumentu, který obsahuje spoustu symbolů:
{ "_id" : 2, "data" : "©♡★✪☆" }
Každý z těchto znaků používá více než jeden bajt. To znamená, že při extrakci podřetězce musíme být opatrní. Musíme si být jisti, že náš výchozí bod nezačíná v polovině postavy. Pokud ano, dojde k chybě. Stejně tak musíme zajistit, aby náš koncový bod neskončil v polovině postavy.
Prozatím použijeme $substrBytes
aniž by došlo k chybě:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 2 ] } } },
{
$project:
{
_id: 0,
data: 1,
bytes: { $strLenBytes: [ "$data" ] },
result: { $substrBytes: [ "$data", 0, 5 ] }
}
}
]
)
Výsledek:
{ "data" : "©♡★✪☆", "bytes" : 14, "result" : "©♡" }
Na základě našeho výchozího bodu 0
a naše byte délka 5
, dostaneme dva znaky v naší výsledkové sadě. Můžeme tedy vidět, že první dva znaky používají 5 bajtů.
V tomto příkladu jsem také použil $strLenBytes
vrátit celkový počet bajtů v řetězci. Udělal jsem to hlavně proto, abych ukázal, že těchto pět znaků používá 14 bajtů (více bajtů na znak).
Zde je mírně upravený příklad, který vrací každý ze dvou vrácených znaků:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 2 ] } } },
{
$project:
{
_id: 0,
data: 1,
r1: { $substrBytes: [ "$data", 0, 2 ] },
r2: { $substrBytes: [ "$data", 2, 3 ] }
}
}
]
)
Výsledek:
{ "data" : "©♡★✪☆", "r1" : "©", "r2" : "♡" }
Vidíme, že první znak používá dva bajty a druhý znak tři.
Špatný výchozí bod
Pokud je váš výchozí bod v polovině postavy, dojde k chybě.
Příklad:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 2 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrBytes: [ "$data", 1, 2 ] }
}
}
]
)
Výsledek:
Error: command failed: { "ok" : 0, "errmsg" : "$substrBytes: Invalid range, starting index is a UTF-8 continuation byte.", "code" : 28656, "codeName" : "Location28656" } : 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
Tato chyba nám říká, že starting index is a UTF-8 continuation byte
. Jinými slovy, pokusili jsme se začít v polovině postavy.
Špatný koncový bod
Stejné je to s koncovým bodem. Pokud je váš koncový bod v polovině znaku, dojde k chybě.
Příklad:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 2 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrBytes: [ "$data", 0, 1 ] }
}
}
]
)
Výsledek:
Error: command failed: { "ok" : 0, "errmsg" : "$substrBytes: Invalid range, ending index is in the middle of a UTF-8 character.", "code" : 28657, "codeName" : "Location28657" } : 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
Tentokrát nám říká, že ending index is in the middle of a UTF-8 character
.