The problem of using one instance of indexSearcher for multiple queries

We use the Lucene API in the .net web application. I want to use the same instance of Indexsearcher for all queries. Storing an instance of indexsearcher in the http cache.

here is my code for the same:

if (HttpRuntime.Cache["IndexSearcher"] == null) { searcher = new IndexSearcher(jobIndexFolderPath); HttpRuntime.Cache["IndexSearcher"] = searcher; } else { searcher = (IndexSearcher)HttpRuntime.Cache["IndexSearcher"]; } 

When I execute the statement below, I get a runtime error: "The reference to the object is not installed in the instance of the object."

Hits hits = search engine. Search (myQuery);

What am I missing here?

Thanks for reading!

+2
lucene
source share
7 answers

Try the following:

 protected static IndexSearcher searcher = null; ... if (searcher == null) { searcher = new IndexSearcher(jobIndexFolderPath); } 
+4
source share

I also have a web application that uses the Lucene API to query (my web application does not write by index), and I create a new search appliance instance for each query. It may not be very " performant ", but I have never had such problems.

If you want, my web application is in Google Code so you can download the source code and see what I have done. Here's the url of the project http://code.google.com/p/goomez/

+1
source share

First of all, it is not safe, it should be:

 var searcher = (IndexSearcher)HttpRuntime.Cache["IndexSearcher"]; if(searcher == null) { searcher = new IndexSearcher(jobIndexFolderPath); HttpRuntime.Cache["IndexSearcher"] = searcher; } 

The code cache may expire between validation and assignment

+1
source share

Two things:

  • If you are using .Net 2.0 and not using SP1, this may help.
  • Look at the problem this person had.

Both entries are related to the fact that objects in the cache expired too quickly - almost immediately in both cases. Things can also be complicated by the fact that objects in the cache are not thread safe.

If you need one IndexSearcher, why not provide it to your web application as a service?

0
source share

My quick answer ...

You really don't need to use the same index search object for the whole query, in fact I would recommend it against. You only need to make sure that only one thread updates the index.

If you really want this, what about a static member variable in an application that is initialized once and used by everyone?

Long answer ... I will try to find my code and see exactly how I dealt with the problem.

0
source share

Steve, see the best ways to use IndexSearcher . This is a bit outdated, but the principle remains: use one instance of IndexSearcher, protect it using the corresponding thread safe code (which I don’t know how to do in .NET) and invalidate it after updating the index. I think this is what Jesse suggested, and I will remember this idea.

0
source share

Instead of caching indexSearcher, I now cache IndexReader. If the IndexReader is already in the cache, I check if it is updated. Otherwise, I open it and pass this instance to the indexSearcher constructor.

Does this logic / code mean an optimized search query response if multiple requests go to the web server for search?

Thanks for reading.

 string key = MyConstants.CacheKey.IndexReader; indexReader = MyCacheManager.Get<IndexReader>(key); if (indexReader == null)//cache is empty.open indexreader { indexReader = IndexReader.Open(myIndexFolderPath); MyCacheManager.Add(key, indexReader); indexSearcher = new IndexSearcher(indexReader); } else//cache contains indexreader...check if it is up to date { indexSearcher = base.GetIndexSearcher(myIndexFolderPath, indexReader); } protected IndexSearcher GetIndexSearcher(string indexFolderPath, IndexReader indexReader) { IndexSearcher indexSearcher = null; if (!indexReader.IsCurrent())//index is not up to date { indexReader = IndexReader.Open(indexFolderPath); indexSearcher = new IndexSearcher(indexReader); } else { indexSearcher = new IndexSearcher(indexReader); } return indexSearcher; } 
0
source share

All Articles