2013-09-06 5 views
0

내 사용자 검색에 Lucene을 사용하고 있습니다. 인덱스를 들어 다음 코드를lucene 검색이 작동하지 않습니다.

private void internalAddUser(User user) throws IOException { 
    Document document = new Document(); 
    document.add(new Field("login", user.getLogin(), Field.Store.YES, Field.Index.NOT_ANALYZED)); 
    document.add(new Field("firstName", user.getFirstName(), Field.Store.YES, Field.Index.NOT_ANALYZED)); 
    document.add(new Field("lastName", user.getLastName(), Field.Store.YES, Field.Index.NOT_ANALYZED)); 
    userIndexWriter.addDocument(document); 
} 

을 가지고 검색을위한 나는 다음과 같은 코드를 사용하지만 난 어떤 결과를 얻고 있지 않다.

@Override 
@Cacheable("user-prefix-cache") 
public Collection<String> searchUserByPrefix(String prefix) { 
    IndexSearcher searcher = null; 
    List<String> logins = new ArrayList<String>(); 
    try { 
     searcher = userSearcherManager.acquire(); 

     BooleanQuery booleanQuery = new BooleanQuery(); 

     Query query1 = new TermQuery(new Term("login", prefix)); 
     Query query2 = new TermQuery(new Term("firstName", prefix)); 
     Query query3 = new TermQuery(new Term("lastName", prefix)); 

     booleanQuery.add(query1, BooleanClause.Occur.SHOULD); 
     booleanQuery.add(query2, BooleanClause.Occur.SHOULD); 
     booleanQuery.add(query3, BooleanClause.Occur.SHOULD); 

     SortField sortField = new SortField("login", SortField.STRING, true); 
     Sort sort = new Sort(sortField); 

     TopDocs topDocs = searcher.search(booleanQuery, DEFAULT_TOP_N_SEARCH_USER, sort); 
     int totalHits = topDocs.totalHits; 
     if (totalHits == 0) { 
      return new ArrayList<String>(); 
     } 

     ScoreDoc[] scoreDocArray = topDocs.scoreDocs; 
     for (int i = 0; i < scoreDocArray.length; i++) { 
      int documentId = scoreDocArray[i].doc; 
      Document document = searcher.doc(documentId); 
      logins.add(document.get("login")); 
     } 
    } catch (IOException e) { 
     log.error("A Lucene query had a I/O error : " + e.getMessage()); 
     if (log.isDebugEnabled()) { 
      e.printStackTrace(); 
     } 
    } finally { 
     try { 
      userSearcherManager.release(searcher); 
     } catch (IOException e) { 
      log.error("The Lucene searcher could not be given back to the searcherManager pool. " + 
        e.getMessage()); 

      if (log.isDebugEnabled()) { 
       e.printStackTrace(); 
      } 
     } 
    } 
    return logins; 
} 

저는 기대하지 않지만 왜 작동하지 않는지 잘 모르겠습니다. 아무도 아무 생각이 없어요.

[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : j 
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : j 
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : ju 
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : jul 
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : juli 
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : julia 
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : julianb 
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : julianb 
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : julian 
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : julia 
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : juli 
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : jul 
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : ju 
[DEBUG] in.daydiary.web.rest.SearchController - REST request to find users starting with : j 

답변

1

두 가지가 의심스러워 보입니다.

모든 필드는 Field.Index.NOT_ANALYZED입니다. 즉, 토큰 화되지는 않지만 여기에서 검색 할 때 전체 필드의 정확한 일치 항목 만 일치시킵니다. 대소 문자를 구분합니다. 정확히 어떤 데이터가 인덱싱되었는지, 쿼리 대상이 실제로 문제인지 이해하는 데 도움이됩니다.

둘째, 메서드 이름은 접두사 검색을 원하지만 접두사 검색을 사용하고 있지 않음을 나타냅니다. TermQuery은 정확히 일치하는 것을 얻을 것입니다. PrefixQuery은 정확히 TermQuery처럼 사용되는 접두사에 의해 검색하는 데 사용된다 :

Query query1 = new PrefixQuery(new Term("login", prefix)); 
    booleanQuery.add(query1, BooleanClause.Occur.SHOULD); 
+0

나는 검색 상자를 가지고 ... 그래서 난 사용자가 검색 시작해야합니다 예를 들어 입력 시작하는 순간을합니다. 내 로그인 정보에는 전자 메일 아이디가 들어 있습니다. 예를 들어 firstName은 피터, lastName은 foo입니다. –

+0

내가 말했듯이, 당신은'PrefixQuery'를 사용해야합니다, 그리고 분석은 여기에서도 필요할 것 같습니다. – femtoRgon

+0

코드를 Prefix Query로 변경했지만 결과가 여전히 없습니다. –

0

첫째. lucene 버전을 제공 할 때주의하십시오.

초. 인덱스를 확실히 볼 수 있습니다. Lucene과 동일한 버전의 luke를 얻을 수 있습니다. luke 내부에서 색인 된 데이터를 볼 수 있습니다 .. java -jar jarname을 실행하여 실행하십시오.

셋째. 색인 생성 과정에서 사용되는 분석기와 검색 과정에서 사용되는 분석기가 같은지 확인하십시오. 이것은 모든 사람이 자주 범하는 실수입니다.

넷째. 당신이 타격을 입지 않으므로, HITS가 발견되지 않을 수도있는 몇 가지 사항을 언급 한이 훌륭한 링크를 참조하십시오.

http://wiki.apache.org/lucene-java/LuceneFAQ#Why_am_I_getting_no_hits_.2F_incorrect_hits.3F

관련 문제