带有整数字段的RangeQuery没有给出预期的结果

时间:2015-08-01 05:29:28

标签: hibernate-search hibernate-entitymanager

以下是实体

中定义的两个字段
@Column(name = "min_price")
@Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO)
@NumericField
@FieldBridge(impl = IntegerBridge.class)
private Integer minPrice;

@Column(name = "max_price")
@Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO)
@NumericField
@FieldBridge(impl = IntegerBridge.class)
private Integer maxPrice;

使用entityManager生成全文查询,如下所示

BooleanJunction priceBooleanJunction = queryBuilder.bool();
    //Building range query for price
    if (minPrice != null) {
        Query rangeQueryMinPrice = queryBuilder.range().onField("minPrice").above(minPrice).createQuery();
        priceBooleanJunction.must(rangeQueryMinPrice);
    }
    if (maxPrice != null) {
        Query rangeQueryMaxPrice = queryBuilder.range().onField("maxPrice").below(maxPrice).createQuery();
        priceBooleanJunction.must(rangeQueryMaxPrice);
    }

    BooleanJunction combainedBoolean = queryBuilder.bool();

    if (!priceBooleanJunction.isEmpty()) {
        combainedBoolean.must(priceBooleanJunction.createQuery());
    }

    Query searchQuery = combainedBoolean.createQuery();
    FullTextQuery query = fullTextEntityManager.createFullTextQuery(searchQuery, ServiceProvider.class);

    LOGGER.info(query.toString());

最后一个日志为40,90输入打印以下内容

FullTextQueryImpl(+minPrice:[40 TO *] +maxPrice:[* TO 90])

数据库包含值(min,max)为(50,80)和(80,90)

仍然是空的。

2 个答案:

答案 0 :(得分:2)

您正在使用的IntegerBridge使用字符串编码,但您希望确保在使用范围查询时使用数字编码。您的案例中无需添加@FieldBridge

此外,行为还取决于您使用的是哪个版本的搜索。在版本5之前,您需要添加@NumericField,但从Hibernate Search 5开始,数字将自动按数字编制索引,在这种情况下,@FieldBridge以及@NumericField不再需要了。

答案 1 :(得分:0)

您的实体是否需要minPrice和maxPrice?你的文章有一个minPrice和一个maxPrice?如果您进行全文搜索,则不需要它。

尝试使用IntegerNumericFieldBridge代替IntegerBridge,如下所示:

@Field @FieldBridge(impl=IntegerNumericFieldBridge.class)
private Integer price;

之后使用NumericRangeQuery代替hibernate搜索范围查询。像这样:

NumericRangeQuery<Integer> integerQuery = NumericRangeQuery.newIntRange("price", minRangePrice, maxRangePrice,  true, true);

如果你有很多查询,你将无法使用hibernate搜索bool()方法,而是使用lucene“BooleanQuery”。像这样:

BooleanQuery luceneBooleanQuery = new BooleanQuery();
luceneBooleanQuery.add(integerQuery, BooleanClause.Occur.MUST); // MUST or SHOULD
luceneBooleanQuery.add(anotherQuery, BooleanClause.Occur.MUST); 

你可以混合像NumericRangeQuery这样的lucene查询和hibernate搜索的QueryBuilder构建的查询。

然后,你可以这样做:

FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(luceneBooleanQuery, YourClass.class);

它应该工作。