Almacenamiento en caché de consultas
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Puedes almacenar en caché los resultados seleccionados mediante estos métodos de QueryBuilder: getMany, getOne, getRawMany, getRawOne y getCount.
También puedes almacenar en caché resultados seleccionados mediante los métodos find* y count* de Repository y EntityManager.
Para habilitar el almacenamiento en caché, necesitas activarlo explícitamente en las opciones de la fuente de datos:
{
type: "mysql",
host: "localhost",
username: "test",
...
cache: true
}
Cuando habilitas la caché por primera vez,
debes sincronizar el esquema de tu base de datos (usando CLI, migraciones o la opción synchronize de la fuente de datos).
Luego, en QueryBuilder puedes activar el caché para cualquier consulta:
const users = await dataSource
.createQueryBuilder(User, "user")
.where("user.isAdmin = :isAdmin", { isAdmin: true })
.cache(true)
.getMany()
Consulta equivalente en Repository:
const users = await dataSource.getRepository(User).find({
where: { isAdmin: true },
cache: true,
})
Esto ejecutará una consulta para obtener todos los usuarios administradores y almacenará los resultados en caché.
La próxima vez que ejecutes el mismo código, obtendrá los usuarios administradores desde la caché.
El tiempo de vida predeterminado de la caché es de 1000 ms, es decir, 1 segundo.
Esto significa que la caché se invalidará 1 segundo después de que se llame al código del constructor de consultas.
En la práctica, esto significa que si los usuarios abren la página de usuario 150 veces en 3 segundos, solo se ejecutarán tres consultas durante este período.
Los usuarios insertados durante la ventana de caché de 1 segundo no se mostrarán al usuario.
Puedes cambiar manualmente el tiempo de caché mediante QueryBuilder:
const users = await dataSource
.createQueryBuilder(User, "user")
.where("user.isAdmin = :isAdmin", { isAdmin: true })
.cache(60000) // 1 minute
.getMany()
O mediante Repository:
const users = await dataSource.getRepository(User).find({
where: { isAdmin: true },
cache: 60000,
})
O globalmente en las opciones de la fuente de datos:
{
type: "mysql",
host: "localhost",
username: "test",
...
cache: {
duration: 30000 // 30 seconds
}
}
Además, puedes configurar un "ID de caché" mediante QueryBuilder:
const users = await dataSource
.createQueryBuilder(User, "user")
.where("user.isAdmin = :isAdmin", { isAdmin: true })
.cache("users_admins", 25000)
.getMany()
O con Repository:
const users = await dataSource.getRepository(User).find({
where: { isAdmin: true },
cache: {
id: "users_admins",
milliseconds: 25000,
},
})
Esto te permite un control granular de tu caché, por ejemplo, para borrar resultados en caché cuando insertas un nuevo usuario:
await dataSource.queryResultCache.remove(["users_admins"])
Por defecto, TypeORM usa una tabla separada llamada query-result-cache y almacena allí todas las consultas y resultados.
El nombre de la tabla es configurable, por lo que puedes cambiarlo especificando un valor diferente en la propiedad tableName.
Ejemplo:
{
type: "mysql",
host: "localhost",
username: "test",
...
cache: {
type: "database",
tableName: "configurable-table-query-result-cache"
}
}
Si almacenar la caché en una sola tabla de base de datos no es eficiente para ti, puedes cambiar el tipo de caché a "redis" o "ioredis" y TypeORM almacenará todos los registros en caché en redis. Ejemplo:
{
type: "mysql",
host: "localhost",
username: "test",
...
cache: {
type: "redis",
options: {
socket: {
host: "localhost",
port: 6379
}
}
}
}
"options" pueden ser opciones específicas de node_redis u opciones específicas de ioredis dependiendo del tipo que uses.
Si deseas conectarte a un clúster de redis usando la funcionalidad de clúster de IORedis, también puedes hacerlo de la siguiente manera:
{
type: "mysql",
host: "localhost",
username: "test",
cache: {
type: "ioredis/cluster",
options: {
startupNodes: [
{
host: 'localhost',
port: 7000,
},
{
host: 'localhost',
port: 7001,
},
{
host: 'localhost',
port: 7002,
}
],
options: {
scaleReads: 'all',
clusterRetryStrategy: function (times) { return null },
redisOptions: {
maxRetriesPerRequest: 1
}
}
}
}
}
Ten en cuenta que aún puedes usar opciones como primer argumento del constructor de clúster de IORedis.
{
...
cache: {
type: "ioredis/cluster",
options: [
{
host: 'localhost',
port: 7000,
},
{
host: 'localhost',
port: 7001,
},
{
host: 'localhost',
port: 7002,
}
]
},
...
}
Si ninguno de los proveedores de caché incorporados satisface tus demandas, también puedes especificar tu propio proveedor usando una función factory provider que debe devolver un nuevo objeto que implemente la interfaz QueryResultCache:
class CustomQueryResultCache implements QueryResultCache {
constructor(private dataSource: DataSource) {}
...
}
{
...
cache: {
provider(dataSource) {
return new CustomQueryResultCache(dataSource);
}
}
}
Si deseas ignorar errores de caché y que las consultas pasen directamente a la base de datos en caso de errores de caché, puedes usar la opción ignoreErrors. Ejemplo:
{
type: "mysql",
host: "localhost",
username: "test",
...
cache: {
type: "redis",
options: {
socket: {
host: "localhost",
port: 6379
}
},
ignoreErrors: true
}
}
Puedes usar typeorm cache:clear para borrar todo lo almacenado en la caché.