0

我正在尝试搜索整数值。我已经用@Field 注释了参数,如下所示:

@Field(name = "confirmedCount", index = UN_TOKENIZED, store = Store.YES)
public int getConfirmedCount() {
   return stuff.size();
}

然后我用卢克执行范围搜索:

confirmedCount:[5 TO 100]

我回来的结果是空的。然后我尝试:

confirmedCount:[1 TO 2]

结果是:

name confirmedCount
b    1
a    1
d    19
c    2

所以我的问题是:为什么我会得到这个回复,我该如何解决?我使用休眠搜索 3.0.1.GA

4

3 回答 3

3

好的,我想我的问题的答案是 RTFM!该文件明确指出:

数字被转换成它们的字符串表示。请注意,Lucene 无法直接比较数字(即用于范围查询):它们必须被填充

所以我们需要实现一个类桥:

public class PaddedIntegerBridge implements StringBridge {

    private int PADDING = 5;

    public String objectToString(Object object) {
        String rawInteger = ( (Integer) object ).toString();
        if (rawInteger.length() > PADDING)
            throw new IllegalArgumentException( "Try to pad on a number too big" );
        StringBuilder paddedInteger = new StringBuilder( );
        for ( int padIndex = rawInteger.length() ; padIndex < PADDING ; padIndex++ ) {
            paddedInteger.append('0');
        }
        return paddedInteger.append( rawInteger ).toString();
    }
}

然后我们需要注释该字段以便它被索引:

@Field(name = "confirmedCount", index = UN_TOKENIZED, store = Store.YES, bridge = @FieldBridge(impl = PaddedIntegerBridge.class))
    public int getConfirmedCount() {
        return stuff.size();
    }

然后在我的搜索中,我只需要在创建查询时使用这个桥就可以了 =)

卢克的一些测试:

confirmedCount:[00005 TO 00100]

name confirmedCount
g    00006
d    00019
于 2012-03-20T15:06:18.157 回答
3

I couldn't find the documentation for 3.0.1 GA, but newer versions of Hibernate Search have a NumericField annotation.

于 2012-03-20T15:15:38.540 回答
0

如果您有字符串类型字段,但您想按数字排序并对其应用 rang 查询。您必须将字符串字段转换为数字字段,但在这里无需转换字段,您可以在字段上实现范围查询并像数字一样应用排序。

在字段上添加或创建自定义 @FieldBridge。

@Field(index=Index.YES,analyze=Analyze.NO,store=Store.YES) @FieldBridge(impl=StringToNumberBridge.class)

private String currentCtc;

假设您想搜索 currentCtc 字段为数字,但它是字符串字段。您可以在 currentCtc 字段上实现 Rang Query。

public class StringToNumberBridge implements TwoWayStringBridge {

    Logger logger=Logger.getLogger(StringToNumberBridge.class);
    public static String PADDING_PROPERTY = "padding";
    private int padding = 7; //default

    public String objectToString(Object object) {

        try {
            if(object!=null) 
            {
                String rawInteger = ((String) object).toString();
                String decimalPoint="";

                if(rawInteger.matches("\\d*\\.\\d+")) 
                {
                    decimalPoint=rawInteger.substring(rawInteger.indexOf("."));
                    rawInteger=rawInteger.substring(0,rawInteger.indexOf("."));
                    System.out.println(decimalPoint);
                    System.out.println(rawInteger);
                }
                if (rawInteger.length() > padding)
                    throw new IllegalArgumentException("Try to pad on a number too big");

                StringBuilder paddedInteger = new StringBuilder();
                for (int padIndex = rawInteger.length(); padIndex < padding; padIndex++) 
                {
                    paddedInteger.append('0');
                }
                return paddedInteger.append(rawInteger).append(decimalPoint).toString();
            }
            else {
                return "";
            }
            //return object.toString();
        } 
        catch (Exception e) {
            logger.error("NumberFormateException:::::::::::"+e);
            return null;
        }
    }

    public Object stringToObject(String stringValue) {
        return Double.valueOf(stringValue);
    }
}

您的索引字符串字段具有与数字相同的填充。对字符串字段应用 Rang Query,但它的工作方式类似于数字。

booleanQuery.must(qb.range().onField("currentCtc").below(25000).createQuery());

将字符串字段排序为数字

SortField field = new SortField("currentCtc".trim(), SortField.DOUBLE,true);

于 2016-08-01T11:28:40.617 回答