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

MongoDB $indexOfCP


No MongoDB, o $indexOfCP O operador de pipeline de agregação pesquisa uma string para uma ocorrência de uma substring e retorna o índice de ponto de código UTF da primeira ocorrência.

O índice de ponto de código UTF é baseado em zero (ou seja, começa em 0 ).

Sintaxe


A sintaxe fica assim:
{ $indexOfCP: [ <string expression>, <substring expression>, <start>, <end> ] }

Onde:
  • <string expression> é a string a ser pesquisada.
  • <substring expression> é a substring que você deseja encontrar na string.
  • <start> é um argumento opcional que especifica uma posição de índice inicial para a pesquisa. Pode ser qualquer expressão válida que resolva para um número inteiro não negativo.
  • <end> é um argumento opcional que especifica uma posição de índice final para a pesquisa. Pode ser qualquer expressão válida que resolva para um número inteiro não negativo.

Se o valor especificado não for encontrado, $indexOfCP retorna -1 .

Se houver várias instâncias do valor especificado, apenas a primeira será retornada.

Exemplo


Suponha que tenhamos uma coleção chamada test com os seguintes documentos:
{ "_id" : 1, "data" : "c 2021" }
{ "_id" : 2, "data" : "© 2021" }
{ "_id" : 3, "data" : "ไม้เมือง" }

Aqui está um exemplo de aplicação de $indexOfCP a esses documentos:
db.test.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfCP: [ "$data", "2021" ] }
          }
     }
   ]
)

Resultado:
{ "data" : "c 2021", "result" : 2 }
{ "data" : "© 2021", "result" : 2 }
{ "data" : "ไม้เมือง", "result" : -1 }

Nos dois primeiros documentos, a substring foi encontrada na posição do índice do ponto de código UTF 2 . Dado $indexOfCP os resultados são baseados em zero (o índice começa em 0 ) a posição 2 representa o terceiro ponto de código.

Este é um resultado diferente do que obteríamos se usássemos $indexOfBytes , porque o símbolo de direitos autorais (© ) no segundo documento ocupa 2 bytes. Mas ele usa apenas um ponto de código, que é o mesmo que a letra c usa.

Em relação ao terceiro documento, a substring não foi encontrada e, portanto, o resultado é -1 .

Aqui está outro exemplo, exceto que desta vez procuramos um caractere tailandês:
db.test.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfCP: [ "$data", "เ" ] }
          }
     }
   ]
)

Resultado:
{ "data" : "c 2021", "result" : -1 }
{ "data" : "© 2021", "result" : -1 }
{ "data" : "ไม้เมือง", "result" : 3 }

Nesse caso, procuramos um caractere que está no terceiro documento e seu índice de ponto de código UTF-8 retorna como 3 . Dado $indexOfCP os resultados são baseados em zero, isso significa que é o quarto ponto de código.

Isso ocorre porque o segundo caractere possui uma marca diacrítica, que também é um ponto de código. Portanto, o primeiro caractere é um ponto de código e o segundo caractere é dois pontos de código (incluindo o diacrítico), o que equivale a três. Isso significa que nosso caractere começa na quarta posição (que é o ponto de código número 3 , devido à contagem de índice começando em 0 ).

Veja MongoDB $strLenCP para um exemplo que retorna o número de pontos de código para cada caractere nessa string específica. E veja MongoDB $strLenBytes para ver o número de bytes na mesma string.

Especifique uma posição inicial


Você pode fornecer um terceiro argumento para especificar uma posição de índice inicial para a pesquisa.

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

Aqui está um exemplo de aplicação de $indexOfCP com uma posição inicial:
db.test.aggregate(
   [
     { $match: { _id: { $in: [ 4 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfCP: [ "$data", "ABC", 1 ] }
          }
     }
   ]
)

Resultado:
{ "data" : "ABC XYZ ABC", "result" : 8 }

Nesse caso, a segunda instância da substring foi retornada. Isso ocorre porque iniciamos a pesquisa na posição 1 , e a primeira instância da substring começa na posição 0 (antes da posição inicial para a busca).

Se a posição inicial for um número maior que a string ou maior que a posição final, $indexOfCP retorna -1 .

Se for um número negativo, $indexOfCP retorna um erro.

Especifique uma posição final


Você também pode fornecer um quarto argumento para especificar a posição final do índice para a pesquisa.

Se você fornecer esse argumento, também precisará fornecer uma posição inicial. Se isso não for feito, esse argumento será interpretado como o ponto de partida.

Exemplo:
db.test.aggregate(
   [
     { $match: { _id: { $in: [ 4 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfCP: [ "$data", "XYZ", 0, 3 ] }
          }
     }
   ]
)

Resultado:
{ "data" : "ABC XYZ ABC", "result" : -1 }

O resultado é -1 o que significa que a substring não foi encontrada. Isso porque iniciamos nossa pesquisa na posição 0 e terminou na posição 3 , portanto, não capturando a substring.

Aqui está o que acontece se incrementarmos a posição do índice final:
db.test.aggregate(
   [
     { $match: { _id: { $in: [ 4 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfCP: [ "$data", "XYZ", 0, 5 ] }
          }
     }
   ]
)

Resultado:
{ "data" : "ABC XYZ ABC", "result" : 4 }

Desta vez, o valor foi incluído e sua posição de índice foi retornada.

Se a posição final for um número menor que a posição inicial, $indexOfCP retorna -1 .

Se for um número negativo, $indexOfCP retorna um erro.

Campos ausentes


Se o campo não estiver no documento, $indexOfCP retorna null .

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

Veja o que acontece quando aplicamos $indexOfCP :
db.test.aggregate(
   [
     { $match: { _id: { $in: [ 5 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfCP: [ "$data", "XYZ" ] }
          }
     }
   ]
)

Resultado:
{ "result" : null }

Valores nulos


Se o primeiro argumento for null , $indexOfCP retorna null .

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

Veja o que acontece quando aplicamos $indexOfCP :
db.test.aggregate(
   [
     { $match: { _id: { $in: [ 6 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfCP: [ "$data", "XYZ" ] }
          }
     }
   ]
)

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

No entanto, quando o segundo argumento (ou seja, a substring) é null , um erro é retornado:
db.test.aggregate(
   [
     { $match: { _id: { $in: [ 1 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfCP: [ "$data", null ] }
          }
     }
   ]
)

Resultado:
uncaught exception: Error: command failed: {
	"ok" : 0,
	"errmsg" : "$indexOfCP requires a string as the second argument, found: null",
	"code" : 40094,
	"codeName" : "Location40094"
} : 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

Tipo de dados incorreto


Se o primeiro argumento for o tipo de dados errado (ou seja, não resolver para uma string), $indexOfCP retorna um erro.

Suponha que temos o seguinte documento:
{ "_id" : 7, "data" : 123 }

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

Resultado:
uncaught exception: Error: command failed: {
	"ok" : 0,
	"errmsg" : "$indexOfCP requires a string as the first argument, found: double",
	"code" : 40093,
	"codeName" : "Location40093"
} : 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

Como a mensagem de erro indica, $indexOfCP requires a string as the first argument .