Как исключить некоторые объекты из индекса с помощью 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;
    }

}

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

Также не забудьте зарегистрировать своего слушателя.

Другие вопросы по тегам