2009-05-22 53 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; 

     } 
相關問題