2017-05-10 3 views
1

Ich arbeite an der Integration von Lucene in unser Spring-MVC-basiertes Projekt und derzeit funktioniert es gut, abgesehen von der Suche mit Zahlen.Jave, Lucene: Suche mit Zahlen als String funktioniert nicht

Immer wenn ich suche wie 123Ab oder 123 oder irgendetwas, das Zahlen darin hat, habe ich keine Suchergebnisse zurück.

Sobald ich die Nummern entfernen, funktioniert es gut.

Irgendwelche Vorschläge? Vielen Dank.

Code:

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; 
    } 

Indexing Code:

@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) { 
     } 
    } 

Ich habe versucht, mit und ohne Wildcard d.h *. Vielen Dank.

+0

Es geht nicht um das Suchen von Code, sondern das Indizieren von Code. Kannst du das (den Indexteil) und welche Version von Lucene zeigen? –

+0

@SabirKhan: Du hast Recht, mein Fehler. Der Indexierungscode wurde im Hauptpost hinzugefügt. Bitte sehen Sie sich um. Vielen Dank. –

+0

@SabirKhan: Danke für die Bearbeitung. –

Antwort

1

Problem ist in Ihrem Indexierungscode.

Ihr Feld contents ein TextField ist, und Sie werden mit einem SimpleAnalyzer so, wenn Sie SimpleAnalyzer Dokumentation zu sehen, sagt er,

Ein Analyzer, die LetterTokenizer Filter mit LowerCaseFilter

Das heißt also, für Ihre Feld, wenn es auf Tokenized Zahlen eingestellt ist, werden entfernt.

Überprüfen Sie nun, TextField Code, hier ein TextField immer unabhängig von Token versehen ist TYPE_STORED oder TYPE_NOT_STORED zu sein.

Wenn Sie also Buchstaben und Zahlen indexieren möchten, müssen Sie eine StringField anstelle einer TextField verwenden.

StringField Dokumentation

Ein Feld, das indiziert ist, aber nicht in Token aufgeteilt: der gesamte String-Wert ist als einzelnes Token indexiert. Dies könnte zum Beispiel für ein Feld "Land" oder ein Feld "ID" verwendet werden, oder jedes Feld, das Sie verwenden möchten, um für das Sortieren oder den Zugriff durch den Feldcache zu verwenden.

A StringField ist nie unabhängig Token aufgeteilt davon TYPE_STORED oder TYPE_NOT_STORED

So nach der Indizierung sind Zahlen von contents Feld entfernt werden und wird ohne Zahlen indiziert, so dass Sie bei der Suche nicht diese Muster finden.

Statt QueryParser und sucht dabei komplizierte, zuerst eine Abfrage wie unten verwenden, um zunächst Ihre indizierten Bedingungen zu überprüfen,

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

auch zu wissen, ob das Debuggen auf Indexer Seite oder Sucherseite fokussiert werden, verwenden Luke Tool um zu sehen, ob Begriffe nach Ihren Bedürfnissen erstellt werden. Wenn Begriffe vorhanden sind, können Sie sich auf den Suchcode konzentrieren.

+0

Nur von TextField zu StringField geändert, jetzt bekomme ich keine Ergebnisse für den Text, den ich versuche zu suchen. –

+0

Welchen Text haben Sie indiziert und was haben Sie gesucht (z. B. 'text' Parameterwert) und welche Version von Lucene? –

+0

Ihre Ursache für Zahlen war, dass ich im Code erwähnt habe. Ich schlage vor, zuerst "WildCardQuery", "TermQuery" usw. anstelle des Abfrageparsers zu verwenden, um indizierte Terme zu verifizieren. –