MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

MongoDB $substrCP


No MongoDB, o $substrCP O operador de pipeline de agregação retorna a substring de uma string, com base nos índices de ponto de código UTF-8 especificados.

Sintaxe


A sintaxe fica assim:
{ $substrCP: [ <string expression>, <code point index>, <code point count> ] }

Onde:
  • <string expression> é a corda. Pode ser qualquer expressão válida, desde que resolva para uma string.
  • <code point index> é onde iniciar a substring. Pode ser qualquer expressão válida, desde que resolva para um número inteiro não negativo.
  • <code point count> é quantos pontos de código a substring deve continuar. Pode ser qualquer expressão válida, desde que resolva para um número inteiro não negativo ou número que possa ser representado como um inteiro.

Exemplo


Imagine que temos uma coleção chamada tests com o seguinte documento:
{ "_id" : 1, "data" : "Red Firetruck" }

Podemos usar $substrCP assim:
db.test.aggregate(
   [
     { $match: { _id: { $in: [ 1 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $substrCP: [ "$data", 0, 3 ] }
          }
     }
   ]
)

Resultado:
{ "data" : "Red Firetruck", "result" : "Red" }

O índice começa em zero e, portanto, nossa substring começou no início da string e continuou por três pontos de código.

Nesse caso, estamos usando caracteres em inglês e cada caractere possui um ponto de código. Isso facilita a contagem de quantos pontos de código usar.

Vamos executar outro exemplo:
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()

Resultado:
{
	"data" : "Red Firetruck",
	"result_1" : "Fire",
	"result_2" : "truck",
	"result_3" : "truck"
}

Observe que em nosso terceiro resultado, especificamos mais pontos de código do que estavam disponíveis, mas ele simplesmente retornou todos os caracteres ao final da string.

Marcas diacríticas


Alguns caracteres têm uma marca diacrítica adicionada, resultando em vários pontos de código.

Suponha que tenhamos uma coleção chamada thai que contém os seguintes documentos:
{ "_id" : 1, "data" : "ไม้เมือง" }
{ "_id" : 2, "data" : "ไ" }
{ "_id" : 3, "data" : "ม้" }
{ "_id" : 4, "data" : "เ" }
{ "_id" : 5, "data" : "มื" }
{ "_id" : 6, "data" : "อ" }
{ "_id" : 7, "data" : "ง" }

Esses documentos contêm caracteres tailandeses. Podemos ver que dois desses caracteres incluem um diacrítico (um pequeno glifo acima do glifo inicial).

Os documentos de 2 a 7 simplesmente listam cada um dos caracteres que estão no documento 1.

Antes de pegarmos uma substring, vamos descobrir quantos code points cada um desses caracteres tem usando o $strLenCP operador:
db.thai.aggregate(
   [
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $strLenCP: "$data" }
          }
     }
   ]
)

Resultado:
{ "data" : "ไม้เมือง", "result" : 8 }
{ "data" : "ไ", "result" : 1 }
{ "data" : "ม้", "result" : 2 }
{ "data" : "เ", "result" : 1 }
{ "data" : "มื", "result" : 2 }
{ "data" : "อ", "result" : 1 }
{ "data" : "ง", "result" : 1 }

Podemos ver que os dois caracteres com os diacríticos têm dois pontos de código e os outros têm um ponto de código.

Vamos aplicar $substrCP ao primeiro documento:
db.thai.aggregate(
   [
     { $match: { _id: { $in: [ 1 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $substrCP: [ "$data", 1, 2 ] }
          }
     }
   ]
)

Resultado:
{ "data" : "ไม้เมือง", "result" : "ม้" }

Com base em nosso ponto de partida de 1 e nossa contagem de pontos de código de 2 , obtemos o segundo caractere e seu diacrítico associado.

Separe os glifos


No exemplo anterior, nosso terceiro argumento era 2 para que retornasse o caractere e o diacrítico juntos. Aqui está o que acontece quando fornecemos um terceiro argumento de 1.
db.thai.aggregate(
   [
     { $match: { _id: { $in: [ 1 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $substrCP: [ "$data", 1, 1 ] }
          }
     }
   ]
)

Resultado:
{ "data" : "ไม้เมือง", "result" : "ม" }

O primeiro caractere é retornado sem a marca diacrítica.

Outros tipos de dados


O $substrCP operador só funciona em strings. No entanto, se você tiver outro tipo de dados, ele ainda funcionará, desde que possa ser resolvido para uma string.

Suponha que temos o seguinte documento:
{ "_id" : 2, "data" : 123456 }

Os data campo contém um número.

Veja o que acontece quando aplicamos $substrCP para esse campo:
db.test.aggregate(
   [
     { $match: { _id: { $in: [ 2 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $substrCP: [ "$data", 1, 2 ] }
          }
     }
   ]
)

Resultado:
{ "data" : 123456, "result" : "23" }

Ele conseguiu fazer o trabalho bem (embora tenha em mente que o resultado é uma string – não um número).

Temos outro documento com um objeto Date:
{ "_id" : 3, "data" : ISODate("2021-01-03T23:30:15.100Z") }

Agora vamos aplicar $substrCP a esse documento:
db.test.aggregate(
   [
     { $match: { _id: { $in: [ 3 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $substrCP: [ "$data", 0, 4 ] }
          }
     }
   ]
)

Resultado:
{ "data" : ISODate("2021-01-03T23:30:15.100Z"), "result" : "2021" }

Então funcionou bem neste cenário também.

Valores nulos


Se a string for null , o resultado é uma string vazia.

Suponha que temos o seguinte documento:
{ "_id" : 4, "data" : null }

Veja o que acontece quando aplicamos $substrCP a esse documento:
db.test.aggregate(
   [
     { $match: { _id: { $in: [ 4 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $substrCP: [ "$data", 1, 2 ] }
          }
     }
   ]
)

Resultado:
{ "data" : null, "result" : "" }

Campo ausente


A tentativa de obter uma substring de um campo que não existe resulta em uma string vazia.

Suponha que temos o seguinte documento:
{ "_id" : 5 } 

Aplicar $substrCP :
db.test.aggregate(
   [
     { $match: { _id: { $in: [ 5 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $substrCP: [ "$data", 1, 2 ] }
          }
     }
   ]
)

Resultado:
{ "result" : "" }