#sql #hibernate #view #lucene #hibernate-search
#sql #переход в режим гибернации #Вид #lucene #переход в режим гибернации-поиск
Вопрос:
У меня есть таблица, в которой хранятся строки продуктов, выставленных на продажу ( tbl_products
), с использованием PostgreSQL 9.1. Есть также несколько других таблиц, в которых хранятся оценки товаров, комментариев и т. Д. Мы используем JPA / Hibernate для ORM в приложении Seam, и соответствующие объекты подключены должным образом. Стремясь предоставить лучшие списки этих товаров, я создал SQL VIEW
( v_product_summary
), который объединяет некоторые основные данные о продукте (название, описание, цена и т.д.) с данными из других таблиц (количество комментариев, средняя оценка и т.д.). Это обеспечивает хорошее краткое представление данных, и я создал соответствующий объект сущности JPA, который предоставляет доступ только для чтения к данным представления.
Все работает нормально в отношении выполнения запросов JPQL либо к Product
object ( tbl_products
), либо к ProductSummary
v_product_summary
объектам () . Тем не менее, мы хотели бы предоставить более широкие возможности поиска с помощью Hibernate Search и Lucene. Проблема, с которой мы сталкиваемся, заключается в том, как мы запрашиваем ProductSummary
объекты с помощью поиска в режиме гибернации? Они не индексируются при создании, потому что они никогда не «создаются». Они получены как объекты, доступные только для чтения из v_product_summary
VIEW
. Запись индекса создается только Product
тогда, когда она сохраняется в базе данных, а не для ProductSummary
, поскольку она никогда не сохранялась.
Мы считаем, что мы должны иметь возможность:
- Сохраняем наш
Product
объект в базе данных - Немедленно запрашивайте соответствующий
ProductSummary
объект, используя идентификатор продукта - Вручную обновите индекс поиска в режиме гибернации для
ProductSummary
объекта
Возможно ли это? Это вообще хорошая идея? Я вижу, что это повлияет на производительность, поскольку мы выполняем запрос для ProductSummary
объекта каждый раз, когда сохраняется новый продукт. Однако продукты не добавляются в базу данных в большом объеме, поэтому я не думаю, что это будет большой проблемой.
Нам бы очень хотелось найти лучший и более эффективный способ достижения этой цели. Кто-нибудь может дать какие-либо советы или рекомендации? Если мы пойдем по пути обновления поискового индекса вручную, это вообще выполнимо? Может ли кто-нибудь предоставить ресурс, объясняющий, как мы можем добавить один ProductSummary в индекс?
Мы будем признательны за любую помощь, которую вы можете предоставить.
Комментарии:
1. У меня также есть аналогичное требование. можете ли вы поделиться тем, как с этим справиться? Создайте индекс для представления, но при вставке новой записи в таблицу, связанную с представлением, индекс не может быть обновлен автоматически.
Ответ №1:
Если я правильно понимаю вопрос, вы пытаетесь сделать обычную вещь — сохранить объект и индексировать его в этот момент, но вы имеете дело с 2 отдельными объектами.
Я постоянно занимаюсь в режиме гибернации сложными вещами, такое ощущение, что это почти требует от вас. Да, это повлияло бы на производительность, и, как вы говорите, это, вероятно, не имеет большого значения, поэтому, возможно, стоит профилировать.
Часть меня помнит, что есть способ обновить объект при записи, и задается вопросом, есть ли способ, которым вы можете обернуть Product и ProductSummary и настроить отображение так, чтобы вы читали часть и записывали часть этого (махая руками на синтаксис и отображение). Или создайте объект, обращенный к режиму гибернации, с полями, доступными только для чтения, которые можно разделить и объединить в два ваших объекта. Я не знаю, разрешает ли ваш дизайн объекты только для гибернации, это обычная идиома в моей системе.
Любой способ может быть полезен, если в этой ситуации у вас было много объектов, если это единственный объект, который вы ищете таким образом, ваши 3 шага выглядят намного понятнее.
Что касается синтаксиса для добавления объекта вручную, я думаю, вы ищете что-то вроде этого, после вашей выборки:
FullTextSession textSession = Search.getFullTextSession(session);
textSession.index(myProductSummary);
Это все, что вы хотели?
Ответ №2:
Поскольку вы используете postgresql, вы можете вставить в представление и использовать правило для перенаправления вставки в соответствующую таблицу.
Правило postgresql — это способ изменить запрос непосредственно перед его выполнением. Я использовал его в приложении, которое нуждалось в изменении схемы, но требовало, чтобы старые запросы все еще работали некоторое время.
Вы можете ознакомиться с документацией о правилах для запросов вставки на сайте postgresql
Поскольку вы будете вставлять и обновлять представление, поиск в режиме гибернации будет работать как обычно.
Редактировать
Более простая стратегия. Вы можете вставлять и обновлять ProductSummary
при выполнении этого Product
и указывать PostgreSQL игнорировать вставки, обновления и удаления в представлении.
На стороне базы данных»
create RULE dontinsert AS ON insert to v_product_summary do instead nothing
create RULE dontupdate AS ON update to v_product_summary do instead nothing
create RULE dontdelete AS ON delete to v_product_summary do instead nothing
Но я думаю, вам нужно будет немного взломать, поскольку вызов jdbc executeUpdate
вернет 0, и спящий режим, вероятно, выйдет из строя.
Ответ №3:
Технически я думаю, что это было бы возможно, но я думаю, что вся ваша дилемма эффективности может быть лучше решена с помощью чего-то вроде memcached, что снижает производительность и, возможно, повышает удобство обслуживания кода в зависимости от того, как вы в настоящее время это реализовали на уровне оператора. Обновляя индекс поиска вручную, вы имеете в виду индекс базы данных? Это не рекомендуется, и я не уверен, что это вообще выполнимо. Почему бы не проиндексировать их при создании?
Комментарии:
1. Нет, я имел в виду индекс Lucene. Он автоматически обновляется при использовании JPA / Hibernate для сохранения объекта в базе данных. Однако в этом случае я не сохраняю объект, который сопоставляется с ПРЕДСТАВЛЕНИЕМ, поэтому индекс поиска в объекте ПРЕДСТАВЛЕНИЯ никогда не обновляется. Я искал способ добиться этого, чтобы я мог искать объекты представления.