2010-02-19 84 views
1

假设我有以下类。 (仅包括最重要的事情)休眠搜索 - 在给定范围内搜索

public class Client { 
    /* Some Properties */ 
} 

public class ClientDocumentAssociation { 
    @ManyToOne 
    private Client client; 

    /* Some Properties */ 
} 

@Indexed 
public class Document { 
    @OneToOne 
    private ClientDocumentAssociation clientAssociation; 

    @Field(name = "text") 
    private String text; 

    /* Some Properties */ 
} 

我的基本文档搜索是这样的:

public List<AbstractDocument> searchDocuments(String text) { 
    if (text == null) { 
     return newArrayList(); 
    } 

    FullTextEntityManager ftem = Search.getFullTextEntityManager(entityManagerProvider.get()); 
    MultiFieldQueryParser parser = new MultiFieldQueryParser(DOCUMENT_FIELDS, new StandardAnalyzer()); 
    parser.setDefaultOperator(Operator.AND); 
    FullTextQuery ftq; 

    try { 
     Query q = parser.parse(text + "*"); 

     ftq = ftem.createFullTextQuery(q, Document.class); 

     ftq.setMaxResults(20); 

     List<AbstractDocument> results = ftq.getResultList(); 
     return results; 
    } catch (ParseException e) { 
     e.printStackTrace(); 
    } 

    return newArrayList(); 
} 

现在,我希望能够搜索文档,而不是在整个索引的范围,但只需查找属于给定客户的文档。我唯一想到的是将关联添加到索引中,并将客户端ID添加到搜索中的相应字段。但这看起来不正确。必须有另一种选择,这就是我所要求的。

回答

2

为什么你最初的想法似乎是错了吗?事实上,索引搜索所需的所有数据是推荐的方式。这就是@IndexedEmbedded的用处。对数据进行索引还可以为查询和/或新查询中的更改提供更大的灵活性。

+0

嗯,我认为对某些值使用索引是不合适的(例如,对某些布尔数据进行过滤看起来不正确)+给出的示例是简化的,真实的关联更加复杂 - 因此我想以其他方式过滤结果。 – 2010-02-26 10:55:57

+0

嗯...我做了一些研究,我认为你是对的,标准不是最好的方式来做到这一点。我会去索引其他值。谢谢。 – 2010-02-26 13:36:03

0

好的我确实找到了解决方案。我(和任何正在寻找相同问题的解决方案的人)所需要的是设置FullTextQuery的标准。

Session session = (Session) ftem.getDelegate(); 
    Criteria criteria = session.createCriteria(Document.class).createCriteria("clientAssociation").add(
      Restrictions.eq("client", owner)); 

    /* .... */ 

    ftq.setCriteriaQuery(criteria); 

似乎工作确定:)

+0

这不建议使用。例如,getResultSize()将返回不正确的值,分页将被拧紧。 我推荐Hardy's或Kango_V的解决方案 – 2010-03-31 07:42:15

1

另一种方法是使用过滤器。一个过滤器可以应用于Lucene搜索。 Hibernate支持添加过滤器作为注释并在运行时启用它们。