2009-05-22 25 views
2

在.net Web应用程序中使用Lucene API。 我想为所有请求使用Indexsearcher的相同实例。因此我们将indexsearcher实例存储在http缓存中。在多个请求中使用indexSearcher的相同实例的问题

这里是我的同一代码:

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

当我执行下面的语句,我得到一个运行时错误:“对象引用不设置到对象的实例。”

Hits hits = searcher.Search(myQuery);

我在这里失踪了什么?

感谢您的阅读!

+0

两条评论:1.)你是否有与存储在HttpRuntime中的其他对象相同的问题? 2.)以防万一你错过了,已经打开的IndexSearcher不能在索引中看到新的条目。所以如果你的应用程序是一个长期运行的搜索索引更新,你可能应该重新考虑对所有请求使用相同的IndexSearcher实例 – StudioEvoque 2009-05-31 12:28:34

+0

fyi,我能够存储和检索HttpRuntime中的其他对象 – 2009-06-11 02:49:49

+1

我不熟悉.net或HttpRuntime。你的代码有一个问题是缺乏同步。但是这只会导致性能不佳和不正确问题。您仍然可以尝试同步初始化。 第二个问题我怀疑是由于某些问题,搜索者根本没有得到初始化。在创建新的IndexSearcher后,检查搜索器是否为空。 – 2009-06-12 06:10:38

回答

4

尝试类似如下:

protected static IndexSearcher searcher = null; 
... 

if (searcher == null) 
{ 
    searcher = new IndexSearcher(jobIndexFolderPath); 
}
0

两件事情:

  1. 如果您正在使用的.Net 2.0,并没有应用SP1,this可能会有帮助。
  2. 看看this人有问题。

这两个条目都指的是缓存中的对象过早过期 - 几乎在两种情况下都立即生效。事情也可能因缓存中的对象不是线程安全的事实而变得复杂。

如果你必须有一个IndexSearcher,为什么不把它作为一个服务提供给Web应用程序?

0

我快速的答案是...

你并不真的需要使用相同的索引搜索的对象为所有的请求,其实我会建议反对。您只需确保只有一个线程更新索引。

如果你真的想要一个,那么应用程序中的一个静态成员变量如何被初始化一次并被所有人使用?

长的答案是... 我会尽量找到我的代码,看看我究竟是如何处理的问题

1

我也有一个使用Lucene的API来查询Web应用程序(我的Web App不写在索引上),并为每个请求创建一个搜索器的新实例。它可能不是很“performant”,但我从来没有这样的问题。

如果您愿意,我的网络应用程序位于Google Code上,因此您可以下载源代码并查看我所做的事情。这里的URL到项目http://code.google.com/p/goomez/

1

所有这不是安全的,首先,它应该是:

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

在你的代码缓存会过期在检查和分配之间

0

Steve,参见best ways of using IndexSearcher。这有点过时了,但原理仍然是:使用IndexSearcher的单个实例,使用适当的线程安全代码(我不知道如何在.Net中执行)保护它,并在索引更新后使其失效。 我相信这就是杰西所建议的,我第二个想法。

0

而不是高速缓存indexSearcher,我现在缓存IndexReader。 如果IndexReader已经在缓存中,我们正在检查它是否是最新的。否则我打开它并将该实例传递给indexSearcher构造函数。

此逻辑/代码是否有意义优化搜索查询响应当多个请求正在触击Web服务器进行搜索?

感谢您的阅读。

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; 

     } 
相关问题