No MongoDB, o
$indexOfBytes O operador de pipeline de agregação pesquisa uma string para uma ocorrência de uma substring e retorna o índice de bytes UTF-8 da primeira ocorrência. O índice de bytes UTF é baseado em zero (ou seja, começa em
0 ). Sintaxe
A sintaxe fica assim:
{ $indexOfBytes: [ <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,
$indexOfBytes 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
$indexOfBytes a esses documentos:db.test.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "2021" ] }
}
}
]
) Resultado:
{ "data" : "c 2021", "result" : 2 }
{ "data" : "© 2021", "result" : 3 }
{ "data" : "ไม้เมือง", "result" : -1 } Podemos ver que os dois primeiros documentos produziram resultados diferentes, embora a substring pareça estar na mesma posição para cada documento. No primeiro documento, a substring foi encontrada na posição do índice de bytes
2 , enquanto o segundo documento o tinha em 3 . A razão para isso é que o símbolo de copyright (
© ) no segundo documento ocupa 2 bytes. O c caractere (no primeiro documento) usa apenas 1 byte. O caractere de espaço também usa 1 byte. O resultado de
$indexOfBytes é baseado em zero (o índice começa em 0 ), e assim acabamos com um resultado de 2 e 3 respectivamente. 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: { $indexOfBytes: [ "$data", "เ" ] }
}
}
]
) Resultado:
{ "data" : "c 2021", "result" : -1 }
{ "data" : "© 2021", "result" : -1 }
{ "data" : "ไม้เมือง", "result" : 9 } Nesse caso, procuramos um caractere que aparece na terceira posição no terceiro documento e seu índice de bytes UTF-8 retorna como
9 . Isso ocorre porque, nesse caso, cada caractere usa 3 bytes. Mas o segundo caractere tem uma marca diacrítica, que também é de 3 bytes. Portanto, os dois primeiros caracteres (incluindo o diacrítico) usam 9 bytes. Dada a indexação baseada em zero, seus índices de bytes UTF-8 variam de
0 para 8 . Isso significa que o terceiro caractere começa na posição 9 . Veja MongoDB
$strLenBytes para um exemplo que retorna o número de bytes para cada caractere nessa string específica. 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
$indexOfBytes com uma posição inicial:db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$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 o comprimento do byte da string ou maior que a posição final,
$indexOfBytes retorna -1 . Se for um número negativo,
$indexOfBytes 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: { $indexOfBytes: [ "$data", "XYZ", 0, 5 ] }
}
}
]
) 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 5 , 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: { $indexOfBytes: [ "$data", "XYZ", 0, 7 ] }
}
}
]
) 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,
$indexOfBytes retorna -1 . Se for um número negativo,
$indexOfBytes retorna um erro. Campos ausentes
Se o campo não estiver no documento,
$indexOfBytes retorna null . Suponha que temos o seguinte documento:
{ "_id" : 5 } Veja o que acontece quando aplicamos
$indexOfBytes :db.test.aggregate(
[
{ $match: { _id: { $in: [ 5 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ" ] }
}
}
]
) Resultado:
{ "result" : null } Valores nulos
Se o primeiro argumento for
null , $indexOfBytes retorna null . Suponha que temos o seguinte documento:
{ "_id" : 6, "data" : null } Veja o que acontece quando aplicamos
$indexOfBytes :db.test.aggregate(
[
{ $match: { _id: { $in: [ 6 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$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: { $indexOfBytes: [ "$data", null ] }
}
}
]
) Resultado:
uncaught exception: Error: command failed: {
"ok" : 0,
"errmsg" : "$indexOfBytes requires a string as the second argument, found: null",
"code" : 40092,
"codeName" : "Location40092"
} : aggregate failed :
example@sqldat.com/mongo/shell/utils.js:25:13
example@sqldat.com/mongo/shell/assert.js:18:14
example@sqldat.com/mongo/shell/assert.js:639:17
example@sqldat.com/mongo/shell/assert.js:729:16
example@sqldat.com/mongo/shell/db.js:266:5
example@sqldat.com/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),
$indexOfBytes retorna um erro. Suponha que temos o seguinte documento:
{ "_id" : 7, "data" : 123 } Veja o que acontece quando aplicamos
$indexOfBytes a esse documento:db.test.aggregate(
[
{ $match: { _id: { $in: [ 7 ] } } },
{
$project:
{
_id: 0,
data: 1,
result: { $indexOfBytes: [ "$data", "XYZ" ] }
}
}
]
) Resultado:
uncaught exception: Error: command failed: {
"ok" : 0,
"errmsg" : "$indexOfBytes requires a string as the first argument, found: double",
"code" : 40091,
"codeName" : "Location40091"
} : aggregate failed :
example@sqldat.com/mongo/shell/utils.js:25:13
example@sqldat.com/mongo/shell/assert.js:18:14
example@sqldat.com/mongo/shell/assert.js:639:17
example@sqldat.com/mongo/shell/assert.js:729:16
example@sqldat.com/mongo/shell/db.js:266:5
example@sqldat.com/mongo/shell/collection.js:1058:12
@(shell):1:1 Como a mensagem de erro indica,
$indexOfBytes requires a string as the first argument .