V MongoDB, $substrCP
Operátor agregačního kanálu vrací podřetězec řetězce na základě zadaných indexů bodů kódu UTF-8.
Syntaxe
Syntaxe vypadá takto:
{ $substrCP: [ <string expression>, <code point index>, <code point 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.<code point 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.<code point count>
udává, kolik bodů kódu by měl 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 $substrCP
takhle:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$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 tři body kódu.
V tomto případě používáme anglické znaky a každý znak má jeden kódový bod. To nám usnadňuje spočítat, kolik kódových bodů použít.
Uveďme další příklad:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result_1: { $substrCP: [ "$data", 4, 4 ] },
result_2: { $substrCP: [ "$data", 8, 5 ] },
result_3: { $substrCP: [ "$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 bodů kódu, než bylo k dispozici, ale jednoduše vrátil všechny znaky na konec řetězce.
Diakritická znaménka
Některé znaky mají přidanou diakritickou znaménka, což má za následek více kódových bodů.
Předpokládejme, že máme kolekci nazvanou thai
který obsahuje následující dokumenty:
{ "_id" : 1, "data" : "ไม้เมือง" } { "_id" : 2, "data" : "ไ" } { "_id" : 3, "data" : "ม้" } { "_id" : 4, "data" : "เ" } { "_id" : 5, "data" : "มื" } { "_id" : 6, "data" : "อ" } { "_id" : 7, "data" : "ง" }
Tyto dokumenty obsahují thajské znaky. Vidíme, že dva z těchto znaků obsahují diakritiku (malý glyf nad počátečním glyfem).
Dokumenty 2 až 7 jednoduše vypíšou všechny znaky, které jsou v dokumentu 1.
Než vezmeme podřetězec, pomocí $strLenCP
zjistíme, kolik kódových bodů má každý z těchto znaků operátor:
db.thai.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
result: { $strLenCP: "$data" }
}
}
]
)
Výsledek:
{ "data" : "ไม้เมือง", "result" : 8 } { "data" : "ไ", "result" : 1 } { "data" : "ม้", "result" : 2 } { "data" : "เ", "result" : 1 } { "data" : "มื", "result" : 2 } { "data" : "อ", "result" : 1 } { "data" : "ง", "result" : 1 }
Vidíme, že dva znaky s diakritikou mají dva kódové body a ostatní jeden kód.
Aplikujme $substrCP
k prvnímu dokumentu:
db.thai.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 2 ] }
}
}
]
)
Výsledek:
{ "data" : "ไม้เมือง", "result" : "ม้" }
Na základě našeho výchozího bodu 1
a náš počet bodů v kódu 2
, dostaneme druhý znak a s ním související diakritiku.
Oddělte glyfy
V předchozím příkladu byl náš třetí argument 2, takže vrátil znak a diakritiku dohromady. Zde je to, co se stane, když poskytneme třetí argument 1.
db.thai.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 1 ] }
}
}
]
)
Výsledek:
{ "data" : "ไม้เมือง", "result" : "ม" }
První znak je vrácen bez diakritického znaménka.
Další typy dat
$substrCP
operátor funguje pouze na řetězcích. Pokud však máte jiný datový typ, měl by stále fungovat, pokud se může přeložit na řetězec.
Předpokládejme, že máme následující dokument:
{ "_id" : 2, "data" : 123456 }
data
pole obsahuje číslo.
Zde je to, co se stane, když použijeme $substrCP
do tohoto pole:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 2 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 2 ] }
}
}
]
)
Výsledek:
{ "data" : 123456, "result" : "23" }
Zvládlo to udělat dobře (i když mějte na paměti, že výsledkem je řetězec – nikoli číslo).
Máme další dokument s objektem Date:
{ "_id" : 3, "data" : ISODate("2021-01-03T23:30:15.100Z") }
Nyní použijeme $substrCP
k tomuto dokumentu:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 3 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 0, 4 ] }
}
}
]
)
Výsledek:
{ "data" : ISODate("2021-01-03T23:30:15.100Z"), "result" : "2021" }
Takže to fungovalo dobře i v tomto scénáři.
Nulové hodnoty
Pokud je řetězec null
, výsledkem je prázdný řetězec.
Předpokládejme, že máme následující dokument:
{ "_id" : 4, "data" : null }
Zde je to, co se stane, když použijeme $substrCP
k tomuto dokumentu:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 2 ] }
}
}
]
)
Výsledek:
{ "data" : null, "result" : "" }
Chybějící pole
Pokus o získání podřetězce z pole, které neexistuje, má za následek prázdný řetězec.
Předpokládejme, že máme následující dokument:
{ "_id" : 5 }
Použijte $substrCP
:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 5 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 2 ] }
}
}
]
)
Výsledek:
{ "result" : "" }