En esta página, puedes encontrar preguntas frecuentes y sus respuestas correspondientes.
Tip
Si no encuentras una respuesta a tu pregunta en esta página, consulta la Página de problemas y ayuda para obtener información sobre cómo informar de problemas.
¿Por Qué Recibo Errores Al Conectarme a MongoDB?
Si tienes problemas para conectarte a una implementación de MongoDB, consulta la guía de resolución de problemas de conexión para posibles soluciones.
¿Cómo funciona el agrupamiento de conexiones en el controlador Rust?
Cada servidor en su clúster de MongoDB mantiene un pool de conexiones. Puedes acceder o gestionar el comportamiento del pool de conexiones utilizando una instancia de un Cliente. Los pools de conexiones abren sockets on-demand para soportar operaciones concurrentes en su aplicación multi-hilo.
Se puede configurar el siguiente pool de conexiones:
Tamaño máximo y mínimo, establecido por el
max_pool_sizeymin_pool_sizeopcionesNúmero máximo de conexiones que el pool crea en paralelo, establecido por la opción
max_connectingTiempo máx. inactivo, configurado mediante la opción
max_idle_time
Para más información sobre agrupamiento de conexiones, consulta la sección Pool de conexiones en la guía Consideraciones de rendimiento.
¿Cómo convierto entre BSON y tipos de Rust?
El driver de Rust y la librería BSON utilizan el framework Serde para realizar conversiones entre tipos personalizados de Rust y BSON. Puedes añadir la caja serde a tu archivo Cargo.toml para acceder a la funcionalidad del framework Serde. Para obtener instrucciones sobre cómo añadir esta caja, consulta serde en el registro de cajas.
Después de agregar la caja a tu aplicación, puedes modelar los documentos en una colección utilizando un tipo personalizado en lugar de un documento BSON. El siguiente ejemplo incluye el atributo derive antes de la definición de estructura Vegetable, lo que indica al driver que realice las siguientes acciones cuando sea necesario:
Serializa la estructura, lo que convierte la estructura a BSON
Deserializar BSON, que convierte los datos BSON en tu struct
struct Vegetable { // Add struct fields here }
A continuación, puedes crear una instancia de Collection con tu propio tipo struct personalizado como parámetro de tipo genérico. En el siguiente ejemplo, se asigna una instancia de Collection parametrizada con el tipo Vegetable a la variable my_coll:
let my_coll: Collection<Vegetable> = client.database("db").collection("vegetables");
Para obtener más información sobre la conversión entre BSON y tipos de Rust, consulta la guía de Modelado de datos y serialización y el artículo del Centro de Desarrolladores de MongoDB Estructuración de datos con Serde en Rust.
¿Cómo puedo solucionar los errores de límites de características insatisfechos?
Los límites de los traits permiten que los métodos restrinjan los tipos que aceptan como parámetros y la funcionalidad que esos tipos deben implementar. Por ejemplo, si se define un método que acepte un parámetro de tipo genérico e imprima su valor, el parámetro debe implementar el rasgo Display para fines de impresión. El siguiente ejemplo define el método printer() y especifica que su parámetro debe implementar Display:
fn printer<T: Display>(t: T) { println!("{}", t); }
Al llamar a un método en un tipo de dato, puede que encuentres un error que indique que los límites del rasgo del método no se cumplen. Por ejemplo, el controlador puede generar el siguiente mensaje de error cuando se llama al método try_next() en una instancia Cursor:
error[E0599]: the method `try_next` exists for struct `mongodb::Cursor<T>`, but its trait bounds were not satisfied
El tipo Cursor<T> solo implementa la cualidad Stream, que se requiere para acceder al método try_next(), si se cumplen las restricciones de la cualidad para T. Específicamente, T debe implementar el trait DeserializeOwned, tal como se especifica en la documentación de la API de Cursor. El siguiente ejemplo replica el mensaje de error anterior mediante la definición de una estructura personalizada Actor para modelar documentos en la colección actors. Sin embargo, esta estructura no implementa el DeserializeOwned trait, y utilizar el método try_next() para iterar sobre instancias de Actor provoca un error:
struct Actor { name: String, } // Add setup code here let my_coll: Collection<Actor> = client.database("db").collection("actors"); let mut cursor = my_coll.find(None, None).await?; while let Some(result) = cursor.try_next().await? { println!("{:?}", result); };
Para resolver el error de límites de tipos, identifica el tipo de datos sobre el que el cursor itera y asegúrate de que este tipo de datos implementa la característica DeserializeOwned. Puedes usar el atributo derive para aplicar el límite de rasgos requerido.
Nota
Rasgos Deserialize y DeserializeOwned
La caja serde proporciona macros de derivación para generar la implementación de ciertos rasgos, incluido el rasgo Deserialize. Sin embargo, esta caja no ofrece un macro de derivación para el rasgo DeserializeOwned. Los tipos de datos que implementan Deserialize sin restricciones de vida útil implementan automáticamente DeserializeOwned, por lo que puedes implementar Deserialize para cumplir con la restricción de rasgo DeserializeOwned.
El siguiente ejemplo ajusta la definición de la estructura Actor para implementar Deserialize:
struct Actor { name: String, }
Para obtener más información sobre los límites de rasgos, consulte los siguientes recursos:
¿Cómo proceso un valor envuelto en un Enum Result u Option?
Rust proporciona los enumerados Result y Option como salvaguardias para el código de tu aplicación. Muchos métodos ofrecidos por el controlador Rust devuelven valores encapsulados en uno de estos dos tipos.
El enumerado Result puede devolver las siguientes variantes:
Ok(T)envuelve el valor del resultado de la operaciónErr(E): envuelve un valor de error si la operación no tiene éxito
Por ejemplo, el método insert_one() devuelve un tipo Result para envolver una respuesta exitosa o un error.
Para acceder al resultado sin envolver de insert_one(), utiliza el operador ?. Si la operación es exitosa, el método retorna la variante Ok(InsertOneResult) del enum Result. En este caso, el operador ? desempaqueta el valor InsertOneResult y lo asigna a la variable insert_one_result. Si la operación no tiene éxito, el método retorna la variante Err(E) del enum, y el operador ? desempaqueta y retorna el valor del error. El siguiente código muestra la sintaxis para usar el operador ? al manejar el resultado de una operación de inserción:
let insert_one_result = my_coll.insert_one(doc, None).await?;
Alternativamente, puede crear una condicional para gestionar los valores desenvueltos de InsertOneResult. El siguiente código utiliza la palabra clave match para procesar el resultado insert_one():
let insert_one_result = my_coll.insert_one(doc, None).await; match insert_one_result { Ok(val) => { println!("Document inserted with ID: {}", val.inserted_id); }, Err(err) => { println!("Operation not successful"); } }
El enumerado Option puede devolver las siguientes variantes:
Nonedelimita un valor vacío devuelto por una operaciónSome(T): envuelve un valor de retorno no vacío
Algunos métodos de los drivers de Rust devuelven un tipo Option, como el método read_concern(). Este método retorna un Option que contiene un valor vacío, si no existe un nivel de consistencia de lectura, o un valor ReadConcern.
Para acceder al resultado de read_concern(), puedes utilizar la misma sintaxis de match que se muestra en el ejemplo anterior para procesar las variantes None y Some(T). Como alternativa, puedes usar la sintaxis if let para procesar solo la variante Some(T). El siguiente código desempaqueta e imprime el valor no vacío de retorno de read_concern(), si es que existe:
if let Some(rc) = my_coll.read_concern() { println!("Read concern: {:?}", rc); }
Para obtener más información sobre los enums Result y Option, consulta los siguientes recursos en la documentación del lenguaje Rust: