使用HibernateSearch的桥接器功能

原因
前段时间,在开发网站时需要搜索功能。因为项目需求的原因,需要使用Lucene,不过在使用的过程中,遇到了一个特别的需求。当前我们的数据库,主要有三种数据,就是英繁简三种语言版本的数据,英文一般都有数据,但是繁简就不一定了,繁简体有可能会有空的数据出现,为了给用户更好的搜索体验,当用户输入简体数据,但数据库只有繁体数据时,需要实现就算数据库中简体没有数据,只要繁体有匹配的数据,都能显示结果给用户。

解决方案

由于我们在使用Lucene的同时,也引入了HibernateSearch。HibernateSearch为JPA提供了良好的支持,所以要解决以上的问题,我们可以借助它的桥接器功能。通过相关的文档,我们了解到HibernateSearch提供了一个叫FieldBridge的接口,利用这个接口,可以用来对字段进行自定义索引,从而解决繁简体的问题。


public class I18nFieldBridge
    implements FieldBridge, TwoWayFieldBridge
{
  /**
   * 得到指定的值.
   * @param name 字段名
   * @param document document对象
   * @return 字段的值
   */
  public Object get(String name, Document document)
  {
    final Field field = document.getField(name);

    return field.stringValue();
  }


  /**
   * 设置指定的值.
   * @param name 字段名
   * @param value 要设置的值
   * @param document document对象
   * @param luceneOptions Lucene的选项值
   */
  public void set(String name, Object value, Document document, LuceneOptions luceneOptions)
  {
    final String stringValue = (String) value;

    if (stringValue == null)
    {
      if (name.startsWith("sC"))
      {
        final String fieldName = name.substring(2, name.length());

        final Field field = document.getField("tC" + fieldName);

        if (field != null)
        {
          final String indexedString = field.stringValue();

          final String i18nIndexedString = CharSetUtil.convertCharSet(indexedString,
              CharSetUtil.TRADITIONAL_CHINESE_CHARSET_HK, WordSetType.DEFAULT);

          luceneOptions.addFieldToDocument(name, i18nIndexedString, document);
        }
      }
      else
      {
        if (name.startsWith("tC"))
        {
          final String fieldName = name.substring(2, name.length());

          final Field field = document.getField("sC" + fieldName);

          if (field != null)
          {
            final String indexedString = field.stringValue();

            final String i18nIndexedString = CharSetUtil.convertCharSet(indexedString,
                CharSetUtil.SIMPLIFIED_CHINESE_CHARSET, WordSetType.DEFAULT);

            luceneOptions.addFieldToDocument(name, i18nIndexedString, document);
          }
        }
        else
        {
          luceneOptions.addFieldToDocument(name, stringValue, document);
        }
      }
    }
    else
    {
      luceneOptions.addFieldToDocument(name, getAllLanguageMessage(name, document, stringValue), document);
    }
  }


  /**
   * 得到所有语言版本的信息。
   * @param name 字段名
   * @param document document对象
   * @return 语言版本的信息
   */
  private String getAllLanguageMessage(String name, Document document, String stringValue)
  {
    final StringBuffer buffer = new StringBuffer();
    buffer.append(stringValue);

    final String i18nTCIndexedString = CharSetUtil.convertCharSet(stringValue,
        CharSetUtil.TRADITIONAL_CHINESE_CHARSET_HK, WordSetType.DEFAULT);
    buffer.append(i18nTCIndexedString);

    final String i18nSCIndexedString = CharSetUtil.convertCharSet(stringValue, CharSetUtil.SIMPLIFIED_CHINESE_CHARSET,
        WordSetType.DEFAULT);
    buffer.append(i18nSCIndexedString);

    final String message = buffer.toString();

    return message;
  }


  /**
   * 转换为字符串.
   * @param value 要转换的对象
   * @return 转换后的字符串
   */
  public String objectToString(Object value)
  {
    final String originalValue = value.toString();

    return originalValue;
  }
}

代码不是太复杂,主要是实现当中的set方法,利用以前我们所写的i18n功能,实现繁简体的转换之后,再进行索引,例如如果检测到繁体语言版本没有数据,则将繁体数据进行i18n转换,反之亦然。

参考资料
http://www.hibernate.org/subprojects/search.html
网上有人翻译了HibernateSearch的技术文档,虽然翻译得不是特别好,但还过得去,可以作一个参考:
http://sin90lzc.iteye.com/category/160975



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值