Кеширование данных в Grails - PullRequest
       20

Кеширование данных в Grails

6 голосов
/ 12 ноября 2010

У меня есть сайт, где пользователи сначала вводят свои критерии поиска. Поиск объединяет данные из 2 источников, один из которых не является базой данных. Результаты поиска обычно достаточно велики, чтобы их можно было разбить на страницы.

Поскольку первоначальный запрос является дорогим, я хотел бы кэшировать результаты поиска, если критерии поиска не меняются для последующих просмотров страниц.

Мой текущий метод выглядит так:

def search(criteriaMap, offset, pagesize)

Каков наилучший способ кэширования результатов поиска в groovy / grails? Как бы я истек результаты поиска?

Обратите внимание, я вижу, что есть плагин Springcache, но я не уверен, будет ли это работать для постраничных результатов. Я также знаю, что Grails упакован с ehcache, но я не видел API, к которому у меня есть прямой доступ, я видел только его используемый для кэширования 2-го уровня с GORM.

Обновление : Я принял участие в решении @ mfloryan, чтобы решить эту проблему.

Я создал два метода в searchService :

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

(один кэшируется, а другой нет.)

Мой код в контроллере поиска :

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

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

[results: results, searchParams : trimmedParams]

В результате я вызвал службу поиска с урезанным списком параметров, которые не включают параметры подкачки. Кэшированные результаты поиска могут быть возвращены.

searchController заботится о поисковом вызове.

note : Я не кешировал результаты гибернации, потому что в итоге я удвоил данные в кеше. Я кэшировал только объединенные результаты из searchService.searchResults (который попадает в REST API и мою локальную базу данных)

1 Ответ

5 голосов
/ 12 ноября 2010

Во-первых, если вы хотите кешировать запрос, то, возможно, стоит начать использовать кеш запросов Hibernate (установите cache:true в mappings и передайте cache: true в executeQuery)

Использование плагина SpringCache позволит вам кэшировать весь ответ от контроллера. Все, что вам нужно сделать, это декорировать контроллер следующим образом: @Cacheable("searchMethodCache") или декорировать только отдельные методы, которые вы хотите, чтобы результаты кэшировались. Кэш сохранит ответ по строке запроса, поэтому он должен хорошо работать с подкачкой страниц. Аннотация @CacheFlush позволяет указать, когда следует очищать кэш.

Сам EH Cache настроен в grails-app/conf/spring/resources.groovy

- ОБНОВЛЕНИЕ -

После вашего комментария я начинаю подозревать, что вы думаете о немного другом решении. Таким образом, существует запрос, который возвращает список результатов, и этот список затем разбивается на страницы и отображается. При стандартном подходе Grails Hibernate будет генерировать один запрос для каждой страницы (возвращая подмножество из полного списка, таким образом выполняя потенциально дорогой запрос один раз для каждой страницы). Предположительно, вы хотите, чтобы запрос выполнялся один раз - возвращать полный набор результатов, который кэшируется, а затем обслуживать отдельные страницы из него. Если это так, то, насколько я знаю, вам придется вручную выводить результаты из кэша Hibernate или кэшировать набор результатов в другом месте (контекст сеанса?)

...