#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, и вот как выглядит окно объяснения структуры:
Должен ли я вручную создавать 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
.