Dado este documento guardado en MongoDB
{
_id : ...,
some_key: {
param1 : "val1",
param2 : "val2",
param3 : "val3"
}
}
Es necesario guardar un objeto con nueva información sobre param2
y param3
desde el mundo exterior.
var new_info = {
param2 : "val2_new",
param3 : "val3_new"
};
Quiero fusionar / superponer los nuevos campos sobre el estado existente del objeto para que no se elimine param1
Haciendo esto
db.collection.update( { _id:...} , { $set: { some_key : new_info } }
Conducirá a que MongoDB esté haciendo exactamente lo que se le pidió, y establece some_key en ese valor. reemplazando el viejo.
{
_id : ...,
some_key: {
param2 : "val2_new",
param3 : "val3_new"
}
}
¿Cuál es la forma de que MongoDB actualice solo los campos nuevos (sin indicarlos uno por uno explícitamente)? para obtener esto:
{
_id : ...,
some_key: {
param1 : "val1",
param2 : "val2_new",
param3 : "val3_new"
}
}
Estoy usando el cliente Java, pero cualquier ejemplo será apreciado
mongodb
mongodb-java
Eran Medan
fuente
fuente
Respuestas:
Si entiendo la pregunta correctamente, desea actualizar un documento con el contenido de otro documento, pero solo los campos que aún no están presentes e ignorar por completo los campos que ya están configurados (incluso si tienen otro valor).
No hay forma de hacerlo en un solo comando.
Primero debe consultar el documento, averiguar qué desea
$set
y luego actualizarlo (utilizando los valores antiguos como un filtro coincidente para asegurarse de que no obtenga actualizaciones concurrentes en el medio).Otra lectura de su pregunta sería con la que está satisfecho
$set
, pero no desea establecer explícitamente todos los campos. ¿Cómo pasarías los datos entonces?Sabes que puedes hacer lo siguiente:
fuente
db.collection.update( { _id:...} , { $set: someObjectWithNewData, { $multi: true } } )
Lo resolví con mi propia función. Si desea actualizar el campo especificado en el documento, debe abordarlo claramente.
Ejemplo:
Si solo desea actualizar param2, es incorrecto:
Debes usar:
Entonces escribí una función algo así:
fuente
db.users.update( { _id: ObjectId("594dbc3186bb5c84442949b1") }, { $set: { resume: { url: "http://i.imgur.com/UFX0yXs.jpg" } } } )
Puede usar la notación de puntos para acceder y establecer campos en lo profundo de los objetos, sin afectar las otras propiedades de esos objetos.
Dado el objeto que especificó anteriormente:
Podemos actualizar solo
some_key.param2
ysome_key.param3
:Puedes profundizar tanto como quieras. Esto también es útil para agregar nuevas propiedades a un objeto sin afectar las existentes.
fuente
La mejor solución es extraer propiedades del objeto y convertirlas en pares clave-valor de notación de puntos planos. Podría usar, por ejemplo, esta biblioteca:
https://www.npmjs.com/package/mongo-dot-notation
Tiene
.flatten
función que le permite cambiar el objeto en un conjunto plano de propiedades que luego podrían asignarse al modificador $ set, sin preocuparse de que cualquier propiedad de su objeto DB existente se elimine / sobrescriba sin necesidad.Tomado de
mongo-dot-notation
documentos:Y luego forma un selector perfecto: actualizará SOLO las propiedades dadas. EDITAR: Me gusta ser arqueólogo algunas veces;)
fuente
Mongo le permite actualizar documentos anidados mediante una
.
convención. Echa un vistazo: Actualización de documentos anidados en mongodb . Aquí hay otra pregunta del pasado sobre una actualización de fusión, como la que está buscando, creo: Actualización atómica de MongoDB a través del documento 'fusión'fuente
Tuve éxito al hacerlo de esta manera:
Tengo una función que maneja mis actualizaciones de perfil dinámicamente
Nota: 'perfil' es específico de mi implementación, es solo la cadena de la clave que le gustaría modificar.
fuente
Parece que puede establecer isPartialObject que podría lograr lo que desea.
fuente
Si tiene varios campos para actualizar
fuente
Al comenzar
Mongo 4.2
,db.collection.update()
puede aceptar una canalización de agregación, que permite usar operadores de agregación como$addFields
, que genera todos los campos existentes de los documentos de entrada y los campos recién agregados:La primera parte
{}
es la consulta de coincidencia, filtrando qué documentos actualizar (en este caso, todos los documentos).La segunda parte
[{ $addFields: { some_key: new_info } }]
es la tubería de agregación de actualizaciones:$addFields
.$addFields
realiza exactamente lo que necesita: actualizar el objeto para que el nuevo objeto se superponga / combine con el existente:{ param2: "val2_new", param3: "val3_new" }
se fusionará con lo existentesome_key
al mantenerseparam1
intacto y agregar o reemplazar ambosparam2
yparam3
.No lo olvide
{ multi: true }
, de lo contrario solo se actualizará el primer documento coincidente.fuente
a
¡Espero que esto ayude!
fuente
Preferiría hacer una actualización, esta operación en MongoDB se utiliza para guardar el documento en la colección. Si el documento coincide con los criterios de consulta, realizará una operación de actualización; de lo contrario, insertará un nuevo documento en la colección.
algo similar como a continuación
fuente
use $ set haga este proceso
fuente
Haga un objeto de actualización con los nombres de las propiedades, incluida la ruta de puntos necesaria. ("somekey." + del ejemplo de OP), y luego use eso para hacer la actualización.
fuente
Sí, la mejor manera es convertir la notación del objeto en una representación de cadena de valor clave clave, como se menciona en este comentario: https://stackoverflow.com/a/39357531/2529199
Quería resaltar un método alternativo usando esta biblioteca NPM: https://www.npmjs.com/package/dot-object que le permite manipular diferentes objetos usando la notación de puntos.
Usé este patrón para crear programáticamente una propiedad de objeto anidado al aceptar el valor-clave como una variable de función, de la siguiente manera:
Este patrón me permite usar propiedades anidadas y de un solo nivel indistintamente, e insertarlas limpiamente en Mongo.
Si necesita jugar con JS Objects más allá de Mongo, especialmente en el lado del cliente pero tiene consistencia al trabajar con Mongo, esta biblioteca le ofrece más opciones que el
mongo-dot-notation
módulo NPM mencionado anteriormente .PD: originalmente quería mencionar esto como un comentario, pero aparentemente mi representante de S / O no es lo suficientemente alto como para publicar un comentario. Entonces, sin tratar de entrometerse en el comentario de SzybkiSasza, solo quería destacar proporcionar un módulo alternativo.
fuente
Traté
findAndModify()
de actualizar un campo en particular en un objeto preexistente.https://docs.mongodb.com/manual/reference/method/db.collection.findAndModify/
fuente
Debería pensar en actualizar el objeto indistintamente y luego simplemente almacenar el objeto con los campos actualizados. Algo así como se hace a continuación
fuente
Tienes que usar documentos incrustados (stringfy el objeto de ruta)
Y así, en JavaScript puede usar Spread Operator (...) para actualizar
fuente