2012-03-20 119 views
0

我正试图执行一个整数值的搜索。 我已经标注了@Field帕拉姆这样:如何在hibernate搜索中实现对int值的搜索?

@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

回答

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 
3

我无法找到3.0.1 GA的文件,但新版本的Hibernate搜索有NumericField annotation

+0

这就是我会使用,但NumericField没有出台,直到3.3 http://docs.jboss.org/hibernate/ search/3.2/api/org/hibernate/search/annotations/http://docs.jboss.org/hibernate/search/3.3/api/org/hibernate/search/annotations/ =) – jakob 2012-03-21 09:59:18

+0

然后你可能有兴趣升级因为NumericField为范围查询提供了更好的性能http://lucene.apache.org/core/old_versioned_docs/versions/3_5_0/ap我/所有/ org/apache/lucene/search/NumericRangeQuery.html – jpountz 2012-03-21 10:03:31

+0

是的,你是对的。我最终会这样做。谢谢! – jakob 2012-03-22 13:32:50

0

如果你有字符串类型的字段,但你想排序为数字明智的,并应用范围查询。你必须将字符串字段转换为数字字段,但是在这里没有转换字段,你可以在字段上实现响应查询,并像数字一样应用排序。

在字段中添加或创建自定义@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); 
    } 
} 

你有索引字符串字段填充相同的数字。 在String字段上应用Rang查询,但它像数字一样工作。

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

适用于字符串字段排序为数字

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