Vai al contenuto principale

Cache delle query

Traduzione Beta Non Ufficiale

Questa pagina è stata tradotta da PageTurner AI (beta). Non ufficialmente approvata dal progetto. Hai trovato un errore? Segnala problema →

Puoi memorizzare nella cache i risultati selezionati con questi metodi di QueryBuilder: getMany, getOne, getRawMany, getRawOne e getCount.

Puoi anche memorizzare nella cache i risultati selezionati dai metodi find* e count* di Repository ed EntityManager.

Per abilitare la cache, devi attivarla esplicitamente nelle opzioni della data source:

{
type: "mysql",
host: "localhost",
username: "test",
...
cache: true
}

Quando abiliti la cache per la prima volta, devi sincronizzare lo schema del database (usando CLI, migrazioni o l'opzione synchronize della data source).

Poi in QueryBuilder puoi abilitare la cache per qualsiasi query:

const users = await dataSource
.createQueryBuilder(User, "user")
.where("user.isAdmin = :isAdmin", { isAdmin: true })
.cache(true)
.getMany()

Query equivalente con Repository:

const users = await dataSource.getRepository(User).find({
where: { isAdmin: true },
cache: true,
})

Questo eseguirà una query per recuperare tutti gli utenti admin e memorizzerà i risultati nella cache. Alla successiva esecuzione dello stesso codice, gli utenti admin verranno recuperati dalla cache. La durata predefinita della cache è pari a 1000 ms, cioè 1 secondo. Ciò significa che la cache diventerà invalida 1 secondo dopo la chiamata del codice del query builder. Nella pratica, se gli utenti aprono la pagina utente 150 volte in 3 secondi, verranno eseguite solo tre query in questo periodo. Gli utenti inseriti durante la finestra di cache di 1 secondo non verranno restituiti.

Puoi modificare manualmente il tempo di cache tramite QueryBuilder:

const users = await dataSource
.createQueryBuilder(User, "user")
.where("user.isAdmin = :isAdmin", { isAdmin: true })
.cache(60000) // 1 minute
.getMany()

O tramite Repository:

const users = await dataSource.getRepository(User).find({
where: { isAdmin: true },
cache: 60000,
})

O globalmente nelle opzioni della data source:

{
type: "mysql",
host: "localhost",
username: "test",
...
cache: {
duration: 30000 // 30 seconds
}
}

Inoltre, puoi impostare un "cache id" tramite 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,
},
})

Questo ti offre un controllo granulare della cache, ad esempio per cancellare i risultati memorizzati quando inserisci un nuovo utente:

await dataSource.queryResultCache.remove(["users_admins"])

Per impostazione predefinita, TypeORM utilizza una tabella separata chiamata query-result-cache per memorizzare query e risultati. Il nome della tabella è configurabile modificando il valore della proprietà tableName:

{
type: "mysql",
host: "localhost",
username: "test",
...
cache: {
type: "database",
tableName: "configurable-table-query-result-cache"
}
}

Se memorizzare la cache in una singola tabella non è efficace per te, puoi cambiare il tipo di cache in "redis" o "ioredis": TypeORM memorizzerà tutti i record in Redis. Esempio:

{
type: "mysql",
host: "localhost",
username: "test",
...
cache: {
type: "redis",
options: {
socket: {
host: "localhost",
port: 6379
}
}
}
}

"options" può essere opzioni specifiche di node_redis o opzioni specifiche di ioredis a seconda del tipo utilizzato.

Se desideri connetterti a un cluster Redis usando la funzionalità cluster di IORedis, puoi farlo così:

{
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
}
}
}
}
}

Nota che puoi comunque usare le options come primo argomento del costruttore del cluster di IORedis.

{
...
cache: {
type: "ioredis/cluster",
options: [
{
host: 'localhost',
port: 7000,
},
{
host: 'localhost',
port: 7001,
},
{
host: 'localhost',
port: 7002,
}
]
},
...
}

Se nessun provider di cache integrato soddisfa le tue esigenze, puoi specificarne uno personalizzato usando una funzione factory provider che restituisca un nuovo oggetto implementante l'interfaccia QueryResultCache:

class CustomQueryResultCache implements QueryResultCache {
constructor(private dataSource: DataSource) {}
...
}
{
...
cache: {
provider(dataSource) {
return new CustomQueryResultCache(dataSource);
}
}
}

Se vuoi ignorare gli errori della cache e far passare le query al database in caso di errori, usa l'opzione ignoreErrors:

{
type: "mysql",
host: "localhost",
username: "test",
...
cache: {
type: "redis",
options: {
socket: {
host: "localhost",
port: 6379
}
},
ignoreErrors: true
}
}

Puoi usare typeorm cache:clear per svuotare completamente la cache.