在多个请求中使用indexSearcher的相同实例时出现问题

时间:2022-04-21 03:09:38

Am using Lucene API in a .net web application. I want to use the same instance of Indexsearcher for all the requests.Hence am storing indexsearcher instance in http cache.

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

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 :"Object reference not set to an instance of an object."

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

Hits hits = searcher.Search(myQuery);

Hits hits = searcher.Search(myQuery);

What am i missing here?

我在这里缺少什么?

Thanks for reading!

谢谢阅读!

7 个解决方案

#1


Try something like the following:

尝试以下内容:

protected static IndexSearcher searcher = null;
...

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

#2


I also have a web application that uses the Lucene API to query (my web app does not writes on the index) and I create a new instance of the searcher for every request. It might not be very "performant" but I never had that kind of problem.

我还有一个使用Lucene API进行查询的Web应用程序(我的Web应用程序没有在索引上写入),我为每个请求创建了一个新的搜索器实例。它可能不是很“高效”,但我从未遇到过这种问题。

If you'd like, my web app is on Google Code so you can download the source code and take a look at what I did. Here's the url to the project http://code.google.com/p/goomez/

如果您愿意,我的网络应用程序位于Google Code上,您可以下载源代码并查看我的操作。这是该项目的网址http://code.google.com/p/goomez/

#3


First of all it's not safe at all, it should be:

首先,它根本不安全,它应该是:

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

In your code cache can expire between check and assignment

在您的代码中,缓存可以在检查和分配之间到期

#4


Two things:

  1. If you're using .Net 2.0 and have not applied SP1, this may help.
  2. 如果您使用的是.Net 2.0并且尚未应用SP1,则可能会有所帮助。

  3. Look at the problem this person was having.
  4. 看看这个人遇到的问题。

Both entries refer to objects in the cache being expired too soon - almost immediately in both cases. Things might also be complicated by the fact that objects in the cache are not thread safe.

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

If you have to have a single IndexSearcher, why not provide it to the web app as a service?

如果您必须拥有一个IndexSearcher,为什么不将其作为服务提供给Web应用程序?

#5


My quick answer is...

我的快速回答是......

You don't really need to use the same index searcher object for all request, in fact i would recommend against it. You only need to make sure there is only one thread updating the index.

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

If you really want one, how about a static member variable in the application that is initialized once and used by all?

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

The long answer is... I will try and find my code and see exactly how I handled the problem

答案很长......我会尝试找到我的代码,看看我是如何处理问题的

#6


Steve, see best ways of using IndexSearcher. This is a bit dated, but the principle remains: Use a single instance of IndexSearcher, guard it using the proper thread safe code (which I do not know how to do in .Net), and invalidate it once the index is updated. I believe this is what Jesse has suggested, and I second this idea.

史蒂夫,看看使用IndexSearcher的最佳方法。这有点过时,但原则仍然是:使用IndexSearcher的单个实例,使用正确的线程安全代码(我不知道如何在.Net中)保护它,并在索引更新后使其无效。我相信这就是杰西的建议,我是第二个想法。

#7


Instead of caching indexSearcher, am now caching IndexReader. If IndexReader is already in cache, am making a check if it is up to date.Otherwise am opening it and passing that instance to indexSearcher constructor.

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

Does this logic/code make sense wrt optimized search query response incase multiple requests are hitting the web server for search?

这个逻辑/代码是否有意义,优化搜索查询响应,因为多个请求正在访问Web服务器进行搜索?

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;

        }

#1


Try something like the following:

尝试以下内容:

protected static IndexSearcher searcher = null;
...

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

#2


I also have a web application that uses the Lucene API to query (my web app does not writes on the index) and I create a new instance of the searcher for every request. It might not be very "performant" but I never had that kind of problem.

我还有一个使用Lucene API进行查询的Web应用程序(我的Web应用程序没有在索引上写入),我为每个请求创建了一个新的搜索器实例。它可能不是很“高效”,但我从未遇到过这种问题。

If you'd like, my web app is on Google Code so you can download the source code and take a look at what I did. Here's the url to the project http://code.google.com/p/goomez/

如果您愿意,我的网络应用程序位于Google Code上,您可以下载源代码并查看我的操作。这是该项目的网址http://code.google.com/p/goomez/

#3


First of all it's not safe at all, it should be:

首先,它根本不安全,它应该是:

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

In your code cache can expire between check and assignment

在您的代码中,缓存可以在检查和分配之间到期

#4


Two things:

  1. If you're using .Net 2.0 and have not applied SP1, this may help.
  2. 如果您使用的是.Net 2.0并且尚未应用SP1,则可能会有所帮助。

  3. Look at the problem this person was having.
  4. 看看这个人遇到的问题。

Both entries refer to objects in the cache being expired too soon - almost immediately in both cases. Things might also be complicated by the fact that objects in the cache are not thread safe.

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

If you have to have a single IndexSearcher, why not provide it to the web app as a service?

如果您必须拥有一个IndexSearcher,为什么不将其作为服务提供给Web应用程序?

#5


My quick answer is...

我的快速回答是......

You don't really need to use the same index searcher object for all request, in fact i would recommend against it. You only need to make sure there is only one thread updating the index.

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

If you really want one, how about a static member variable in the application that is initialized once and used by all?

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

The long answer is... I will try and find my code and see exactly how I handled the problem

答案很长......我会尝试找到我的代码,看看我是如何处理问题的

#6


Steve, see best ways of using IndexSearcher. This is a bit dated, but the principle remains: Use a single instance of IndexSearcher, guard it using the proper thread safe code (which I do not know how to do in .Net), and invalidate it once the index is updated. I believe this is what Jesse has suggested, and I second this idea.

史蒂夫,看看使用IndexSearcher的最佳方法。这有点过时,但原则仍然是:使用IndexSearcher的单个实例,使用正确的线程安全代码(我不知道如何在.Net中)保护它,并在索引更新后使其无效。我相信这就是杰西的建议,我是第二个想法。

#7


Instead of caching indexSearcher, am now caching IndexReader. If IndexReader is already in cache, am making a check if it is up to date.Otherwise am opening it and passing that instance to indexSearcher constructor.

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

Does this logic/code make sense wrt optimized search query response incase multiple requests are hitting the web server for search?

这个逻辑/代码是否有意义,优化搜索查询响应,因为多个请求正在访问Web服务器进行搜索?

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;

        }