Una aplicación podría necesitar derivar un valor de los datos fuente almacenados en una base de datos. Calcular un nuevo valor puede requerir una gran cantidad de recursos de CPU, especialmente con grandes conjuntos de datos o cuando se deben examinar varios documentos.
Si se solicita un valor calculado con frecuencia, puede ser más eficiente guardarlo en la base de datos con antelación. Cuando la aplicación solicita datos, solo se requiere una operación de lectura.
Acerca de esta tarea
Si las lecturas son significativamente más frecuentes que las escrituras, el patrón calculado reduce la frecuencia de cálculo de los datos. En lugar de calcular valores en cada lectura, la aplicación almacena el valor calculado y lo recalcula según sea necesario. La aplicación puede recalcular el valor con cada escritura que modifique sus datos de origen o como parte de una tarea periódica.
Nota
Con actualizaciones periódicas, no se garantiza la exactitud del valor calculado devuelto. Sin embargo, este enfoque puede justificar la mejora del rendimiento si no se requiere precisión.
Pasos
En este ejemplo, una aplicación muestra información sobre la audiencia y los ingresos de las películas. Los usuarios pueden consultar una película en particular y sus ingresos.
Insertar datos de muestra
Crea el screenings recopilación:
db.screenings.insertMany( [ { theater: "Alger Cinema", location: "Lakeview, OR", movie_title: "Lost in the Shadows", movie_id: 1, num_viewers: 344, revenue: 3440 }, { theater: "City Cinema", location: "New York, NY", movie_title: "Lost in the Shadows", movie_id: 1, num_viewers: 1496, revenue: 22440 }, ] )
Insertar datos calculados
Los usuarios suelen querer saber cuántas personas vieron una película y cuánto dinero generó. En el esquema actual, para sumar num_viewers y revenue, se debe realizar una lectura de los cines que proyectaron la película "Perdidos en las Sombras" y sumar los valores de esos campos.
Para evitar realizar ese cálculo cada vez que se solicita la información, puede calcular los valores totales y almacenarlos en una colección movies con el propio registro de la película:
db.movies.insertOne( { _id: 1, title: "Lost in the Shadows", total_viewers: 1840, total_revenue: 25880 } )
Datos calculados actualizados
Considere que se agrega una nueva proyección a la colección screenings:
db.screenings.insertOne( { theater: "Overland Park Cinema", location: "Boise, ID", movie_title: "Lost in the Shadows", movie_id: 1, num_viewers: 760, revenue: 7600 } )
Los datos calculados de la colección movies ya no reflejan los datos de cribado actuales. La frecuencia de actualización de los datos calculados depende de la aplicación:
En un entorno de escritura baja, el cálculo puede ocurrir junto con cualquier actualización de los datos
screenings.En un entorno con escrituras más regulares, los cálculos se pueden realizar a intervalos definidos (por ejemplo, cada hora). Los datos de origen en
screeningsno se ven afectados por las escrituras en la colecciónmovies, por lo que se pueden ejecutar cálculos en cualquier momento.
Para actualizar los datos calculados en función de los datos de evaluación, puede ejecutar la siguiente agregación a intervalos regulares:
db.screenings.aggregate( [ { $group: { _id: "$movie_id", total_viewers: { $sum: "$num_viewers" }, total_revenue: { $sum: "$revenue" } } }, { $merge: { into: { db: "test", coll: "movies" }, on: "_id", whenMatched: "merge" } } ] )
Resultados
El patrón computacional reduce la carga de trabajo de la CPU y aumenta el rendimiento de la aplicación. Considere el patrón computacional: su aplicación realiza los mismos cálculos repetidamente y tiene una alta tasa de lectura-escritura.