MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

MongoDB $indexOfBytes

In MongoDB, il $indexOfBytes l'operatore della pipeline di aggregazione cerca in una stringa l'occorrenza di una sottostringa e restituisce l'indice di byte UTF-8 della prima occorrenza.

L'indice di byte UTF è a base zero (cioè inizia da 0 ).

Sintassi

La sintassi è questa:

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

Dove:

  • <string expression> è la stringa da cercare.
  • <substring expression> è la sottostringa che vuoi trovare nella stringa.
  • <start> è un argomento facoltativo che specifica una posizione di indice iniziale per la ricerca. Può essere qualsiasi espressione valida che si risolve in un numero intero non negativo.
  • <end> è un argomento facoltativo che specifica una posizione di indice finale per la ricerca. Può essere qualsiasi espressione valida che si risolve in un numero intero non negativo.

Se il valore specificato non viene trovato, $indexOfBytes restituisce -1 .

Se sono presenti più istanze del valore specificato, viene restituita solo la prima.

Esempio

Supponiamo di avere una collezione chiamata test con i seguenti documenti:

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

Ecco un esempio di applicazione di $indexOfBytes a quei documenti:

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "2021" ] }
          }
     }
   ]
)

Risultato:

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

Possiamo vedere che i primi due documenti hanno prodotto risultati diversi, anche se la sottostringa sembra trovarsi nella stessa posizione per ogni documento. Nel primo documento, la sottostringa è stata trovata nella posizione dell'indice di byte 2 , mentre il secondo documento lo aveva in 3 .

Il motivo è che il simbolo del copyright (© ) nel secondo documento occupa 2 byte. Il c carattere (nel primo documento) utilizza solo 1 byte. Anche il carattere spazio utilizza 1 byte.

Il risultato di $indexOfBytes è a base zero (l'indice inizia da 0 ), e così si ottiene un risultato di 2 e 3 rispettivamente.

Per quanto riguarda il terzo documento, la sottostringa non è stata trovata affatto, quindi il risultato è -1 .

Ecco un altro esempio, tranne che questa volta cerchiamo un carattere tailandese:

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "เ" ] }
          }
     }
   ]
)

Risultato:

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

In questo caso, abbiamo cercato un carattere che appare nella terza posizione nel terzo documento e il suo indice di byte UTF-8 ritorna come 9 .

Questo perché in questo caso ogni carattere utilizza 3 byte. Ma il secondo carattere ha un segno diacritico, che è anche 3 byte. Pertanto, i primi due caratteri (incluso il segno diacritico) utilizzano 9 byte. Data l'indicizzazione in base zero, i loro indici di byte UTF-8 vanno da 0 a 8 . Ciò significa che il terzo carattere inizia alla posizione 9 .

Vedi MongoDB $strLenBytes per un esempio che restituisce il numero di byte per ogni carattere in questa particolare stringa.

Specifica una posizione di partenza

Puoi fornire un terzo argomento per specificare una posizione di indice iniziale per la ricerca.

Supponiamo di avere il seguente documento:

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

Ecco un esempio di applicazione di $indexOfBytes con una posizione di partenza:

db.test.aggregate(
   [
     { $match: { _id: { $in: [ 4 ] } } },
     {
       $project:
          {
            _id: 0,
            data: 1,
            result: { $indexOfBytes: [ "$data", "ABC", 1 ] }
          }
     }
   ]
)

Risultato:

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

In questo caso, è stata restituita la seconda istanza della sottostringa. Questo perché abbiamo iniziato la ricerca nella posizione 1 e la prima istanza della sottostringa inizia nella posizione 0 (prima della posizione di partenza per la ricerca).

Se la posizione iniziale è un numero maggiore della lunghezza in byte della stringa o maggiore della posizione finale, $indexOfBytes restituisce -1 .

Se è un numero negativo, $indexOfBytes restituisce un errore.

Specifica una posizione finale

Puoi anche fornire un quarto argomento per specificare la posizione dell'indice finale per la ricerca.

Se fornisci questo argomento, devi anche fornire una posizione di partenza. In caso contrario, questo argomento verrà interpretato come punto di partenza.

Esempio:

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

Risultato:

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

Il risultato è -1 il che significa che la sottostringa non è stata trovata. Questo perché abbiamo iniziato la nostra ricerca nella posizione 0 e l'ha terminato alla posizione 5 , quindi non catturando la sottostringa.

Ecco cosa succede se incrementiamo la posizione dell'indice finale:

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

Risultato:

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

Questa volta il valore è stato incluso e la sua posizione di indice è stata restituita.

Se la posizione finale è un numero inferiore alla posizione iniziale, $indexOfBytes restituisce -1 .

Se è un numero negativo, $indexOfBytes restituisce un errore.

Campi mancanti

Se il campo non è nel documento, $indexOfBytes restituisce null .

Supponiamo di avere il seguente documento:

{ "_id" : 5 }

Ecco cosa succede quando applichiamo $indexOfBytes :

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

Risultato:

{ "result" : null }

Valori Nulli

Se il primo argomento è null , $indexOfBytes restituisce null .

Supponiamo di avere il seguente documento:

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

Ecco cosa succede quando applichiamo $indexOfBytes :

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

Risultato:

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

Tuttavia, quando il secondo argomento (cioè la sottostringa) è null , viene restituito un errore:

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

Risultato:

uncaught exception: Error: command failed: {
	"ok" : 0,
	"errmsg" : "$indexOfBytes requires a string as the second argument, found: null",
	"code" : 40092,
	"codeName" : "Location40092"
} : 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 di dati errato

Se il primo argomento è il tipo di dati sbagliato (cioè non si risolve in una stringa), $indexOfBytes restituisce un errore.

Supponiamo di avere il seguente documento:

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

Ecco cosa succede quando applichiamo $indexOfBytes a quel documento:

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

Risultato:

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

Come afferma il messaggio di errore, $indexOfBytes requires a string as the first argument .