2010-02-19 82 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支持添加過濾器作爲註釋並在運行時啓用它們。