如何将Myblog1.0升级到Myblog1.5 解决Compass,Lucene高亮的问题
Sep 07

转载请注明:
作者:somebody(莫多)
出处:http://jdkcn.com/entry/the-better-revolution-about-the-compass-lucene-highlight.html

      前面两篇文章介绍了搜索高亮的实现,以及html代码问题的解决。《给Compass搜索添加高亮(highlight)》《解决Compass,Lucene高亮的问题

     其实对于很多html的内容,我们关心的其实只是html格式代码之外的文字内容。搜索出来也应该是其中的内容,前面的一个解决方法只是在搜索结果里面去处了高亮内容中的html格式代码,这样不会弄乱你的搜索结果页面。这几天仔细看了一下compass的文档和代码,其实我们可以彻底的解决这个问题。我们需要在索引的时候,转换一下,去掉html代码就可以了。
   
      compass为我们封装了很多ResourcePropertyConverter,我们可以转换日期,数字等。这里我们实现一个自己的HtmlPropertyConverter就可以达到我们的目的了。

import org.compass.core.converter.ConversionException;
import org.compass.core.converter.basic.AbstractBasicConverter;
import org.compass.core.mapping.ResourcePropertyMapping;

import com.jdkcn.util.MyblogUtil;

/**
 * @author <a href="mailto:rory.cn@gmail.com">somebody</a>
 * @since Sep 5, 2007 10:26:00 AM
 * @version $Id HtmlPropertyConverter.java$
 */
public class HtmlPropertyConverter extends AbstractBasicConverter {

    /* (non-Javadoc)
     * @see org.compass.core.converter.ResourcePropertyConverter#fromString(java.lang.String, org.compass.core.mapping.ResourcePropertyMapping)
     */
    public Object fromString(String str,
            ResourcePropertyMapping resourcePropertyMapping)
            throws ConversionException {
        return MyblogUtil.removeHTML(str);
    }
   
    /* (non-Javadoc)
     * @see org.compass.core.converter.basic.AbstractBasicConverter#toString(java.lang.Object, org.compass.core.mapping.ResourcePropertyMapping)
     */
    @Override
    public String toString(Object o,
            ResourcePropertyMapping resourcePropertyMapping) {
        if (o instanceof String) {
            String str = (String) o;
            str = MyblogUtil.removeHTML(str);
            return str;
        }
        return super.toString(o, resourcePropertyMapping);
    }
}


在fromString和toString方法里面去掉html代码就ok了。然后修改一下我们的compass配置,以及domain的compass映射文件。

    <bean id="compass" class="org.compass.spring.LocalCompassBean">
        <property name="resourceDirectoryLocations">
            <list>
                <value>classpath:com/jdkcn/compass</value>
            </list>
        </property>
        <property name="connection">
            <value>/lucene/indexes</value>
        </property>
        <property name="compassSettings">
            <props>
                <prop key="compass.transaction.factory">
                    org.compass.spring.transaction.SpringSyncTransactionFactory
                </prop>
                <prop key="compass.engine.highlighter.default.formatter.simple.pre">
                    <![CDATA[<span class="highlight">]]>
                </prop>
                <prop key="compass.engine.highlighter.default.formatter.simple.post">
                    <![CDATA[</span>]]>
                </prop>
            </props>
        </property>
        <property name="transactionManager">
            <ref bean="transactionManager" />
        </property>
        <property name="convertersByName">
            <map>
                <entry key="htmlPropertyConverter">
                    <bean class="com.jdkcn.compass.HtmlPropertyConverter"/>
                </entry>
            </map>
        </property>
    </bean>


配置里面多了一个convertersByName,注册我们自己的HtmlPropertyConverter。

<compass-core-mapping package="com.jdkcn.domain">
    <class name="Entry" alias="entry">
        <id name="id" />
        <property name="title">
            <meta-data>title</meta-data>
        </property>
        <property name="content">
            <meta-data converter="htmlPropertyConverter">content</meta-data>
        </property>
        <property name="name">
            <meta-data>name</meta-data>
        </property>
        <property name="entryStatus">
            <meta-data>entryStatus</meta-data>
        </property>
        <property name="type">
            <meta-data>type</meta-data>
        </property>
        <property name="postTime">
            <meta-data format="yyyy-MM-dd">postTime</meta-data>
        </property>
    </class>
</compass-core-mapping>


ok了。记得要重新生成一下你的索引哦。效果如本站搜索所示。。


Like others

