Bogdan Şara
Bogdan Şara

Reputation: 73

Why is the Lucene.NET IndexSearcher returning zero results?

I recently started working with Lucene.NET and I have some problems: I have used an IndexWriter to index my documents in C:\\TestIndex which I guess it worked since it generated several .fnm, .frq, .cfx, .tii, .tis files.

The problem is when trying to make a simple search through them, I never get any results back. Below is the code I use,

using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.QueryParsers;
using Lucene.Net.Search;
using Lucene.Net.Store;
using Lucene.Net.Util;

//Provide the directory where index is stored
Directory directory = FSDirectory.Open(newSystem.IO.DirectoryInfo(@"C:\\TestIndex")); 

IndexReader indexReader = IndexReader.Open(directory, true);
Searcher indexSearch = new IndexSearcher(indexReader);

Analyzer std = new StandardAnalyzer(Version.LUCENE_29);
QueryParser parser = new QueryParser(Version.LUCENE_29, "text", std);
Query qry = parser.Parse("morning");

// true opens the index in read only mode
Searcher srchr = new IndexSearcher(IndexReader.Open(directory, true));

TopScoreDocCollector cllctr = TopScoreDocCollector.Create(100, true);

ScoreDoc[] hits = cllctr.TopDocs().ScoreDocs;
srchr.Search(qry, cllctr); 

for (int i = 0; i < hits.Length; i++)
{
    int docId = hits[i].Doc;
    float score = hits[i].Score;
    Document doc = srchr.Doc(docId);
    Console.WriteLine("Searched from Text: " + doc.Get("text"));
}

I tried several approaches but I never get any result. Do you have any idea?

Below is indexing code,

IndexWriter indexWriter = 
    new IndexWriter(
        luceneDir, 
        new StandardAnalyzer(Version.LUCENE_29), 
        true, 
        IndexWriter.MaxFieldLength.UNLIMITED);

string[] listOfFiles = Directory.GetFiles(@"C:\Projects\lucene.net-trunk\build\vs2010\demo\MyTestProject\TestDocs");

foreach (string s in listOfFiles)
{
    String content = File.ReadAllText(s);
    Document doc = new Document();
    String title = s;

    // adding title field
    doc.Add(new Field("title", title, Field.Store.YES, Field.Index.NOT_ANALYZED));  
    doc.Add(new Field("content", content, Field.Store.YES, Field.Index.ANALYZED));

    indexWriter.AddDocument(doc);
}

indexWriter.Optimize();
indexWriter.Dispose();

Upvotes: 3

Views: 3571

Answers (3)

mbarthelemy
mbarthelemy

Reputation: 12913

Could you try explicitely specifying the field you're searching? for example:

    Lucene.Net.QueryParsers.QueryParser parser = new Lucene.Net.QueryParsers.QueryParser(Lucene.Net.Util.Version.LUCENE_29, "text", std);
    Lucene.Net.Search.Query qry = parser.Parse("content: morning");

I think that Lucene requires you to tell it on which field(s) (title, content...) you want to run your query.

Upvotes: 1

Dreamwalker
Dreamwalker

Reputation: 3035

Use luke to inspect the index to ensure it has data also you can perform searches to validate your search criteria

http://www.getopt.org/luke/

EDIT - (Luke will work with lucene and lucene.net indexes you will need to install java to use)

EDIT

Update the line

Lucene.Net.QueryParsers.QueryParser parser = new Lucene.Net.QueryParsers.QueryParser(Lucene.Net.Util.Version.LUCENE_29, "text", std);

With

Lucene.Net.QueryParsers.QueryParser parser = new Lucene.Net.QueryParsers.QueryParser(Lucene.Net.Util.Version.LUCENE_29, "content", std);

You have set the default search field to text which doesn't exist

Also you are trying to fetch the wrong field in your console.write line

Upvotes: 2

volpav
volpav

Reputation: 5128

Make sure you use the same analyzer when indexing and searching (in your case it's StandardAnalyzer I guess):

using Lucene.Net.Analysis;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.Store;

...

Directory directory = FSDirectory.Open(new System.IO.DirectoryInfo(@"C:\\TestIndex"));

var writer = new IndexWriter(
    directory, 
    new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29), 
    true, 
    new MaxFieldLength(int.MaxValue));

UPDATE

I'm using a slightly different approach for searching but, anyway, maybe you need to swap these two lines:

ScoreDoc[] hits = cllctr.TopDocs().ScoreDocs;
srchr.Search(qry, cllctr); 

So it becomes:

srchr.Search(qry, cllctr); 
ScoreDoc[] hits = cllctr.TopDocs().ScoreDocs;

meaning that the collector first collects the results when the search is executed and then you get your scored documents via the collector instance.

Upvotes: 0

Related Questions