una - mongodb modificar documento
MongoDB: ActualizaciĆ³n de documentos utilizando datos del mismo documento (6)
De la CLI? Creo que primero hay que sacar los valores y asignar el valor a una variable. Luego ejecuta tu comando de actualización.
O (no lo he intentado) elimine ''db'' de la cadena. events.lat
y events.lon
Si funciona, todavía tendrá valores múltiples, los valores anteriores para "lat" y "lon" y la nueva matriz que creó.
Esta pregunta ya tiene una respuesta aquí:
Tengo una lista de documentos, cada uno con propiedades lat y lon (entre otros).
{ ''lat'': 1, ''lon'': 2, someotherdata [...] }
{ ''lat'': 4, ''lon'': 1, someotherdata [...] }
[...]
Quiero modificarlo para que se vea así:
{ ''coords'': {''lat'': 1, ''lon'': 2}, someotherdata [...]}
{ ''coords'': {''lat'': 4, ''lon'': 1}, someotherdata [...]}
[...]
Hasta ahora tengo esto:
db.events.update({}, {$set : {''coords'': {''lat'': db.events.lat, ''lon'': db.events.lon}}}, false, true)
Pero trata los db.events.lat y db.events.lon como cadenas. ¿Cómo puedo hacer referencia a las propiedades del documento?
Aclamaciones.
El operador $rename (introducido un mes después de la publicación de esta pregunta) hace que sea muy fácil hacer este tipo de cosas donde no es necesario modificar los valores.
Inserta algunos documentos de prueba
db.events.insert({ ''lat'': 1, ''lon'': 2, someotherdata: [] })
db.events.insert({ ''lat'': 4, ''lon'': 1, someotherdata: [] })
usa el operador $rename
db.events.update({}, {$rename: {''lat'': ''coords.lat'', ''lon'': ''coords.lon''}}, false, true)
Resultados
db.events.find()
{
"_id" : ObjectId("5113c82dd28c4e8b79971add"),
"coords" : {
"lat" : 1,
"lon" : 2
},
"someotherdata" : [ ]
}
{
"_id" : ObjectId("5113c82ed28c4e8b79971ade"),
"coords" : {
"lat" : 4,
"lon" : 1
},
"someotherdata" : [ ]
}
Podemos usar la secuencia de comandos de Mongo para manipular datos sobre la marcha. ¡Esto funciona para mi!
Yo uso este script para corregir mis datos de dirección.
Ejemplo de dirección actual: "N ° 12, QUINTA AVENIDA".
Quiero eliminar la última coma redundante, la nueva dirección esperada "" Nº12, QUINTA AVENIDA ".
var cursor = db.myCollection.find().limit(100);
while (cursor.hasNext()) {
var currentDocument = cursor.next();
var address = currentDocument[''address''];
var lastPosition = address.length - 1;
var lastChar = address.charAt(lastPosition);
if (lastChar == ",") {
var newAddress = address.slice(0, lastPosition);
currentDocument[''address''] = newAddress;
db.localbizs.update({_id: currentDocument._id}, currentDocument);
}
}
¡Espero que esto ayude!
Siempre que esté de acuerdo con la creación de una copia de los datos, el marco de agregación se puede utilizar como una alternativa aquí. También tiene la opción de hacer más a los datos si desea usar otros operadores, pero el único que necesita es $project
. Es algo derrochador en términos de espacio, pero puede ser más rápido y más apropiado para algunos usos. Para ilustrar, primero insertaré algunos datos de muestra en la colección foo
:
db.foo.insert({ ''lat'': 1, ''lon'': 2, someotherdata : [1, 2, 3] })
db.foo.insert({ ''lat'': 4, ''lon'': 1, someotherdata : [4, 5, 6] })
Ahora, solo usamos $project
para volver a trabajar los campos lat
y lon
, y luego los enviamos a la colección newfoo
:
db.foo.aggregate([
{$project : {_id : "$_id", "coords.lat" : "$lat", "coords.lon" : "$lon", "someotherdata" : "$someotherdata" }},
{ $out : "newfoo" }
])
Luego revisa newfoo
para ver nuestros datos alterados:
db.newfoo.find()
{ "_id" : ObjectId("544548a71b5cf91c4893eb9a"), "someotherdata" : [ 1, 2, 3 ], "coords" : { "lat" : 1, "lon" : 2 } }
{ "_id" : ObjectId("544548a81b5cf91c4893eb9b"), "someotherdata" : [ 4, 5, 6 ], "coords" : { "lat" : 4, "lon" : 1 } }
Una vez que esté satisfecho con los nuevos datos, puede usar el renameCollection()
para descartar los datos antiguos y usar los nuevos datos con el nombre anterior:
> db.newfoo.renameCollection("foo", true)
{ "ok" : 1 }
> db.foo.find()
{ "_id" : ObjectId("544548a71b5cf91c4893eb9a"), "someotherdata" : [ 1, 2, 3 ], "coords" : { "lat" : 1, "lon" : 2 } }
{ "_id" : ObjectId("544548a81b5cf91c4893eb9b"), "someotherdata" : [ 4, 5, 6 ], "coords" : { "lat" : 4, "lon" : 1 } }
Una última nota: hasta que se complete SERVER-7944 no puede hacer el equivalente de una instantánea al _id
índice _id
como se sugiere en esta respuesta y así puede terminar golpeando un documento más de una vez si la actividad en algún otro lugar lo mueve. Dado que está insertando el campo _id
en este ejemplo, cualquier suceso causaría una violación de clave única, por lo que no terminará con duplicados, pero es posible que tenga una versión "anterior" de un documento. Como siempre, verifique sus datos a fondo antes de soltarlos y, preferiblemente, haga una copia de seguridad.
Actualización: si todo lo que tiene que hacer es cambiar la estructura de un documento sin cambiar los valores, consulte la respuesta de gipset para obtener una buena solución.
De acuerdo con un comentario (ahora no disponible) en la página de documentación de actualización , no puede hacer referencia a las propiedades del documento actual desde dentro de una update()
.
Tendrás que repetir todos los documentos y actualizarlos de esta manera:
db.events.find().snapshot().forEach(
function (e) {
// update document, using its own properties
e.coords = { lat: e.lat, lon: e.lon };
// remove old properties
delete e.lat;
delete e.lon;
// save the updated document
db.events.save(e);
}
)
Dicha función también se puede usar en un trabajo map-reduce o en un trabajo db.eval()
servidor, según sus necesidades.
Neils responde . Solo para que las personas sepan que no se puede ejecutar esto en una gran base de datos si se permite hacerlo remotamente como Robomongo. Tendrá que ingresar al caparazón de mongo de su servidor real. También podría hacer esto si prefiere hacer una actualización.
db.Collection.find({***/ possible query /***}).toArray().forEach(
function(obj){
obj.item = obj.copiedItem;
obj.otherItem = obj.copiedItem;
obj.thirdItem = true;
obj.fourthItem = "string";
db.Collection.update({_id: obj._id}, obj);
}
);