В MongoDB, $substrCP
Операторът на тръбопровода за агрегиране връща подниза на низ въз основа на посочените индекси на кодовата точка UTF-8.
Синтаксис
Синтаксисът е така:
{ $substrCP: [ <string expression>, <code point index>, <code point count> ] }
Къде:
<string expression>
е низът. Може да бъде всеки валиден израз, стига да се разрешава в низ.<code point index>
е откъде да започне поднизът. Може да бъде всеки валиден израз, стига да се разреши до неотрицателно цяло число.<code point count>
е за колко кодови точки трябва да продължи поднизът. Може да бъде всеки валиден израз, стига да се разреши до неотрицателно цяло число или число, което може да бъде представено като цяло число.
Пример
Представете си, че имаме колекция, наречена tests
със следния документ:
{ "_id" : 1, "data" : "Red Firetruck" }
Можем да използваме $substrCP
така:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 0, 3 ] }
}
}
]
)
Резултат:
{ "data" : "Red Firetruck", "result" : "Red" }
Индексът започва от нула и така нашият подниз започва в началото на низа и продължава три кодови точки.
В този случай използваме английски знаци и всеки знак има една кодова точка. Това ни улеснява да преброим колко кодови точки да използваме.
Нека изпълним друг пример:
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()
Резултат:
{ "data" : "Red Firetruck", "result_1" : "Fire", "result_2" : "truck", "result_3" : "truck" }
Забележете, че в нашия трети резултат посочихме повече кодови точки, отколкото бяха налични, но той просто върна всички знаци в края на низа.
Диакритични знаци
Някои знаци имат добавен диакритичен знак, което води до множество кодови точки.
Да предположим, че имаме колекция, наречена thai
който съдържа следните документи:
{ "_id" : 1, "data" : "ไม้เมือง" } { "_id" : 2, "data" : "ไ" } { "_id" : 3, "data" : "ม้" } { "_id" : 4, "data" : "เ" } { "_id" : 5, "data" : "มื" } { "_id" : 6, "data" : "อ" } { "_id" : 7, "data" : "ง" }
Тези документи съдържат тайландски знаци. Можем да видим, че два от тези символа включват диакрит (малък глиф над първоначалния глиф).
Документи от 2 до 7 просто изброяват всеки от знаците, които са в документ 1.
Преди да вземем подниз, нека разберем колко кодови точки има всеки от тези знаци, като използваме $strLenCP
оператор:
db.thai.aggregate(
[
{
$project:
{
_id: 0,
data: 1,
result: { $strLenCP: "$data" }
}
}
]
)
Резултат:
{ "data" : "ไม้เมือง", "result" : 8 } { "data" : "ไ", "result" : 1 } { "data" : "ม้", "result" : 2 } { "data" : "เ", "result" : 1 } { "data" : "มื", "result" : 2 } { "data" : "อ", "result" : 1 } { "data" : "ง", "result" : 1 }
Виждаме, че двата знака с диакритични знаци имат две кодови точки, а останалите имат една кодова точка.
Нека приложим $substrCP
към първия документ:
db.thai.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 2 ] }
}
}
]
)
Резултат:
{ "data" : "ไม้เมือง", "result" : "ม้" }
Въз основа на нашата начална точка от 1
и нашия брой кодови точки от 2
, получаваме втория знак и свързания с него диакритичен знак.
Разделете глифовете
В предишния пример нашият трети аргумент беше 2, така че връща знака и диакритиката заедно. Ето какво се случва, когато предоставим трети аргумент от 1.
db.thai.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 1 ] }
}
}
]
)
Резултат:
{ "data" : "ไม้เมือง", "result" : "ม" }
Първият знак се връща без диакритичния знак.
Други типове данни
$substrCP
операторът работи само върху низове. Ако обаче имате друг тип данни, той трябва да работи, стига да може да се разреши до низ.
Да предположим, че имаме следния документ:
{ "_id" : 2, "data" : 123456 }
data
полето съдържа число.
Ето какво се случва, когато приложим $substrCP
към това поле:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 2 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 2 ] }
}
}
]
)
Резултат:
{ "data" : 123456, "result" : "23" }
Той успя да свърши добре работата (въпреки че имайте предвид, че резултатът е низ, а не число).
Имаме друг документ с обект Date:
{ "_id" : 3, "data" : ISODate("2021-01-03T23:30:15.100Z") }
Сега нека приложим $substrCP
към този документ:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 3 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 0, 4 ] }
}
}
]
)
Резултат:
{ "data" : ISODate("2021-01-03T23:30:15.100Z"), "result" : "2021" }
Така че работи добре и в този сценарий.
Нулеви стойности
Ако низът е null
, резултатът е празен низ.
Да предположим, че имаме следния документ:
{ "_id" : 4, "data" : null }
Ето какво се случва, когато приложим $substrCP
към този документ:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 2 ] }
}
}
]
)
Резултат:
{ "data" : null, "result" : "" }
Липсващо поле
Опитът за получаване на подниз от поле, което не съществува, води до празен низ.
Да предположим, че имаме следния документ:
{ "_id" : 5 }
Приложете $substrCP
:
db.test.aggregate(
[
{ $match: { _id: { $in: [ 5 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $substrCP: [ "$data", 1, 2 ] }
}
}
]
)
Резултат:
{ "result" : "" }