No MongoDB, o
$arrayToObject
operador de pipeline de agregação converte uma matriz em um documento. A matriz fornecida para
$arrayToObject
deve estar em um dos dois formatos a seguir:- Uma matriz de matrizes de dois elementos em que o primeiro elemento é o nome do campo e o segundo elemento é o valor do campo.
- Uma matriz de documentos que contém um
k
campo e umv
campo, onde ok
campo contém o nome do campo e ov
campo contém o valor.
Formato 1
Suponha que tenhamos uma coleção chamada
test
com o seguinte documento:{ "_id" : 1, "data" : [ [ "name", "Fetch" ], [ "type", "Dog" ] ] }
Podemos usar o
$arrayToObject
operador para retornar os data
campo como um objeto de documento:db.test.aggregate(
[
{ $match: { _id: { $in: [ 1 ] } } },
{ $project: {
_id: 0,
result: { $arrayToObject: "$data" } }
}
]
)
Resultado:
{ "result" : { "name" : "Fetch", "type" : "Dog" } }
Formato 2
Suponha que temos um documento como este:
{ "_id" : 2, "data" : [ { "k" : "name", "v" : "Fetch" }, { "k" : "type", "v" : "Dog" } ] }
Neste caso, o
k
os campos contêm as chaves e o v
campos contêm os valores. Veja o que acontece quando aplicamos
$arrayToObject
a esse documento:db.test.aggregate(
[
{ $match: { _id: { $in: [ 2 ] } } },
{ $project: {
_id: 0,
result: { $arrayToObject: "$data" } }
}
]
)
Resultado:
{ "result" : { "name" : "Fetch", "type" : "Dog" } }
Podemos ver que isso resultou no mesmo documento que foi produzido no exemplo anterior.
Matrizes não conformes
O argumento fornecido para
$arrayToObject
pode ser qualquer expressão válida desde que resolva para um array de arrays de dois elementos ou array de documentos que contenha k
e v
Campos. Se o argumento não aderir a isso, ocorrerá um erro.
Suponha que temos o seguinte documento:
{ "_id" : 3, "data" : [ [ "name", "Fetch", "Dog" ] ] }
Esta matriz contém três elementos.
Veja o que acontece quando aplicamos
$arrayToObject
a esse documento:db.test.aggregate(
[
{ $match: { _id: { $in: [ 3 ] } } },
{ $project: {
_id: 0,
result: { $arrayToObject: "$data" } }
}
]
)
Resultado:
uncaught exception: Error: command failed: { "ok" : 0, "errmsg" : "$arrayToObject requires an array of size 2 arrays,found array of size: 3", "code" : 40397, "codeName" : "Location40397" } : 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 o erro indica,
$arrayToObject requires an array of size 2 arrays
. Aqui está outro documento que contém uma matriz não conforme:
{ "_id" : 4, "data" : [ { "a" : "name", "b" : "Fetch" } ] }
Neste caso, o documento dentro do array usa
a
e b
campos em vez de k
e v
. Veja o que acontece quando aplicamos
$arrayToObject
:db.test.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{ $project: {
_id: 0,
result: { $arrayToObject: "$data" } }
}
]
)
Resultado:
uncaught exception: Error: command failed: { "ok" : 0, "errmsg" : "$arrayToObject requires an object with keys 'k' and 'v'. Missing either or both keys from: {a: \"name\", b: \"Fetch\"}", "code" : 40393, "codeName" : "Location40393" } : 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
Nesse caso, o erro informa que
$arrayToObject requires an object with keys 'k' and 'v'
. Tipo errado
Da mesma forma, se o argumento não for nem mesmo uma matriz, ocorrerá um erro.
Suponha que temos o seguinte documento:
{ "_id" : 5, "data" : "None" }
Os
data
campo contém uma string. Veja o que acontece quando aplicamos
$arrayToObject
a esse documento:db.test.aggregate(
[
{ $match: { _id: { $in: [ 5 ] } } },
{ $project: {
_id: 0,
result: { $arrayToObject: "$data" } }
}
]
)
Resultado:
uncaught exception: Error: command failed: { "ok" : 0, "errmsg" : "$arrayToObject requires an array input, found: string", "code" : 40386, "codeName" : "Location40386" } : 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 o erro indica,
$arrayToObject requires an array input
. Valores nulos
Fornecendo
null
resulta em null
. Suponha que temos o seguinte documento:
{ "_id" : 6, "data" : null }
E aplicamos
$arrayToObject
:db.test.aggregate(
[
{ $match: { _id: { $in: [ 6 ] } } },
{ $project: {
_id: 0,
result: { $arrayToObject: "$data" } }
}
]
)
Resultado:
{ "result" : null }
Campos ausentes
Se o campo estiver ausente, o resultado será
null
. Suponha que temos o seguinte documento:
{ "_id" : 7 }
E aplicamos
$arrayToObject
:db.test.aggregate(
[
{ $match: { _id: { $in: [ 7 ] } } },
{ $project: {
_id: 0,
result: { $arrayToObject: "$data" } }
}
]
)
Resultado:
{ "result" : null }
Nomes de campo repetidos
De acordo com a documentação do MongoDB, se o nome de um campo se repetir no array:
- A partir da versão 4.0.5,
$arrayToObject
usa o último valor para esse campo. Para 4.0.0-4.0.4, o valor usado depende do driver. - A partir da versão 3.6.10,
$arrayToObject
usa o último valor para esse campo. Para 3.6.0-3.6.9, o valor usado depende do driver. - A partir da versão 3.4.19,
$arrayToObject
usa o último valor para esse campo. Para 3.4.0-3.4.19, o valor usado depende do driver.