Как исключить некоторые объекты из индекса с помощью Hibernate Search?
Мы хотим включить полнотекстовый поиск в базе данных Hibernate только для некоторых объектов определенного объекта. Есть ли способ запретить поиску в спящем режиме индексировать некоторые экземпляры этого объекта? Мы не хотим фильтровать результаты поиска, мы просто хотим, чтобы некоторые экземпляры вообще не индексировались.
Пример: у нас есть база данных с работниками, как активными, так и вышедшими на пенсию. Нам не нужно искать пенсионеров. Мы очень старая IT-компания, основанная в 1695 году, поэтому у нас около 2 миллионов пенсионеров, которых мы очень любим, но не хотим индексировать, только 10 активных. Есть ли способ, с помощью которого Hibernate Search можно указывать только тех сотрудников, у которых в отставке = false?
С уважением, Йохен
2 ответа
Я не думаю, что вы должны работать с IndexReader непосредственно в слушателе событий. Вместо этого вы должны расширить (или написать новую версию) существующий FullTextIndexEventListener и проверить вашу сущность в методе обратного вызова и в зависимости от вызова удаленного поля или не вызова processWork.
Если вы хотите использовать Hibernate Search 4 (вместе с Hibernate Core 4), вам также потребуется пользовательский HibernateSearchIntegrator.
Это решение будет работать, но его следует рассматривать как временное решение, пока не будет реализован HSEARCH-471.
Вам понадобится PreUpdateEventListener
В этом слушателе проверьте сущность и определите, хотите ли вы добавить ее в индекс lucene.
Этот код не гарантированно работает, но, надеюсь, вы поймете идею.
public class LuceneUpdateListener implements PreUpdateEventListener {
protected FSDirectory directory; // = path to lucene index
public boolean onPreUpdate(PreUpdateEvent event) {
if (event.getEntity() instanceof Employee ) {
try {
Employee employee = (Employee) event.getEntity();
//Remove on update
remove((Employee) event.getEntity(), (Long) event.getId(), directory);
//Add it back if this instance should be indexed
try {
if (employee.shouldBeIndexed()) {
add((Employee) event.getEntity(), (Long) event.getId(), directory);
}
}
catch (Exception e) {
}
}
catch (Exception e) {
throw new CallbackException(e.getMessage());
}
}
}
return false;
}
protected synchronized void add(Employee employee, Id employeeId, FSDirectory directory) {
try{
IndexWriter writer = new IndexWriter(directory, new StandardAnalyzer(), false);
Document d = LuceneDocumentFactory.makeDocument(employee);
writer.addDocument(d);
writer.close();
directory.close();
}
catch(Exception e) {
}
}
protected synchronized void remove(Long id, FSDirectory directory) throws IOException {
try {
IndexReader ir = IndexReader.open(directory);
ir.deleteDocuments(new Term("id", id.toString()));
ir.close();
}
catch(Exception e) {
}
}
public FSDirectory getDirectory() {
return directory;
}
public void setDirectory(FSDirectory directory) {
this.directory = directory;
}
}
Чтобы проиндексировать эти объекты вне события гибернации, вы можете извлечь логику из этого класса и обработать своих сотрудников в пакетном режиме.
Также не забудьте зарегистрировать своего слушателя.