我们希望在Hibernate数据库上仅针对特定实体的某些目标启用全文搜索。有没有办法阻止hibernate搜索索引这个实体的某些实例?我们不想过滤搜索结果,我们只想让一些实例完全没有索引。
一个例子:我们有一个包含员工的数据库,包括活跃和退休。我们不需要能够搜索退休员工。我们是一家非常古老的IT公司,成立于1695年,因此我们有大约200万退休员工,我们非常喜欢,但不想索引,只有10个活跃的员工。有没有办法我们可以告诉Hibernate Search只为那些退休= false的员工编制索引?
此致 约亨
答案 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实施之前将其视为临时解决方案。