Java 带范围的Lucene查询

Java 带范围的Lucene查询,java,lucene,Java,Lucene,我正在索引一些项目,其中包括标题和成本字段。成本是双重价值。 我正在准备一个查询,例如: (title:item~0.8) AND (cost:[0.0 TO 200.0]) 解析后,query.toString()如下所示: +title:item~0 +cost:[0.0 TO 200.0] 从返回的结果来看,显然没有考虑成本。 我确信成本已编入索引,因为我可以检索它。 索引代码: public void index(Set<Item> items) throws IOExc

我正在索引一些项目,其中包括
标题
成本
字段。成本是双重价值。 我正在准备一个查询,例如:

(title:item~0.8) AND (cost:[0.0 TO 200.0])
解析后,
query.toString()
如下所示:

+title:item~0 +cost:[0.0 TO 200.0]
从返回的结果来看,显然没有考虑成本。 我确信
成本
已编入索引,因为我可以检索它。 索引代码:

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");
}
公共无效索引(集合项)引发IOException{
String path=“D:\\lucenedata\\myproj”;
目录fsDir=FSDirectory.open(新文件(路径));
StandardAnalyzer=新的StandardAnalyzer();
IndexWriterConfig iwConf=新的IndexWriterConfig(Version.LUCENE_4_10_3,analyzer);
iwConf.setOpenMode(IndexWriterConfig.OpenMode.CREATE);
IndexWriter IndexWriter=新的IndexWriter(fsDir,iwConf);
用于(项目:项目){
文件d=新文件();
if(item.getCost()!=null){
d、 添加(新的双字段(“成本”,item.getCost().doubleValue(),Store.YES));
}
d、 添加(新文本字段(“title”,item.getTitle(),Store.YES));
indexWriter.addDocument(d);
}
indexWriter.commit();
indexWriter.close();
System.out.println(“索引”+项.size()+项”);
}

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

最好通过查询API生成数值范围,使用,而不是QueryParser,并使用。比如:

Query parsedQuery=parser.parse(标题:item~0.8);
Query costQuery=numerirangequery.newDoubleRange(“成本”,0.00200.0,真,真);
BooleanQuery finalQuery=新建BooleanQuery();
add(newbooleanclause(parsedQuery,BooleanClause.occure.MUST));
add(newbooleanclause(costQuery,BooleanClause.occure.MUST));

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

最好通过查询API生成数值范围,使用,而不是QueryParser,并使用。比如:

Query parsedQuery=parser.parse(标题:item~0.8);
Query costQuery=numerirangequery.newDoubleRange(“成本”,0.00200.0,真,真);
BooleanQuery finalQuery=新建BooleanQuery();
add(newbooleanclause(parsedQuery,BooleanClause.occure.MUST));
add(newbooleanclause(costQuery,BooleanClause.occure.MUST));

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

最好通过查询API生成数值范围,使用,而不是QueryParser,并使用。比如:

Query parsedQuery=parser.parse(标题:item~0.8);
Query costQuery=numerirangequery.newDoubleRange(“成本”,0.00200.0,真,真);
BooleanQuery finalQuery=新建BooleanQuery();
add(newbooleanclause(parsedQuery,BooleanClause.occure.MUST));
add(newbooleanclause(costQuery,BooleanClause.occure.MUST));

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

最好通过查询API生成数值范围,使用,而不是QueryParser,并使用。比如:

Query parsedQuery=parser.parse(标题:item~0.8);
Query costQuery=numerirangequery.newDoubleRange(“成本”,0.00200.0,真,真);
BooleanQuery finalQuery=新建BooleanQuery();
add(newbooleanclause(parsedQuery,BooleanClause.occure.MUST));
add(newbooleanclause(costQuery,BooleanClause.occure.MUST));

我最终将
QueryParser
子类化,然后在遇到
成本时创建一个
numeriRange
。它工作得很好

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

然后像以前一样解析我的查询
(标题:item~0.8)和(cost:[0.0到200.0])

我最终对
QueryParser
进行子类化,然后在遇到
cost
时创建一个
numeriRange
。它工作得很好

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

然后像以前一样解析我的查询
(标题:item~0.8)和(cost:[0.0到200.0])

我最终对
QueryParser
进行子类化,然后在遇到
cost
时创建一个
numeriRange
。它工作得很好

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

然后像以前一样解析我的查询
(标题:item~0.8)和(cost:[0.0到200.0])

我最终对
QueryParser
进行子类化,然后在遇到
cost
时创建一个
numeriRange
。它工作得很好

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

并像以前一样解析我的查询(标题:item~0.8)和(cost:[0.0到200.0])

谢谢您的解释。我还发现,以这种方式组合是行不通的。相反,我编写了一个定制的QueryParser,如果遇到“cost”列,它将创建新的NumericRange。我也会发布我的解决方案。谢谢你的解释。我还发现了combi