sql >> Base de Datos >  >> NoSQL >> MongoDB

MongoDB $indexOfCP

En MongoDB, el $indexOfCP El operador de canalización de agregación busca en una cadena una aparición de una subcadena y devuelve el índice de punto de código UTF de la primera aparición.

El índice de punto de código UTF se basa en cero (es decir, comienza en 0 ).

Sintaxis

La sintaxis es así:

{ $indexOfCP: [ <string expression>, <substring expression>, <start>, <end> ] }

donde:

  • <string expression> es la cadena a buscar.
  • <substring expression> es la subcadena que desea encontrar en la cadena.
  • <start> es un argumento opcional que especifica una posición de índice inicial para la búsqueda. Puede ser cualquier expresión válida que se resuelva en un número entero no negativo.
  • <end> es un argumento opcional que especifica una posición de índice final para la búsqueda. Puede ser cualquier expresión válida que se resuelva en un número entero no negativo.

Si no se encuentra el valor especificado, $indexOfCP devuelve -1 .

Si hay varias instancias del valor especificado, solo se devuelve la primera.

Ejemplo

Supongamos que tenemos una colección llamada test con los siguientes documentos:

{ "_id" : 1, "data" : "c 2021" }
{ "_id" : 2, "data" : "© 2021" }
{ "_id" : 3, "data" : "ไม้เมือง" }

Aquí hay un ejemplo de cómo aplicar $indexOfCP a esos 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 }

En los dos primeros documentos, la subcadena se encontró en la posición de índice de punto de código UTF 2 . Dado $indexOfCP los resultados están basados ​​en cero (el índice comienza en 0 ) la posición 2 representa el tercer punto de código.

Este es un resultado diferente al que obtendríamos si usamos $indexOfBytes , porque el símbolo de copyright (© ) en el segundo documento ocupa 2 bytes. Pero usa solo un punto de código, que es lo mismo que la letra c usos.

Con respecto al tercer documento, la subcadena no se encontró en absoluto, por lo que el resultado es -1 .

Aquí hay otro ejemplo, excepto que esta vez buscamos un carácter 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 }

En este caso, buscamos un carácter que está en el tercer documento y su índice de punto de código UTF-8 regresa como 3 . Dado $indexOfCP los resultados se basan en cero, lo que significa que es el cuarto punto de código.

Esto se debe a que el segundo carácter tiene un signo diacrítico, que también es un punto de código. Por lo tanto, el primer carácter es un punto de código y el segundo carácter es dos puntos de código (incluido el diacrítico), lo que equivale a tres. Esto significa que nuestro personaje comienza en la cuarta posición (que es el punto de código número 3 , debido al recuento de índices que comienza en 0 ).

Ver MongoDB $strLenCP para ver un ejemplo que devuelve el número de puntos de código para cada carácter en esta cadena en particular. Y vea MongoDB $strLenBytes para ver el número de bytes en la misma cadena.

Especifique una posición inicial

Puede proporcionar un tercer argumento para especificar una posición de índice inicial para la búsqueda.

Supongamos que tenemos el siguiente documento:

{ "_id" : 4, "data" : "ABC XYZ ABC" }

Aquí hay un ejemplo de cómo aplicar $indexOfCP con una posición 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 }

En este caso, se devolvió la segunda instancia de la subcadena. Esto se debe a que comenzamos la búsqueda en la posición 1 , y la primera instancia de la subcadena comienza en la posición 0 (antes de la posición inicial de la búsqueda).

Si la posición inicial es un número mayor que la cadena o mayor que la posición final, $indexOfCP devuelve -1 .

Si es un número negativo, $indexOfCP devuelve un error.

Especifique una posición final

También puede proporcionar un cuarto argumento para especificar la posición final del índice para la búsqueda.

Si proporciona este argumento, también debe proporcionar una posición inicial. Si no lo hace, este argumento se interpretará como el punto de partida.

Ejemplo:

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 }

El resultado es -1 lo que significa que no se encontró la subcadena. Eso es porque comenzamos nuestra búsqueda en la posición 0 y lo terminó en la posición 3 , por lo tanto, no captura la subcadena.

Esto es lo que sucede si incrementamos la posición final del índice:

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 }

Esta vez se incluyó el valor y se devolvió su posición de índice.

Si la posición final es un número menor que la posición inicial, $indexOfCP devuelve -1 .

Si es un número negativo, $indexOfCP devuelve un error.

Campos faltantes

Si el campo no está en el documento, $indexOfCP devuelve null .

Supongamos que tenemos el siguiente documento:

{ "_id" : 5 }

Esto es lo que sucede cuando aplicamos $indexOfCP :

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

Resultado:

{ "result" : null }

Valores nulos

Si el primer argumento es null , $indexOfCP devuelve null .

Supongamos que tenemos el siguiente documento:

{ "_id" : 6, "data" : null }

Esto es lo que sucede cuando aplicamos $indexOfCP :

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

Resultado:

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

Sin embargo, cuando el segundo argumento (es decir, la subcadena) es null , se devuelve un error:

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 datos incorrecto

Si el primer argumento es del tipo de datos incorrecto (es decir, no se resuelve en una cadena), $indexOfCP devuelve un error.

Supongamos que tenemos el siguiente documento:

{ "_id" : 7, "data" : 123 }

Esto es lo que sucede cuando aplicamos $indexOfCP a ese 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 indica el mensaje de error, $indexOfCP requires a string as the first argument .