转载请注明:
作者: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

Friday, October 05, 2007, 08:34:22 AM (CST)
不错,正找这个呢。感谢。
Friday, January 18, 2008, 11:12:35 AM (CST)
刚刚在自己的网站上用了lucene+compass,一起来与大家研究.我的网址www.bieyou.com
Tuesday, February 19, 2008, 01:46:07 AM (CST)
请问一下莫多同学,为什么我的只可以搜索英文,而不能搜索中文啊?没有结果出来,而且在搜索框内的字体变乱码了!!
很急,期待您的回复,谢谢!!
Tuesday, February 19, 2008, 09:20:28 AM (CST)
可以搜索中文的啊。
http://www.jdkcn.com/search.html?query=%E9%AB%98%E4%BA%AE
也正常的啊。
Tuesday, February 19, 2008, 09:35:51 AM (CST)
不是啊,我是说我自己使用就不行,请问一下 是不是该注意哪些设置呢?
能说说么 谢谢了! 是不是跟中文分词有关系啊?
Tuesday, February 19, 2008, 09:39:25 AM (CST)
那是你的中文没有处理好吧。你debug的时候看一下传过去的是不是中文。这个不是compass的问题。
Wednesday, February 20, 2008, 04:12:22 PM (CST)
还是不行,我页面的和数据库等都是UTF-8都是正常的,可就是搜索中文没结果和回显关键字时是乱码(在搜索框里是乱码)!!
Wednesday, February 20, 2008, 04:26:23 PM (CST)
你debug的时候中文正确的传过去了?
你在search之前把传过来的参数打印出来看一下。是不是正常的。
Wednesday, February 20, 2008, 04:28:51 PM (CST)
能加QQ么?还有很多不懂的要请教您!!谢谢:54339729
Thursday, March 13, 2008, 05:31:37 PM (CST)
这种搜索会不会把Entry (entryStatus) 状态为无效的搜索出来呢?
Thursday, March 13, 2008, 06:14:32 PM (CST)
这个就看你怎么去过滤了。既然索引了entryStatus,你就可以进行筛选了啊。
to:dhxyu 我一般不用qq。用gtalk 比较多。 rory.cn # gmail DOT com
Wednesday, April 09, 2008, 10:43:20 AM (CST)
最近我也想搞自己的一个网站,为空间烦呀,请问莫多在哪买的jsp空间呀?
Saturday, May 10, 2008, 03:42:18 PM (CST)
你那个HtmlPropertyConverter类有点轻微复杂,其实继承AbstractBasicConverter后直接实现doFromString方法就可以了,也就是return MyblogUtil.removeHTML(arg0);就行了啊
Tuesday, May 13, 2008, 01:34:15 PM (CST)
谢谢破坏子提示。
你可以提交一下patch给我么?我可以添加到myblog的src中。
tks
Thursday, May 29, 2008, 05:54:04 PM (CST)
按照您的方法(还没有封装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>
Wednesday, July 09, 2008, 06:50:40 PM (CST)
想请问下
<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里面进行注解写的。这一段是否要换成别的配置方式。
Tuesday, July 29, 2008, 12:16:52 AM (CST)
莫多,您好!
这段时间一直在研究您的compass部分的代码,我用的的是SSH架构,参照资料写了一个compassSearchService,其他功能都得以实现,就是高亮部分有问题,参照您的Htmlconverter方法,cpm.xml文件配置converter,compass配置文件也注册了这个转换器,重新索引都不起作用,没办法,只好用您的老办法先替换高亮部分。再去掉Html,再把高亮换回去,这个办法还不是很完美,若fragment只取到一个“<"“>”而不是一对"<>"就麻烦了,我想请问为什么我的Htmlconverter不起作用,您写这个程序的时候碰到过这个问题吗?请指教!
Thursday, July 31, 2008, 01:40:59 PM (CST)
to:虚心学
我想你可以打开compass的debug来看看你的htmlconverter有没有注册到
org.compass.spring.LocalCompassBean 中。
你把org.compass的log level设置成debug.
怀疑你的配置有问题。原来的那种实现是有问题的。就你像你说的那样。
所以才用htmlConverter来解决的。
Saturday, August 02, 2008, 11:10:00 AM (CST)
谢谢莫多回复,现在我是这样解决的,发现若fragment只截取到一半标签,左边的一定是">",右边的一定是"<", 这样我就再对highlightText进行一次去除">"、"<"的处理,例:
font:宋体,size=12pix">规范公务接待<span class
我把">"左边的字符去除,再把"<"右边的去除,得到"规范公务接待",也达到了想要的效果,好象没有什么例外,那个注册的我再按您的方法调试一下,谢谢!
Tuesday, June 23, 2009, 04:37:21 AM (CST)
问下楼主,我出现不能搜索中文,搜索完了,中文关键字也是乱码,碰到过这种问题吗
Monday, April 12, 2010, 06:26:51 PM (CST)
莫多,我想问一下
debug调试htmlconverte已经注册到compass中,而且Htmlconverter执行了,不过results.getHits()[i].getHighlightedText();结果还是没能去掉html标签
Wednesday, April 14, 2010, 10:53:16 AM (CST)
to:浩渺
我想你应该从 results.getHits()[i].getHighlightedText(); 开始debug看看是哪里没有处理到。我这里用的compass的版本太低了。api应该有变化了。
Wednesday, April 14, 2010, 11:47:20 AM (CST)
To:莫多
谢谢你的回复
我的问题已经解决,我重写了AbstractBasicConverter的createProperty方法
Friday, April 30, 2010, 03:31:20 PM (CST)
莫多 你好,想请教一下,你们的例子都是在控制台输出的 我想应用到项目中,但是放在页面中为什么没有结果呢,能不能举个应用到网页中的例子,是不是还需要配置文件什么的吗,谢谢了