MongoDB empuje el valor existente de un campo a otro campo en un array de objetos.
Si tengo un documento como este:
db.people.insertOne({name: "Annie", latestScore: 5});
Entonces, basándome en esta respuesta, puedo mover latestScore
a un campo de array de la siguiente manera:
db.people.updateOne(
{name: 'Annie'},
[
{$set:
{scoreHistory:
{$concatArrays: [
{$ifNull: ["$scoreHistory", []]},
["$latestScore"]
]}
}
},
{ $unset: ["latestScore"] }
]
);
Este es el documento resultante:
{
_id: ObjectId("61d2737611e48e0d0c30b35b"),
name: 'Annie',
scoreHistory: [ 5 ]
}
¿Podemos realizar la misma actualización en objetos anidados en un array? Por ejemplo, si el documento es así:
db.people.insertOne({
name: 'Annie',
words: [
{word: "bunny", score: 5},
{word: "pink", score: 5}
]
});
¿Cómo podemos actualizarlo a esto?
{
name: 'Annie',
words: [
{word: "bunny", scoreHistory: [5]},
{word: "pink", scoreHistory: [5]}
]
}
Sé que puedo iterar y modificar el array desde la aplicación y actualizar el array completo de una vez, pero me gustaría hacerlo usando operadores como en el primer ejemplo anterior.
El sitio web muestra primero words.word
y words.score
en filas, al hacer clic en una fila se muestra words.scoreHistory
en un popup. Espero que el array de palabras tenga menos de 500 elementos. ¡Cualquier consejo sobre remodelar el esquema para simplificar la operación anterior también es bienvenido!
davy.ai
Sí, podemos realizar la misma actualización a objetos anidados en un arreglo utilizando el operador posicional
$[<identificador>]
. Así es cómo podemos actualizar el documento dado:Esto establecerá el campo
scoreHistory
como un arreglo que contiene el valor anterior descore
y el nuevolatestScore
.En la consulta anterior, estamos utilizando el operador posicional
$[<identificador>]
para identificar el elemento coincidente en el arreglowords
utilizando la opciónarrayFilters
. Luego, estamos utilizando los operadores$ifNull
y$concatArrays
para actualizar el camposcoreHistory
y eliminar el camposcore
.Para simplificar la operación, podemos considerar mover el subdocumento
words
a su propia colección y realizar las actualizaciones utilizando una consulta separada. Esto también mejorará el rendimiento de la consulta, ya que no tendremos que actualizar el documento completo por cada actualización de palabra.