如何使用Hibernate Search从索引中省略一些对象?

时间:2011-09-27 13:39:33

标签: hibernate hibernate-search

我们希望在Hibernate数据库上仅针对特定实体的某些目标启用全文搜索。有没有办法阻止hibernate搜索索引这个实体的某些实例?我们不想过滤搜索结果,我们只想让一些实例完全没有索引。

一个例子:我们有一个包含员工的数据库,包括活跃和退休。我们不需要能够搜索退休员工。我们是一家非常古老的IT公司,成立于1695年,因此我们有大约200万退休员工,我们非常喜欢,但不想索引,只有10个活跃的员工。有没有办法我们可以告诉Hibernate Search只为那些退休= false的员工编制索引?

此致 约亨

2 个答案:

答案 0 :(得分:0)

您需要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;
    }

}

为了在hibernate事件之外索引这些对象,您可以从该类中提取逻辑,并批量处理您的员工。

另外不要忘记注册你的听众。

答案 1 :(得分:0)

我认为你不应该直接在事件监听器中使用 IndexReader 。您应该扩展(或编写新版本)现有的 FullTextIndexEventListener 并在回调方法中检查您的实体,并根据已停用的字段调用或不调用 processWork

如果您想使用Hibernate Search 4(与Hibernate Core 4一起使用),您还需要一个自定义的 HibernateSearchIntegrator

此解决方案可行,但应在HSEARCH-471实施之前将其视为临时解决方案。