【问题标题】:RangeQuery with Integer fields not giving expected result具有整数字段的 RangeQuery 未给出预期结果
【发布时间】:2015-08-01 05:29:28
【问题描述】:

以下是实体中定义的两个字段

@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)

结果还是空的。

【问题讨论】:

    标签: hibernate-search hibernate-entitymanager


    【解决方案1】:

    您使用的IntegerBridge 正在使用字符串编码,但您要确保在使用范围查询时使用数字编码。在您的情况下无需添加@FieldBridge

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

    【讨论】:

      【解决方案2】:

      您的实体是否需要 minPrice 和 maxPrice ?您的文章有 minPrice 和 maxPrice 吗?如果您这样做是为了全文搜索,则不需要它。

      尝试像这样使用IntegerNumericFieldBridge 而不是IntegerBridge

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

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

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

      如果您有很多查询,您将无法使用 hibernate search 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 search的QueryBuilder构建的查询。

      那么,你可以这样做:

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

      它应该工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-07
        • 1970-01-01
        • 2019-12-28
        • 2021-09-15
        • 2016-01-30
        • 2021-04-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多