Estoy tratando de actualizar el tipo de datos de un campo de cadena a ObjectId para todos los documentos en una colección usando el controlador MongoDB C#. Esta consulta funciona perfectamente bien:
db.getCollection('MyCollection').updateMany( { MyField: { $type: 2 } }, [{ $set: { MyField: { $toObjectId: "$MyField" } } }] );Pero tengo problemas para escribir la misma consulta en C#. Probé la siguiente consulta usando UpdateManyAsync:
var filter = new BsonDocument("MyField", new BsonDocument("$type", BsonType.String)); var update = new BsonDocument { { "$set", new BsonDocument("MyField", new BsonDocument("$toObjectId", "$MyField")) } }; var updateResult = await collection.UpdateManyAsync(filter, update);Pero obtuve el siguiente error:
El campo con el prefijo dólar ($) '$toObjectId' en 'MyField.$toObjectId' no es válido para el almacenamiento
Este ejemplo aquí funciona, pero no es ideal porque me obliga a buscar todos los documentos:
var updateList = new List<WriteModel<BsonDocument>>(); var documents = await collection.Find(Builders<BsonDocument>.Filter.Empty).ToListAsync(); foreach (var document in documents) { var id = document.GetElement("_id").Value.AsString; var myFieldValue = document.GetElement("MyField").Value.AsString; var filter = Builders<BsonDocument>.Filter.Eq("_id", id); var update = Builders<BsonDocument>.Update.Set("MyField", new BsonObjectId(ObjectId.Parse(myFieldValue))); updateList.Add(new UpdateOneModel<BsonDocument>(filter, update)); } if (updateList.Any()) { var bulkWriteResult = await collection.BulkWriteAsync(updateList); }Mira esto:
var pipeline = Builders<BsonDocument> .Update .Pipeline(new EmptyPipelineDefinition<BsonDocument>() .AppendStage<BsonDocument, BsonDocument, BsonDocument>("{ $set: { MyField: { $toObjectId: '$MyField' } } }")); coll.UpdateMany( new BsonDocument("MyField", new BsonDocument("$type", BsonType.String)), pipeline);Este ejemplo de código funciona:
var filter = new BsonDocument("MyField", new BsonDocument("$type", BsonType.String)); var stage = new BsonDocument { { "$set", new BsonDocument { { "MyField", new BsonDocument { { "$toObjectId", "$MyField" } } } } } }; var pipeline = PipelineDefinition<BsonDocument, BsonDocument>.Create(stage); var update = Builders<BsonDocument>.Update.Pipeline(pipeline); var result = await collection.UpdateManyAsync(filter, update);Muchas gracias @kanils_ me indicó la dirección correcta, este ejemplo de agregación C# del controlador Mongo Db para la actualización también me ayudó a escribir el código anterior. También muchas gracias @dododo por tu sugerencia.