Luke Lucene BooleanQuery - PullRequest
       36

Luke Lucene BooleanQuery

4 голосов
/ 13 мая 2011

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

docurl:www.siteurl.com  docfile:Tomatoes*

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

        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 Query Structure

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

Редактировать: Упрощая немного, docfile:Tomatoes* возвращает 23 документа в Люке, но 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);

parsedQuery просто docfile:tomatoes*

Edit2:

Мне кажется, я наконец-то дошел до проблемы с корнем:

            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?

Edit3: Ух, как расстраивает.В соответствии с документацией , я могу выполнить это с помощью:

parser.setLowercaseExpandedTerms (false);

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

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

Ответы [ 2 ]

3 голосов
/ 15 мая 2011

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

1 голос
/ 14 мая 2011

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

Первым делом необходимо подключить отладчик и проверить значение и тип parsedQuery.

...