2010-11-12 29 views
6

Tengo un sitio donde los usuarios primero ingresarán sus criterios de búsqueda. La búsqueda combina datos de 2 fuentes, una de las cuales no es una base de datos. Los resultados de búsqueda generalmente son lo suficientemente grandes como para ser localizados.Datos de almacenamiento en caché en grails

Dado que la consulta inicial es costosa, me gustaría almacenar en caché los resultados de la búsqueda si los criterios de búsqueda no cambian para las siguientes visitas a la página.

Mi método actual se parece a:

def search(criteriaMap, offset, pagesize) 

¿Cuál es la mejor manera de almacenamiento en caché de los resultados de búsqueda en Groovy/Grails? ¿Cómo expiraré los resultados de búsqueda?

Nota, veo que hay un complemento Springcache, pero no estoy seguro de si esto funcionará para los resultados paginados. También sé que Grails está empaquetado con ehcache pero no he visto una API a la que tenga acceso directamente, solo la he visto usar para el segundo nivel de almacenamiento en caché con GORM.

Actualización: Tomé parte de la solución de @ mfloryan para solucionar esto.

creé dos métodos en la SearchService:

@Cacheable("searchCache") 
def searchResults(uid, trimmedParams) 
def trimParams(params) 

(Uno se almacena en caché y el otro no lo es.)

Mi código en el searchController:

def trimmedParams = searchService.trimParams(params) 
def results = searchService.searchResults(trimmedParams) 

//Page results 
results = HelperService.pageResults(results, params.offset, params.max) 

[results: results, searchParams : trimmedParams] 

Como resultado, invoqué el servicio de búsqueda con una lista recortada de parámetros que no incluyen ude paginación params. Los resultados de búsqueda en caché pueden ser devueltos.

searchController se ocupa de la búsqueda.

nota: No guardé en caché los resultados de hibernación porque terminaría con el doble de datos en la memoria caché. Sólo en caché los resultados combinados de searchService.searchResults (que realiza un API REST y mi base de datos local)

Respuesta

5

En primer lugar, si desea almacenar en caché la consulta, entonces tal vez el uso de la caché de consultas de Hibernate es un buen comienzo (Set cache:true en la mappings y pasar a la cache: trueexecuteQuery)

Utilizando el SpringCache plug-in le permitirá almacenar en caché toda la respuesta del controlador. Todo lo que tendría que hacer es decorar el controlador de la siguiente manera: @Cacheable("searchMethodCache") o solo decorar los métodos individuales que desea resultados de la caché. La caché guardará la respuesta por cadena de consulta, por lo que debería funcionar bien con paginación. La anotación @CacheFlush permite establecer cuándo se debe borrar la memoria caché.

La propia caché EH está configurado en grails-app/conf/spring/resources.groovy

- ACTUALIZACIÓN -

Después de comentar empiezo a sospechar que su podría estar pensando en una solución ligeramente diferente. Entonces, hay una consulta que devuelve una lista de resultados y luego esa lista se busca y muestra.Con el enfoque estándar de Grails, Hibernate generará una consulta para cada página (devolviendo un subconjunto de la lista completa, ejecutando así la consulta potencialmente costosa una vez para cada página). Presumiblemente, desea que la consulta se ejecute una vez: para devolver el conjunto completo de resultados que se almacenan en caché y luego servir páginas individuales desde el mismo. Si ese es el caso, que sepa, tendrá que buscar los resultados manualmente desde el caché Hibernate o almacenando en caché el conjunto de resultados en otro lugar (¿Contexto de sesión?)

+0

¿Cómo interactuaría el widget de paginación con esto? ¿Puedo vaciar la caché según el tiempo o el orden FIFO? – Tihom

+0

Ir a una página diferente cambia la cadena de consulta para que la respuesta diferente se almacene en caché y luego se sirva. La caché caduca automáticamente, por lo que no es necesario realizar un vaciado explícito en función del tiempo. Simplemente configúrelo en Config.groovy en sprigcache/caches/[cacheName]/timeToLive = ... – mfloryan

+0

Me gustaría evitar la repetición para diferentes páginas. ¿Cómo puedo hacer eso? – Tihom

Cuestiones relacionadas