Логический запрос Люка Люсена

#c# #lucene #lucene.net #luke

#c# #lucene #lucene.net #luke

Вопрос:

В Luke следующее поисковое выражение возвращает 23 результата:

 docurl:www.siteurl.com  docfile:Tomatoes*
  

Если я передам это же выражение в свой C # Lucene.СЕТЕВОЕ приложение со следующей реализацией:

         IndexReader reader = IndexReader.Open(indexName);
        Searcher searcher = new IndexSearcher(reader);
        try
        {
            QueryParser parser = new QueryParser("docurl", new StandardAnalyzer());
            BooleanQuery bquery = new BooleanQuery();
            Query parsedQuery = parser.Parse(query);
            bquery.Add(parsedQuery, Lucene.Net.Search.BooleanClause.Occur.MUST);
            int _max = searcher.MaxDoc();
            BooleanQuery.SetMaxClauseCount(Int32.MaxValue);
            TopDocs hits = searcher.Search(parsedQuery, _max)
            ...
        }
  

Я получаю 0 результатов

Люк использует StandardAnalyzer, и вот как выглядит окно объяснения структуры: Структура запроса Luke

Должен ли я вручную создавать BooleanClause объекты для каждого поля, по которому я выполняю поиск, указывая Should для каждого из них, а затем добавлять их к BooleanQuery объекту с помощью .Add() ? Я думал, QueryParser это сделает за меня. Чего я не понимаю?

Редактировать: немного упрощая, docfile:Tomatoes* возвращает 23 документа в Luke, но 0 в моем приложении. По предложению Джина, я изменил с MUST на SHOULD :

             QueryParser parser = new QueryParser("docurl", new StandardAnalyzer());
            BooleanQuery bquery = new BooleanQuery();
            Query parsedQuery = parser.Parse(query);
            bquery.Add(parsedQuery, Lucene.Net.Search.BooleanClause.Occur.SHOULD);
            int _max = searcher.MaxDoc();
            BooleanQuery.SetMaxClauseCount(Int32.MaxValue);
            TopDocs hits = searcher.Search(parsedQuery, _max);
  

Обработанный запрос — это просто docfile:tomatoes*

Правка2:

Я думаю, что я, наконец, добрался до основной проблемы:

             QueryParser parser = new QueryParser("docurl", new StandardAnalyzer());
            Query parsedQuery = parser.Parse(query);
  

Во второй строке query есть "docfile:Tomatoes*" , но parsedQuery есть {docfile:tomatoes*} . Заметили разницу? В проанализированном запросе ‘t’ в нижнем регистре. Я никогда раньше этого не замечал. Если я изменю значение в IDE на ‘T’, вернутся 23 результата.

Я проверил, что StandardAnalyzer используется при индексации и чтении индекса. Как мне заставить queryParser сохранить регистр значения query ?

Правка3: Вау, как это расстраивает. Согласно документации, я могу выполнить это с помощью:

синтаксический анализатор.setLowercaseExpandedTerms(false);

Должны ли термины запросов с подстановочными знаками, префиксами, нечеткостью и диапазонами автоматически записываться в нижнем регистре или нет. Значение по умолчанию равно true.

Я не буду спорить, является ли это разумным значением по умолчанию или нет. Я полагаю, что SimpleAnalyzer следовало использовать для ввода в нижний регистр всего, что входит в индекс и выходит из него. Самое неприятное, что, по крайней мере, в версии, которую я использую, Luke по умолчанию использует другой способ! По крайней мере, я узнал немного больше о Lucene.

Комментарии:

1. Какое примерное значение переменной «запрос»? Кроме того, какова цель «bquery»?

2. Я бы предположил, что запрос — это строка, по которой он выполняет поиск: docurl:www.siteurl.com файл документа:Tomatoes*

Ответ №1:

Использование Occur.MUST эквивалентно использованию оператора со стандартным анализатором запросов. Таким образом, вычисляется ваш код docurl:www.siteurl.com docfile:Tomatoes* , а не выражение, которое вы ввели в Luke. Чтобы добиться такого поведения, попробуйте Occur.SHOULD при добавлении ваших предложений.

Комментарии:

1. Меняю выражение поиска в Luke на docurl:www.toledoblade.com docfile:Tomatoes* действительно возвращает 0 документов. Однако изменение моего предложения на SHOULD, похоже, не имеет обратного эффекта. bquery. Добавить (обработанный запрос, Lucene.Net.Search. Логическая причина. . ДОЛЖЕН);. количество просмотров по-прежнему равно 0.

2. попробуйте выполнить поиск по bquery' rather than on parsedQuery , and, as @ryan mentioned below, see what the class of parsedQuery` is. Пошаговое выполнение кода в отладчике часто бывает полезным.

Ответ №2:

QueryParser действительно примет запрос типа «docurl:www.siteurl.com docfile:Tomatoes*» и создайте из него соответствующий запрос (логический запрос, запрос диапазона и т.д.) В зависимости от заданного запроса (см. синтаксис запроса).

Вашим первым шагом должно быть подключение отладчика и проверка значения и типа parsedQuery .

Комментарии:

1. Обработанный запрос = docurl:www.toledoblade.com файл документа:tomatoes*. Итак, похоже, что анализатор запросов выполняет свою задачу.

2. Каков тип parsedQuery? Это должен быть логический запрос, состоящий из двух других запросов (соответствующий структуре запроса, которую вы видите в Luke). Два вопроса: 1 — какова цель bquery (похоже, он вообще не используется)? 2 . Получаете ли вы те же результаты, если используете другой метод поиска (одну из других перегрузок)?

3. Вы правы насчет bquery, я никогда не замечал, что он не используется. Я не писал этот код. Сейчас разбираюсь в этом.

4. Причина использования bquery заключается в том, чтобы указать более одного поискового запроса, и именно тогда вступит в игру различие «ДОЛЖЕН» / SHOULD.

5. bquery однако не используется в качестве аргумента для IndexSearcher .