2016-11-10 43 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