# Problem bei Suche im Lucene-Index (nach Dateinamen suchen)



## Kryptaesthesie (9. April 2008)

Hallo zusammen,
ich versuche mich mit Lucene vertraut zu machen.
Mein erstes Ziel sollte sein, nach Dateien eines Verzeichnisses suchen zu können.
Also baue ich meinen Index so auf:

```
public class IndexCreator {

    private Directory directory;
    
    public IndexCreator() {
        try {
            this.directory = FSDirectory.getDirectory("D:\\Temp\\index");
        } catch(IOException ioe) { ioe.printStackTrace(); }
        
        buildIndex();
        searchFiles();
    }
    
    public void buildIndex() {
        IndexWriter writer = null;
        try {
            
            //writer = new IndexWriter(indexFile, new StandardAnalyzer(), true);
            writer = new IndexWriter(directory, new StandardAnalyzer(), true);
            
            Document doc = null;
            File dir = new File("D:\\Temp");
            for(File f : dir.listFiles()) {
                doc = new Document();
                Field field = new Field("file", f.getAbsolutePath(), Field.Store.YES, Field.Index.NO);
                
                doc.add(field);
                writer.addDocument(doc);
            }
            writer.optimize();
            writer.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
...
```
Der Index wird erstellt!
Dann folgt die Suche _searchFiles();_
Die hat folgenden Code:

```
...
    public void searchFiles() {
        IndexSearcher searcher = null;
        try {
            
            searcher = new IndexSearcher(directory);
            
            search(searcher, "icon");
            
            searcher.close();
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private void search(Searcher searcher, String queryString) throws ParseException, IOException {
    
      // Build a Query object
      QueryParser parser = new QueryParser("file", new StandardAnalyzer());
      Query query = parser.parse(queryString);
    
      // Search for the query
      Hits hits = searcher.search(query);
    
      // Examine the Hits object to see if there were any matches
      int hitCount = hits.length();
      if(hitCount == 0) {
        System.out.println("No matches were found for \"" + queryString + "\"");
      } else {
        System.out.println("Hits for \"" + queryString + "\" were found in quotes by:");
    
        // Iterate over the Documents in the Hits object
        for(int i = 0; i < hitCount; i++) {
          Document doc = hits.doc(i);
    
          // Print the value that we stored in the "title" field. Note
          // that this Field was not indexed, but (unlike the
          // "contents" field) was stored verbatim and can be
          // retrieved.
          System.out.println(" " + (i + 1) + ". " + doc.get("file"));
        }
      }
      System.out.println();
    }
```
Wenn ich jetzt 

```
public static void main(String[] args) {
        new IndexCreator(null);
    }
```
ausführe, bekomme ich aber immer nur 





> No matches were found for "icon"


 als Ergebnis.

Sieht einer von euch einen Fehler im Code?
Wie gesagt, es geht mir nur um die Dateinamen, nicht um den Dateiinhalt!


Vielen Dank schon mal für eure Hilfe!
MfG Gerrit


----------



## Fulk (9. April 2008)

Hallo,

ich habe jetzt nur kurz den Quelltext überflogen.

Aber wie es scheint ist doch "icon" nur ein Teil des gesamten Filepaths - oder?
(Du hast ja im Field "file" den gesamten Pfad einlesen lassen, also z.b. C:/.../.../icon).

Demzufolge müsstest Du entweder den vollen Pfad der Suche übergeben(also QueryParser verwenden) oder Du verwendest sog. wildcards (* und ?). Das erfordert aber wiederum eine WildcardQuery.

Hier eine kurze Übersicht über die Query-Arten von Lucene:
http://lucene.apache.org/java/2_2_0/api/org/apache/lucene/search/Query.html

Ich hoffe ich konnte ein wenig helfen.
Viele Grüße.


----------



## Kryptaesthesie (9. April 2008)

Danke schon mal für deine Hilfe!



Fulk hat gesagt.:


> Demzufolge müsstest Du entweder den vollen Pfad der Suche übergeben(also QueryParser verwenden)


Ich habe jetzt mal nach "D:\Temp\application_icon_trash.png" gesucht. Diese Datei müsste gefunden werden und der Pfad steht auch in der Lucene-Index-Datei drin, wenn ich mir diese mit nem Texteditor anschaue.

