2016-11-10 1 views
0

저는 Lucene (최대 절전 모드 검색을 통해)을 사용하여 쿼리하고자하는 기업과 사람들의 데이터베이스를 보유하고 있습니다. 검색 기능은 자동 완성 스타일 조회로 구현되며 웹 페이지는 사용자 유형과 일치하는 것을 제안합니다.단일 문자 (예 : 사람 머리 글자)로 lucene 색인을 쿼리합니다.

일부 회사 및 사람들은 이니셜을 사용하여 식별됩니다.

  • G & H 토목 엔지니어링
  • JG 반 데르 메르 웨는

나는 그들이 더 많은 텍스트를 추가로 사용자가 (검색 정제 점진적으로 문자의 몇 가지를 입력하지만, 이후 경기를 받기 시작하려면 가능하면 공백 포함). 서로 다른 몇 가지 필드를 쿼리하고 있습니다. 이름, 상호, ID 번호, 전화 번호 등을 포함 할 수 있습니다. 사용자는 이름, ID 번호, 상호 또는 셀 번호의 일부를 입력 할 수 있습니다.

그러나 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

귀하의 특정 문제는 수집기를 재사용한다는 사실과 관련이 있습니다. 이는 상태 보존 형이며 일회용으로 만 설계된 것입니다. 두 번째 쿼리에서 새 수집기를 사용하면 트릭을 수행해야합니다.

그러나, 최대 절전 모드 검색 당신은 많은 루씬 내부를 만지지 안있어주의하십시오 : 최대 절전 모드 검색 인덱싱 시간에 개체에서 루씬 문서를 자동으로 추출하고, 쿼리 할 때 필요에 따라 인덱스 독자와 수집을 구축 할 것입니다. Lucene/Hibernate Search가 처음이라면 Lucene을 직접 사용하지 않는 것이 좋습니다. Lucene은 강력하지만 사용하기 쉬운 도구는 아닙니다.

이는 수동으로 문서를 작성하는 대신 주석이 달린 (또는 프로그래밍 방식으로 매핑 된) 요소를 사용한다는 것을 의미합니다. the documentation, 특히 section about entity mappingsection about analysis을 참조하십시오.

또한 쿼리 할 때 the Hibernate Search DSL을 사용할 수 있습니다. 아마도 원시 Lucene 쿼리를 작성하는 것보다 쉬울 것입니다. 그리고 쿼리가 빌드되었을 때 Hibernate Search를 retrieve the results으로 쉽게 요청할 수도 있습니다.

관련 문제