Hibernate Search 之 精确与 All Fields 搜索

在使用 Hibernate Search时,为了降低复杂性,通常都把所有的 @Field 加上

name = "ALL",然后在搜索的时候,只支持对 "ALL" 这个 Field 的搜索。这样的

好处当然是简单,不需要在搜索的时候去解析用户的输入,高亮的时候也不需要

去逐个解析搜索条件。

 

当然,有利必有弊,坏处就是不能精确的检索。例如,我只想找标题里面含有某个特殊

字符的,那么我的这种做法就没戏了。

 

解决方案是什么呢,其实也简单,还是 FieldBridge。我在 @Field 里面,不定义name,

也就是说,原来是title的field,现在还是title。只不过,我在Class上面增加了一个自己的

ClassBridge,在这个bridge里面,把所有标注为@Field的fields全部找出来,放在一个大

的字符串里面,把它命名为 "ALL"。然后在QueryParser里面,定义缺省的Field为 "ALL"。

 

当用户的搜索条件里面不包含field信息时,就直接在 "ALL"里面进行检索,当包含的时候呢,

又可以精确的定位。例如: title:abc def 就可以找到包含 def,并且 title 里面有 abc的内容。

 

接下来,上代码,在POJO里面这样写:

@Entity
@Indexed
@ClassBridge( impl = AllFieldSearchableClassBridge.class)
public class Person implements Serializable, Searchable {
...

 这个Bridge是这样实现的:

public class AllFieldSearchableClassBridge implements FieldBridge {

    @Override
    public void set(String name, Object value, Document doc, LuceneOptions luceneOptions) {
        try {
            Class<? extends Object> clz = value.getClass();
            Field[] fields = clz.getDeclaredFields();
            StringBuilder allStr = new StringBuilder();
            for ( Field field : fields) {
                org.hibernate.search.annotations.Field anno = field.getAnnotation( org.hibernate.search.annotations.Field.class);
                if ( anno == null) continue;
                Object fieldValue = ReflectUtils.getFieldValue( field, value);
                if ( fieldValue != null)
                    allStr.append( fieldValue).append( " ");
            }
            
            org.apache.lucene.document.Field field = new org.apache.lucene.document.Field("ALL", allStr.toString(), Store.YES, Index.ANALYZED);
            doc.add( field);
        } catch ( Exception e) {
            e.printStackTrace();
        }
    }
}



 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值