Aber trotzdem kommt 





> No matches were found for "D:\Temp\application_icon_trash.png"


----------



## Fulk (9. April 2008)

Ich musste mich in letzter Zeit auch ein wenig in Lucene einarbeiten.
Bei meiner Recherche im Internet bin ich auf ein kleines Tool gestoßen, was mir sehr geholfen hat.
Es heißt "Luke". Damit kannst Du Dir Deine Indizes anzeigen lassen und auch Anfragen stellen.

Unter 
http://www.getopt.org/luke/
kannst Du es Dir runterladen.

Viele Grüße.


----------



## Kryptaesthesie (9. April 2008)

Fulk hat gesagt.:


> Ich musste mich in letzter Zeit auch ein wenig in Lucene einarbeiten.
> Bei meiner Recherche im Internet bin ich auf ein kleines Tool gestoßen, was mir sehr geholfen hat.
> Es heißt "Luke". Damit kannst Du Dir Deine Indizes anzeigen lassen und auch Anfragen stellen.


Vielen Dank! 

Wenn ich in Luke unter Search einen Begriff eingebe, oder auch den vollen Pfadnamen, komme ich trotzdem nicht zum Ziel. Es werden mir keine Suchergebnisse angezeigt


----------



## Fulk (9. April 2008)

Mhh, Problem ist hier der gewählte Analyzer.
Auf der rechten Seite kann man ihn einstellen. 
Wählt man jedoch bspw. SimpleAnalyzer, so macht der Dir alle "/" weg. Ich glaube der WhitespaceAnalyzer hat bei mir geklappt.

Beachte jedoch, dass die Suche bzw. das Einstellen des Analyzers in Luke nicht ganz ernst zu nehmen ist, da Du bei Deiner Indexerstellung einen Analyzer angeben musst (Du hast den StandardAnalyzer gewählt). Wenn Du jetzt in Luke für Deine Anfrage einen anderen Analyzer nimmst, so macht dies keinen Sinn.

Hast Du geschaut, ob der Index prinzipiell korrekt erstellt wurde?

Wie schon gesat, kannst es ja auch mal mit einer Wildcardquery. Die finde ich am flexibelsten.


----------



## Kryptaesthesie (10. April 2008)

Vielen Dank für deine Hilfe! Ich bin schon einen Schritt weiter! 

Ich nutze jetzt den WhitespaceAnalyzer und habe für Pfad und Dateinamen zwei Fields

```
for(File f : dir.listFiles()) {
                doc = new Document();
                Field field = new Field("file", f.getName(), Field.Store.YES, Field.Index.TOKENIZED);
                doc.add(field);
                field = new Field("path", f.getPath(), Field.Store.YES, Field.Index.TOKENIZED);
                doc.add(field);
                
                writer.addDocument(doc);
            }
```
Wenn ich jetzt nach dem Dateinamen suche, klappt das hervorragend, wenn ich den vollen Dateinamen angebe.
Wenn ich jetzt aber mit Wildcards arbeiten möchte, dann klappt das auch. 
*Bsp:* _application_icon_trash.?ng _oder_ application*_
Aber was mache ich, wenn ich nach _icon_ suchen möchte?
Ich kann doch keinen Wildcard am Anfang des Suchbegriffs packen, oder? Jedenfalls meckert Luke dann.

Weiß da noch jemand rat?


----------



## Fulk (10. April 2008)

Na das klingt doch erstmal super!

Bei mir war es so, dass die Pfade, die durchsucht werden sollten immer mit "/...." anfingen.
Da habe ich einfach an den eingegebenen String (bspw. Nutzer wollte alle .java-Files haben --> also "*.java") ein "/" vorne angehangen, so dass Lucene nach "*/**.java" gesucht hat.


----------



## Fulk (2. Januar 2009)

Hi,

da ich mich auch mal wieder mit Lucene beschäftige habe ich mal ein wenig im Netz geschaut und bin auf folgendes gestoßen.

Mittels:

```
parser = new MultiFieldQueryParser(new String[]{"text", "pfad", "owner"}, new StandardAnalyzer());
parser.setAllowLeadingWildcard(true);
```
kannst Du nun auch Wildcards an den Anfang setzen 

Viele Grüße,
Fulk.


----------