24 Responses to “关于compass,lucene高亮的比较完美的解决方案”

  1. jeer Says:

    不错,正找这个呢。感谢。

  2. tudo Says:

    刚刚在自己的网站上用了lucene+compass,一起来与大家研究.我的网址www.bieyou.com 

  3. dhxyu Says:

    请问一下莫多同学,为什么我的只可以搜索英文,而不能搜索中文啊?没有结果出来,而且在搜索框内的字体变乱码了!!
    很急,期待您的回复,谢谢!!

  4. 莫多(somebody) Says:

    可以搜索中文的啊。
    http://www.jdkcn.com/search.html?query=%E9%AB%98%E4%BA%AE
    也正常的啊。

  5. dhxyu Says:

    不是啊,我是说我自己使用就不行,请问一下 是不是该注意哪些设置呢?
    能说说么 谢谢了! 是不是跟中文分词有关系啊?

  6. 莫多(somebody) Says:

    那是你的中文没有处理好吧。你debug的时候看一下传过去的是不是中文。这个不是compass的问题。

  7. dhxyu Says:

    还是不行,我页面的和数据库等都是UTF-8都是正常的,可就是搜索中文没结果和回显关键字时是乱码(在搜索框里是乱码)!!

  8. 莫多(somebody) Says:

    你debug的时候中文正确的传过去了?
    你在search之前把传过来的参数打印出来看一下。是不是正常的。

  9. dhxyu Says:

    能加QQ么?还有很多不懂的要请教您!!谢谢:54339729

  10. sailor Says:

    这种搜索会不会把Entry (entryStatus) 状态为无效的搜索出来呢?

  11. 莫多(somebody) Says:

    这个就看你怎么去过滤了。既然索引了entryStatus,你就可以进行筛选了啊。
    to:dhxyu 我一般不用qq。用gtalk 比较多。 rory.cn #  gmail  DOT com

  12. sailor Says:

    最近我也想搞自己的一个网站,为空间烦呀,请问莫多在哪买的jsp空间呀?

  13. 破坏子 Says:

    你那个HtmlPropertyConverter类有点轻微复杂,其实继承AbstractBasicConverter后直接实现doFromString方法就可以了,也就是return  MyblogUtil.removeHTML(arg0);就行了啊

  14. 莫多(somebody) Says:

    谢谢破坏子提示。
    你可以提交一下patch给我么?我可以添加到myblog的src中。
    tks

  15. wanggc_qq Says:

    按照您的方法(还没有封装CompassHit和CompassSearchResults)我的摘要在第一页的时候是能显示出高亮度的,但是以后的几页不仅不显示高亮度而且摘要都没有了.但是通过<c:out value="${hit.data.content}"/>是能得到摘要的.调试的时候highligtedText数组都是null,请问莫多这是怎么回事啊?请您指点一下.

    以下是cpm.xml片段

    <compass-core-mapping package="com.pubone.emarket.model">
      <class name="Opporunity" alias="opporunity">
      <id name="opportunityId" />
      <property name="subject">
       <meta-data>subject</meta-data>
      </property>
      
      <property name="epWebUrl">
       <meta-data>epWebUrl</meta-data>
      </property>
      
      <property name="content">
       <!-- <meta-data>${Opporunity.content}</meta-data> -->
       <meta-data converter="htmlPropertyConverter">content</meta-data>
      </property>
      ...   
      </class>
        
    </compass-core-mapping>

  16. 路凡 Says:

    想请问下
     <property name="content">
                <meta-data converter="htmlPropertyConverter">content</meta-data>
            </property>
    换成anotation方式怎么写

    <property name="resourceDirectoryLocations">
                <list>
                    <value>classpath:com/jdkcn/compass</value>
                </list>
            </property>

    我没有配置这个路径,因为是直接在domain里面进行注解写的。这一段是否要换成别的配置方式。

  17. 虚心学 Says:

    莫多,您好!
       这段时间一直在研究您的compass部分的代码,我用的的是SSH架构,参照资料写了一个compassSearchService,其他功能都得以实现,就是高亮部分有问题,参照您的Htmlconverter方法,cpm.xml文件配置converter,compass配置文件也注册了这个转换器,重新索引都不起作用,没办法,只好用您的老办法先替换高亮部分。再去掉Html,再把高亮换回去,这个办法还不是很完美,若fragment只取到一个“<"“>”而不是一对"<>"就麻烦了,我想请问为什么我的Htmlconverter不起作用,您写这个程序的时候碰到过这个问题吗?请指教!

  18. 莫多(somebody) Says:

    to:虚心学
    我想你可以打开compass的debug来看看你的htmlconverter有没有注册到
    org.compass.spring.LocalCompassBean 中。

    你把org.compass的log level设置成debug.

    怀疑你的配置有问题。原来的那种实现是有问题的。就你像你说的那样。
    所以才用htmlConverter来解决的。

  19. 虚心学 Says:

    谢谢莫多回复,现在我是这样解决的,发现若fragment只截取到一半标签,左边的一定是">",右边的一定是"<", 这样我就再对highlightText进行一次去除">"、"<"的处理,例:
       font:宋体,size=12pix">规范公务接待<span class
    我把">"左边的字符去除,再把"<"右边的去除,得到"规范公务接待",也达到了想要的效果,好象没有什么例外,那个注册的我再按您的方法调试一下,谢谢!

  20. cg Says:

    问下楼主,我出现不能搜索中文,搜索完了,中文关键字也是乱码,碰到过这种问题吗

  21. 浩渺 Says:

    莫多,我想问一下
    debug调试htmlconverte已经注册到compass中,而且Htmlconverter执行了,不过results.getHits()[i].getHighlightedText();结果还是没能去掉html标签

  22. 莫多(somebody) Says:

    to:浩渺 
    我想你应该从 results.getHits()[i].getHighlightedText(); 开始debug看看是哪里没有处理到。我这里用的compass的版本太低了。api应该有变化了。

  23. 浩渺 Says:

    To:莫多
    谢谢你的回复
    我的问题已经解决,我重写了AbstractBasicConverter的createProperty方法

  24. 张建良 Says:

    莫多 你好,想请教一下,你们的例子都是在控制台输出的  我想应用到项目中,但是放在页面中为什么没有结果呢,能不能举个应用到网页中的例子,是不是还需要配置文件什么的吗,谢谢了

Leave a Reply

Identifying Code