Проблема при использовании одного и того же экземпляра indexSearcher для нескольких запросов - PullRequest
2 голосов
/ 22 мая 2009

Я использую Lucene API в веб-приложении .net. Я хочу использовать один и тот же экземпляр Indexsearcher для всех запросов. Поэтому я храню экземпляр indexsearcher в кэше http.

вот мой код для того же:

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

Когда я выполняю приведенную ниже инструкцию, я получаю ошибку во время выполнения: «Ссылка на объект не установлена ​​для экземпляра объекта».

Хиты хиты = поисковик. Поиск (myQuery);

Что мне здесь не хватает?

Спасибо за чтение!

Ответы [ 7 ]

4 голосов
/ 15 июня 2009

Попробуйте что-то вроде следующего:

protected static IndexSearcher searcher = null;
...

if (searcher == null)
{
    searcher = new IndexSearcher(jobIndexFolderPath);
}
1 голос
/ 16 июня 2009

Прежде всего это вообще не безопасно, оно должно быть:

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

В вашем коде кеш может истечь между проверкой и назначением

1 голос
/ 15 июня 2009

У меня также есть веб-приложение, которое использует API Lucene для запросов (мое веб-приложение не записывает в индекс), и я создаю новый экземпляр поисковика для каждого запроса. Это может быть не очень " исполнитель ", но у меня никогда не было такой проблемы.

Если хотите, мое веб-приложение работает на Google Code, поэтому вы можете загрузить исходный код и посмотреть, что я сделал. Вот ссылка на проект http://code.google.com/p/goomez/

0 голосов
/ 18 июня 2009

Вместо кэширования indexSearcher, теперь я кеширую IndexReader. Если IndexReader уже находится в кэше, я проверяю его актуальность. В противном случае я открываю его и передаю этот экземпляр конструктору indexSearcher.

Имеет ли смысл эта логика / код по сравнению с оптимизированным ответом на поисковый запрос, если несколько запросов попадают на веб-сервер для поиска?

Спасибо за чтение.

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 голосов
/ 16 июня 2009

Стив, см. лучшие способы использования IndexSearcher . Это немного устарело, но принцип остается: используйте один экземпляр IndexSearcher, защитите его, используя правильный потокобезопасный код (который я не знаю, как сделать в .Net), и сделайте его недействительным после обновления индекса. Я полагаю, что это то, что предложил Джесси, и я поддерживаю эту идею.

0 голосов
/ 15 июня 2009

Мой быстрый ответ ...

Вам не нужно использовать один и тот же объект поиска индекса для всех запросов, на самом деле я бы рекомендовал против этого. Вам нужно только убедиться, что только один поток обновляет индекс.

Если вы действительно хотите один, как насчет статической переменной-члена в приложении, которая инициализируется один раз и используется всеми?

Длинный ответ ... Я попытаюсь найти свой код и увижу, как именно я справился с проблемой

0 голосов
/ 12 июня 2009

Две вещи:

  1. Если вы используете .Net 2.0 и не использовали SP1, это может помочь.
  2. Посмотрите на проблему у этого человека.

Обе записи относятся к объектам в кэше, срок действия которых истекает слишком рано - почти сразу в обоих случаях. Это может также осложняться тем фактом, что объекты в кеше не являются потокобезопасными.

Если вам нужен один IndexSearcher, почему бы не предоставить его веб-приложению в качестве службы?

...