2016-11-10 31 views
0

我的公司和我想要使用Lucene(通過Hibernate Search的)來查詢的人的數據庫。搜索功能實現爲自動填充樣式查找,網頁將根據用戶類型提示匹配。與單個字符查詢Lucene索引,e.g人首字母

一些公司和人都在使用英文縮寫例如確定

  • 摹&^h土木工程
  • JG VAN DER莫維

我希望用戶爲他們增加更多的文字開始輸入幾個字母,但逐步細化搜索後得到匹配(可能包括空格)。我在查詢幾個不同的領域,例如姓名,商號,身份證號碼,電話號碼等,使用戶可以輸入部分姓名,身份證號碼,商號或手機號碼。

但是,我無法建立索引和查詢,從而像G & H一個任期將文檔匹配。使用像CIVIL這樣的術語,會有很多匹配。然而,中間有空格的單個字符不匹配任何內容。

下面的測試就上線失敗。我不確定分析儀,標記器,過濾器的組合&我應該使用的查詢。

@Test 
public void testSearching() throws Exception { 
    Analyzer analyzer = new ReusableAnalyzerBase() { 
     @Override 
     protected TokenStreamComponents createComponents(String fieldName, Reader reader) { 
      StandardTokenizer tokenizer = new StandardTokenizer(Version.LUCENE_36, reader); 
      LowerCaseFilter lowerCaseFilter = new LowerCaseFilter(Version.LUCENE_36, tokenizer); 
      NGramTokenFilter filter = new NGramTokenFilter(lowerCaseFilter, 3, 20); 
      return new TokenStreamComponents(tokenizer, filter); 
     } 
    }; 
    Directory ramDirectory = new RAMDirectory(); 

    IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_36, analyzer); 
    IndexWriter w = new IndexWriter(ramDirectory, config); 

    Document doc = new Document(); 
    doc.add(new Field("id", "819", Field.Store.YES, Field.Index.NOT_ANALYZED)); 
    doc.add(new Field("particulars.registeredName", "G & H CIVIL ENGINEERING", Field.Store.NO, Field.Index.ANALYZED)); 

    w.addDocument(doc); 
    w.close(); 

    // search 
    int numberOfHits = 200; 
    TopScoreDocCollector collector = TopScoreDocCollector.create(numberOfHits, true); 
    IndexSearcher searcher = new IndexSearcher(IndexReader.open(ramDirectory)); 

    PhraseQuery q = new PhraseQuery(); 
    q.add(new Term("particulars.registeredName", "civil")); 
    searcher.search(q, collector); 
    ScoreDoc[] hits = collector.topDocs().scoreDocs; 
    assertThat(hits.length, greaterThan(0)); 

    PhraseQuery phraseQuery = new PhraseQuery(); 
    phraseQuery.add(new Term("particulars.registeredName", "g & h")); 
    searcher.search(q, collector); 
    hits = collector.topDocs().scoreDocs; 
    assertThat(hits.length, greaterThan(0)); // this fails - no matches 

我是新來的Lucene - 任何指針將不勝感激。

回答

0

您的特定問題,可能與你重用電器,其狀態和設計僅用於一次性使用的事實。在第二個查詢中使用新的收集器應該可以做到這一點。

然而,請注意,使用Hibernate Search的你不應該多觸摸Lucene的內部:從你的實體在索引時間Hibernate Search的將自動獲得Lucene的文檔,查詢時建立索引的讀者和收藏家是必要的。我強烈建議你避免直接使用Lucene,如果你還不熟悉Lucene/Hibernate Search:Lucene功能強大,但不是一個簡單易用的工具。

這將意味着使用註釋(或編程映射)的實體,而不是手動構建文檔。請參考the documentation,特別是section about entity mappingsection about analysis

此外,查詢時,您可以使用the Hibernate Search DSL。它可能比構建原始Lucene查詢更容易。當你的查詢已經建好時,你也可以輕鬆地讓Hibernate Search登錄到retrieve the results