2017-05-10 3 views
1

Lucene을 Spring MVC 기반 프로젝트에 통합하기 위해 노력하고 있으며, 현재 숫자로 검색하는 것 이외에도 잘 작동합니다.Jave, Lucene : 숫자가 문자열이 아닌 것으로 검색했습니다.

123Ab 또는 123 또는 그 안에 숫자가있는 것으로 검색하려고 시도 할 때마다 검색 결과가 표시되지 않습니다.

숫자를 삭제하자마자 제대로 작동합니다.

제안 사항? 고맙습니다.

코드 :

public List<Integer> searchLucene(String text, long groupId, boolean type) { 
     List<Integer> objectIds = new ArrayList<>(); 
     if (text != null) { 
      //String specialChars = "+ - && || ! () { } [ ]^\" ~ * ? : \\ /"; 
      text = text.replace("+", "\\+"); 
      text = text.replace("-", "\\-"); 
      text = text.replace("&&", "\\&&"); 
      text = text.replace("||", "\\||"); 
      text = text.replace("!", "\\!"); 
      text = text.replace("(", "\\("); 
      text = text.replace(")", "\\)"); 
      text = text.replace("{", "\\}"); 
      text = text.replace("{", "\\}"); 
      text = text.replace("[", "\\["); 
      text = text.replace("^", "\\^"); 
      // text = text.replace("\"","\\\""); 
      text = text.replace("~", "\\~"); 
      text = text.replace("*", "\\*"); 
      text = text.replace("?", "\\?"); 
      text = text.replace(":", "\\:"); 
      //text = text.replace("\\","\\\\"); 
      text = text.replace("/", "\\/"); 
      try { 
       Path path; 
      //Set system path code 
        Directory directory = FSDirectory.open(path); 
        IndexReader indexReader = DirectoryReader.open(directory); 
        IndexSearcher indexSearcher = new IndexSearcher(indexReader); 
        QueryParser queryParser = new QueryParser("contents", new SimpleAnalyzer()); 
        Query query; 
        query = queryParser.parse(text+"*"); 
        TopDocs topDocs = indexSearcher.search(query, 50); 
        for (ScoreDoc scoreDoc : topDocs.scoreDocs) { 
         org.apache.lucene.document.Document document = indexSearcher.doc(scoreDoc.doc); 
         objectIds.add(Integer.valueOf(document.get("id"))); 
         System.out.println(""); 
         System.out.println("id " + document.get("id")); 
         System.out.println("content " + document.get("contents")); 
        } 
        indexSearcher.getIndexReader().close(); 
        directory.close(); 
       return objectIds; 
      } catch (Exception ignored) { 
      } 
     } 
     return null; 
    } 

인덱싱 코드 :

@Override 
    public void saveIndexes(String text, String tagFileName, String filePath, long groupId, boolean type, int objectId) { 
     try { 
      //indexing directory 
      File testDir; 
      Path path1; 
      Directory index_dir; 
      if (type) { 
      // System path code 
      Directory directory = org.apache.lucene.store.FSDirectory.open(path); 
      IndexWriterConfig config = new IndexWriterConfig(new SimpleAnalyzer()); 
      IndexWriter indexWriter = new IndexWriter(directory, config); 


      org.apache.lucene.document.Document doc = new org.apache.lucene.document.Document(); 
      if (filePath != null) { 
       File file = new File(filePath); // current directory 
       doc.add(new TextField("path", file.getPath(), Field.Store.YES)); 
      } 
      doc.add(new StringField("id", String.valueOf(objectId), Field.Store.YES)); 
      // doc.add(new TextField("id",String.valueOf(objectId),Field.Store.YES)); 
      if (text == null) { 
       if (filePath != null) { 
        FileInputStream is = new FileInputStream(filePath); 
        BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 
        StringBuilder stringBuffer = new StringBuilder(); 
        String line; 
        while ((line = reader.readLine()) != null) { 
         stringBuffer.append(line).append("\n"); 
        } 
        stringBuffer.append("\n").append(tagFileName); 
        reader.close(); 
        doc.add(new TextField("contents", stringBuffer.toString(), Field.Store.YES)); 
       } 
      } else { 
       text = text + "\n" + tagFileName; 
       doc.add(new TextField("contents", text, Field.Store.YES)); 
      } 
      indexWriter.addDocument(doc); 
      indexWriter.commit(); 
      indexWriter.flush(); 
      indexWriter.close(); 
      directory.close(); 


     } catch (Exception ignored) { 
     } 
    } 

내가 함께 와일드 카드 즉 *없이 노력했다. 고맙습니다.

+0

코드 검색이 아니라 코드 색인 생성에 관한 내용입니다. 그 (색인 부분)과 lucene의 어떤 버전을 보여줄 수 있습니까? –

+0

@SabirKhan : 네 말이 맞아, 내 실수 야. 메인 포스트에 색인 코드를 추가했습니다. 친절하게보세요. 고맙습니다. –

+0

@SabirKhan : 편집 해 주셔서 감사합니다. –

답변

1

색인 생성 코드에 문제가 있습니다.

귀하의 필드 contentsTextField이며 SimpleAnalyzer 설명서를 참조하는 경우가 있으므로 SimpleAnalyzer를 사용하고, 그것은

이 LowerCaseFilter

와 LetterTokenizer 필터 분석기는 그래서 당신의 수단을 말한다 필드로 설정하면 토큰 화 된 숫자가 제거됩니다.

지금 TextField 코드에서, 여기에 TextField는 관계없이 항상이 TYPE_STORED 또는 TYPE_NOT_STORED 인의 토큰 화 본다.

글자와 숫자를 색인화하려면 TextField 대신 StringField을 사용해야합니다.

StringField 문서,

색인하지만 토큰 화되지 않은 필드 : 전체 문자열 값이 하나의 토큰으로 색인 입니다. 예를 들어 'country'필드 또는 'id'필드 또는 필드 캐시를 통해 정렬하거나 액세스하기 위해 을 사용하려는 필드에 사용할 수 있습니다.

StringField

은 그래서 인덱싱 후, 숫자 contents 필드에서 제거됩니다

TYPE_STORED 또는 TYPE_NOT_STORED 인 당신이 검색하는 동안 그 패턴을 찾을 수없는, 그래서 수없이 인덱싱에 관계없이 토큰 화되지 않습니다.디버깅 인덱서 측 또는 수색자 측면에 집중 될 경우

대신 QueryParser

및 복잡한 검색하고, 첫번째 먼저 인덱스 약관을 확인하려면 아래 같은 쿼리를 사용하여, 또한

Query wildcardQuery = new WildcardQuery(new Term("contents", searchString)); 
TopDocs hits = searcher.search(wildcardQuery, 20); 

Luke Tool를 사용, 알고 용어가 귀하의 필요에 따라 만들어 졌는지 확인하십시오. 이용 약관이 있으면 검색 자 코드에 집중할 수 있습니다.

+0

지금 TextField에서 StringField로 바뀌 었습니다. 이제는 검색하려고하는 텍스트에 대한 결과가 표시되지 않습니다. –

+0

색인을 생성 한 텍스트와 검색 한 내용 (즉, '텍스트'매개 변수 값)과 Lucene의 버전은 무엇입니까? –

+0

숫자에 대한 근본 원인은 내가 코드에서 언급 한 것입니다. 먼저 인덱스 파서를 검증하기 위해 쿼리 파서 대신'WildCardQuery','TermQuery' 등을 직접 사용하는 것이 좋습니다. –

관련 문제