在Lucene中将数字范围查询与术语查询相结合

时间:2010-07-14 23:06:40

标签: java lucene

我想在Lucene中将数值范围查询与术语查询相结合。例如,我想搜索已编入索引的文档,其中包含10到20页,标题为“Hello World”。

似乎不可能使用QueryParser为我生成此查询; QueryParser生成的范围查询似乎是文本查询。

我绝对会欣赏如何将数值范围查询与术语查询相结合的示例。我也会公开选择我的索引。

由于

4 个答案:

答案 0 :(得分:11)

好吧,看起来我自己想出了这个。您可以将Query.combine()一起用于OR查询。我在下面列举了一个例子。

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});

答案 1 :(得分:5)

您还可以创建自定义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 :(得分:2)

您可以使用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);

答案 3 :(得分:0)

RangeQuery amountQuery = new RangeQuery(lowerTerm, upperTerm, true);

Lucene将数字视为单词,因此数字按字母顺序排列。

1
12
123
1234
etc.

话虽这么说,你仍然可以使用范围查询,你只需要更聪明一点。

为了正确查询数值,您需要填充整数以使其长度相同(无论您支持的最大值是多少)

0001
0012
0123
1234

显然,这对负数不起作用(因为-2 <-1),希望你不必处理它们。如果您遇到负面消息,这里有一篇有用的文章: http://wiki.apache.org/lucene-java/SearchNumericalFields