Объединение запроса числового диапазона с запросом термина в Lucene - PullRequest
12 голосов
/ 15 июля 2010

Я хотел бы объединить запрос числового диапазона с запросом термина в Lucene.Например, я хочу найти проиндексированные документы, которые содержат от 10 до 20 страниц и имеют заголовок «Hello World».

Кажется, невозможно использовать QueryParser для генерации этого запроса для меня;запрос диапазона, который генерирует QueryParser, выглядит как текстовый.

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

Спасибо

Ответы [ 4 ]

11 голосов
/ 15 июля 2010

Ну, похоже, я понял это сам. Вы можете использовать Query.combine () для запросов ИЛИ вместе. Я включил пример ниже.

String termQueryString = "title:\"hello world\"";
Query termQuery = parser.parse(termQueryString);

Query pageQueryRange = NumericRangeQuery.newIntRange("page_count", 10, 20, true, true);

Query query = termQuery.combine(new Query[]{termQuery, pageQueryRange});
5 голосов
/ 25 января 2012

Вы также можете создать пользовательский метод переопределения QueryParser protected Query getRangeQuery(...), который должен возвращать NumericRangeQuery экземпляр при обнаружении поля "page_count".

Примерно так ...

public class CustomQueryParser extends QueryParser {

    public CustomQueryParser(Version matchVersion, String f, Analyzer a) {
        super(matchVersion, f, a);
    }

    @Override
    protected Query getRangeQuery(final String field, final String part1, final String part2, final boolean inclusive) throws ParseException {

        if ("page_count".equals(field)) {
            return NumericRangeQuery.newIntRange(field, Integer.parseInt(part1), Integer.parseInt(part2), inclusive, inclusive);
        }

        // return default
        return super.getRangeQuery(field, part1, part2, inclusive);    
    }
}

Затем используйте CustomQueryParser при разборе текстовых запросов ..

Примерно так ...

...
final QueryParser parser = new CustomQueryParser(Version.LUCENE_35, "some_default_field", new StandardAnalyzer(Version.LUCENE_35));
final Query q = parser.parse("title:\"hello world\" AND page_count:[10 TO 20]");
...

Все это, конечно, предполагает, что NumericField(...).setIntValue(...) использовался, когда page_count значения были добавлены в документы

2 голосов
/ 23 августа 2014

Вы можете использовать BooleanQuery:

var combinedQuery = new BooleanQuery();
combinedQuery.Add(new TermQuery(new Term("title","hello world")),Occur.MUST);
combinedQuery.Add(NumericRangeQuery.newIntRange("page_count", 10, 20, true, true),Occur.MUST);
0 голосов
/ 15 июля 2010
RangeQuery amountQuery = new RangeQuery(lowerTerm, upperTerm, true);

Lucene рассматривает числа как слова, поэтому числа упорядочены в алфавитном порядке.

1
12
123
1234
etc.

При этом вы все равно можете использовать запрос диапазона, вам просто нужно быть более умным.

Чтобы правильно запрашивать числовые значения, вам нужно дополнить свои целые числа одинаковыми длинами (независимо от того, какое у вас максимальное поддерживаемое значение)

0001
0012
0123
1234

Очевидно, что это не работает для отрицательных значенийчисла (начиная с -2 <-1), и, надеюсь, вам не придется иметь с ними дело.Вот полезная статья для негативов, если вы их встретите: <a href="http://wiki.apache.org/lucene-java/SearchNumericalFields" rel="nofollow noreferrer">http://wiki.apache.org/lucene-java/SearchNumericalFields

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...