es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Mostrando un cursor de pymongo sin cargarlo en una lista.

Estoy trabajando en una aplicación PyQT5. Quiero mostrar un conjunto de datos grande extraído de una base de datos MongoDB.

Para hacerlo, extraigo mi colección en 3 cursores (necesito ordenar la visualización). Sin embargo, hasta ahora, estaba convirtiendo los cursores en una lista y luego emitiendo esa lista.

Pero ahora mi base de datos ha crecido significativamente en tamaño, y el tiempo de ejecución se ha convertido en un problema importante. Pasar por listas consume mucho tiempo. Por lo tanto, estoy tratando de encontrar una forma de acceder directamente al cursor en su totalidad sin recorrerlo (sé que suena un poco complicado ya que el cursor es simplemente una referencia a la colección).

Un ejemplo de lo que se hace ahora:

D1 = list(self.collection.find({“$and”:[{“location”: current_location}, {“vehicle”:”Car”}]}))

D2 = list(self.collection.find({“$and”:[{“location”: current_location}, {“vehicle”:{“$nin”:[“Car”,”Truck”]}}]}))

D3 = list(self.collection.find({“$and”:[{“location”: current_location}, {“vehicle” : “Truck”}]}).sort([(“_id”,-1)]).limit(60 – len(D1)))

extraido = D1 + D2 + D3
l_data_extraido.emit(extraido) # enviar los datos cargados al frente

Cargar los 3 cursores lleva mucho tiempo, pero pasarlos en una lista hace que la aplicación sea más pesada.

Busqué recursos sobre la gestión de cursores, pero cada vez veo respuestas que involucran bucles o conversiones (que ya hago).

¿Habría alguna forma de emitir directamente el cursor y, al igual que en C, pasar el argumento por referencia para obtener los datos apuntados? ¿O estoy obligado a recorrer y convertir en lista debido a su naturaleza particular?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Hasta donde yo sé, no hay forma de acceder directamente al cursor en su totalidad sin recorrerlo por completo o convertirlo en una lista. Esto se debe a que el objeto cursor en pymongo es una referencia al conjunto de resultados, que se almacena en el servidor de MongoDB. Por lo tanto, no puedes acceder a todos los resultados de una sola vez en la memoria.

    Una posible solución para evitar el bucle o la conversión de los cursores es utilizar la función de “evaluación perezosa” de pymongo. Esta función te permite iterar sobre el cursor y recuperar cada documento uno a la vez, lo que puede reducir significativamente la cantidad de memoria utilizada por tu programa.

    Para utilizar la evaluación perezosa, simplemente puedes iterar sobre el cursor usando un bucle for, así:

    cursor = self.collection.find({...}) # tu consulta aquí
    for documento in cursor:
        # hacer algo con el documento
    

    De esta manera, solo carga un documento en la memoria a la vez y puedes procesarlo inmediatamente sin tener que esperar a que se cargue todo el conjunto de resultados.

    Otra opción es utilizar el parámetro “batch_size” para controlar la cantidad de documentos recuperados por cada solicitud al servidor. Por defecto, pymongo recupera todos los documentos de una sola vez, lo que puede consumir mucha memoria. Sin embargo, al establecer el tamaño del lote en un valor menor, puedes recuperar los documentos en fragmentos más pequeños, lo que puede ser más eficiente.

    cursor = self.collection.find({...}).batch_size(100) # establecer el tamaño del lote en 100
    

    Estos métodos pueden ayudarte a optimizar el rendimiento de tu aplicación PyQT5 cuando trabajas con conjuntos de datos grandes de MongoDB.

Comments are closed.