Al fin después de tanto batallar ya encontramos la respuesta de este atasco que muchos usuarios de este sitio han presentado. Si deseas compartir algo más no dudes en dejar tu comentario.
Solución:
La mejor manera de hacer esto es en la versión 4.2+ que permite el uso de canalización de agregación en el documento de actualización y el updateOne
, updateMany
o update
método de recolección. Tenga en cuenta que este último ha quedado obsoleto en la mayoría, si no en todos, los controladores de idiomas.
MongoDB 4.2+
La versión 4.2 también introdujo la $set
operador de etapa de tubería que es un alias para $addFields
. usaré $set
aquí como mapas con lo que estamos tratando de lograr.
db.collection.(
,
[
"$set": "name": "$concat": ["$firstName", " ", "$lastName"]
]
)
MongoDB 3.4+
En 3.4+ puedes usar $addFields
y el $out
operadores de tuberías de agregación.
db.collection.aggregate(
[
"$addFields":
"name": "$concat": [ "$firstName", " ", "$lastName" ]
,
"$out": "collection"
]
)
Tenga en cuenta que esto no actualiza su colección, sino que reemplaza la colección existente o crea una nueva. También para operaciones de actualización que requieran “type casting” necesitará procesamiento del lado del cliente, y dependiendo de la operación, es posible que necesite utilizar el find()
método en lugar del .aggreate()
método.
MongoDB 3.2 y 3.0
La forma en que hacemos esto es por $project
ing nuestros documentos y utilizar el $concat
string operador de agregación para devolver el concatenado string. A partir de ahí, itera el cursor y usa el $set
operador de actualización para agregar el nuevo campo a sus documentos usando operaciones masivas para una máxima eficiencia.
Consulta de agregación:
var cursor = db.collection.aggregate([
"$project":
"name": "$concat": [ "$firstName", " ", "$lastName" ]
])
MongoDB 3.2 o más reciente
a partir de esto, es necesario utilizar el bulkWrite
método.
var requests = [];
cursor.forEach(document =>
requests.push(
'updateOne':
'filter': '_id': document._id ,
'update': '$set': 'name': document.name
);
if (requests.length === 500)
//Execute per 500 operations and re-init
db.collection.bulkWrite(requests);
requests = [];
);
if(requests.length > 0)
db.collection.bulkWrite(requests);
MongoDB 2.6 y 3.0
A partir de esta versión, debe usar el ahora obsoleto Bulk
API y sus métodos asociados.
var bulk = db.collection.initializeUnorderedBulkOp();
var count = 0;
cursor.snapshot().forEach(function(document)
bulk.find( '_id': document._id ).updateOne(
'$set': 'name': document.name
);
count++;
if(count%500 === 0)
// Excecute per 500 operations and re-init
bulk.execute();
bulk = db.collection.initializeUnorderedBulkOp();
)
// clean up queues
if(count > 0)
bulk.execute();
Mongo DB 2.4
cursor["result"].forEach(function(document)
db.collection.update(
"_id": document._id ,
"$set": "name": document.name
);
)
Deberías iterar. Para su caso específico:
db.person.find().snapshot().forEach(
function (elem)
db.person.update(
_id: elem._id
,
$set:
name: elem.firstname + ' ' + elem.lastname
);
);
Aparentemente, hay una manera de hacer esto de manera eficiente desde MongoDB 3.4, vea la respuesta de styvane.
Respuesta obsoleta a continuación
No puede hacer referencia al documento en sí mismo en una actualización (todavía). Deberá iterar a través de los documentos y actualizar cada documento usando una función. Vea esta respuesta para ver un ejemplo, o esta para el lado del servidor eval()
.
Valoraciones y reseñas
Agradecemos que quieras añadir valor a nuestro contenido cooperando tu veteranía en los comentarios.