Lucene查询范围

时间:2015-01-04 13:53:22

标签: java lucene

我将包含titlecost的某些项目编入索引作为字段。成本是双倍价值。 我准备了一个查询,例如:

(title:item~0.8) AND (cost:[0.0 TO 200.0])

解析后,query.toString()看起来像这样:

+title:item~0 +cost:[0.0 TO 200.0]

根据返回的结果,很明显不会考虑cost 我确信cost已编入索引,因为我可以检索它。 索引代码:

public void index(Set<Item> items) throws IOException {
    String path = "D:\\lucenedata\\myproj";
    Directory fsDir = FSDirectory.open(new File(path));
    StandardAnalyzer analyzer = new StandardAnalyzer();
    IndexWriterConfig iwConf = new IndexWriterConfig(Version.LUCENE_4_10_3, analyzer);
    iwConf.setOpenMode(IndexWriterConfig.OpenMode.CREATE);
    IndexWriter indexWriter = new IndexWriter(fsDir, iwConf);
    for (Item item : items) {
        Document d = new Document();
        if (item.getCost() != null) {
            d.add(new DoubleField("cost", item.getCost().doubleValue(), Store.YES));
        }
        d.add(new TextField("title", item.getTitle(), Store.YES));
        indexWriter.addDocument(d);
    }
    indexWriter.commit();
    indexWriter.close();
    System.out.println("Indexed " + items.size() + " items");
}

2 个答案:

答案 0 :(得分:2)

我最终继承了QueryParser,然后在遇到NumericRange时创建cost。效果很好。

public class WebSearchQueryParser extends QueryParser {

    public WebSearchQueryParser(String f, Analyzer a) {
        super(f, a);
    }

    protected Query getRangeQuery(final String field, final String min, final String max,
            final boolean startInclusive, final boolean endInclusive) throws ParseException {
        if ("cost".equals(field)) {
            return NumericRangeQuery.newDoubleRange(field, Double.parseDouble(min), Double.parseDouble(max),
                    startInclusive, endInclusive);
        }
        return super.getRangeQuery(field, min, max, startInclusive, endInclusive);
    }
}

然后初始化:

QueryParser queryParser = new WebSearchQueryParser("title", new StandardAnalyzer());

并解析我的查询(title:item~0.8) AND (cost:[0.0 TO 200.0])

答案 1 :(得分:1)

QueryParser不会生成数值范围查询。因此,您在按字典顺序搜索成本在0.0到200.0之间的值,而不是数字。此外,数字字段将转换为索引中的前缀编码形式,因此您的结果将非常难以预测。

最好通过查询API使用NumericRangeQuery而不是QueryParser生成数值范围,然后使用BooleanQuery将它们与您的已解析查询相结合。类似的东西:

Query parsedQuery = parser.parse(title:item~0.8);
Query costQuery = NumericRangeQuery.newDoubleRange("cost", 0.00, 200.0, true, true);
BooleanQuery finalQuery = new BooleanQuery();
finalQuery.add(new BooleanClause(parsedQuery, BooleanClause.Occur.MUST));
finalQuery.add(new BooleanClause(costQuery, BooleanClause.Occur.MUST));