<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>出家如初，成佛有余&#187; lucene</title>
	<atom:link href="http://www.yeeach.com/tag/lucene/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.yeeach.com</link>
	<description>专注电子商务领域，关注无线互联网，关注新媒体；Yeeach.com用于记录我技术生涯的点滴</description>
	<lastBuildDate>Sun, 25 Jul 2010 10:30:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>企业级搜索引擎Solr使用入门指南</title>
		<link>http://www.yeeach.com/2008/07/29/%e4%bc%81%e4%b8%9a%e7%ba%a7%e6%90%9c%e7%b4%a2%e5%bc%95%e6%93%8esolr%e4%bd%bf%e7%94%a8%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/</link>
		<comments>http://www.yeeach.com/2008/07/29/%e4%bc%81%e4%b8%9a%e7%ba%a7%e6%90%9c%e7%b4%a2%e5%bc%95%e6%93%8esolr%e4%bd%bf%e7%94%a8%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/#comments</comments>
		<pubDate>Tue, 29 Jul 2008 09:33:46 +0000</pubDate>
		<dc:creator>chuanliang</dc:creator>
				<category><![CDATA[技术相关]]></category>
		<category><![CDATA[compass]]></category>
		<category><![CDATA[lucene]]></category>
		<category><![CDATA[solr]]></category>
		<category><![CDATA[搜索引擎]]></category>

		<guid isPermaLink="false">http://www.yeeach.com/2008/07/29/%e4%bc%81%e4%b8%9a%e7%ba%a7%e6%90%9c%e7%b4%a2%e5%bc%95%e6%93%8esolr%e4%bd%bf%e7%94%a8%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/</guid>
		<description><![CDATA[&#160;&#160;&#160; 由于搜索引擎功能在门户社区中对提高用户体验有着重在门户社区中涉及大量需要搜索引擎的功能需求，目前在实现搜索引擎的方案上有集中方案可供选择： 基于Lucene自己进行封装实现站内搜索。 工作量及扩展性都较大，不采用。 调用Google、Baidu的API实现站内搜索 同第三方搜索引擎绑定太死，无法满足后期业务扩展需要，暂时不采用。 基于Compass+Lucene实现站内搜索 &#160;&#160;&#160; 适合于对数据库驱动的应用数据进行索引，尤其是替代传统的like ‘%expression%’来实现对varchar或clob等字段的索引，对于实现站内搜索是一种值得采纳的方案。但在分布式处理、接口封装上尚需要自己进行一定程度的封装，暂时不采用。 基于Solr实现站内搜索 封装及扩展性较好，提供了较为完备的解决方案，因此在门户社区中采用此方案，后期加入Compass方案。 1、 Solr简介 &#160;&#160;&#160; Solr是一个基于Lucene的Java搜索引擎服务器。Solr 提供了层面搜索、命中醒目显示并且支持多种输出格式（包括 XML/XSLT 和 JSON 格式）。它易于安装和配置，而且附带了一个基于 HTTP 的管理界面。Solr已经在众多大型的网站中使用，较为成熟和稳定。Solr 包装并扩展了 Lucene，所以Solr的基本上沿用了Lucene的相关术语。更重要的是，Solr 创建的索引与 Lucene 搜索引擎库完全兼容。通过对 Solr 进行适当的配置，某些情况下可能需要进行编码，Solr 可以阅读和使用构建到其他 Lucene 应用程序中的索引。此外，很多 Lucene 工具（如Nutch、 Luke）也可以使用 Solr 创建的索引。 2、 Tomcat下Solr安装配置 &#160;&#160;&#160; 由于Solr基于java开发，因此Solr在windows及Linux都能较好部署使用，但由于Solr提供了一些用于测试及管理、维护较为方便的shell脚本，因此在生产部署时候建议安装在Linux上，测试时候可以在windows使用。 下面以Linux下安装配置Solr进行说明，windows与此类似。 wget http://apache.mirror.phpchina.com/tomcat/tomcat-6/v6.0.16/bin/apache-tomcat-6.0.16.zip unzip apache-tomcat-6.0.16.zip mv apache-tomcat-6.0.16 /opt/tomcat chmod 755 /opt/tomcat/bin/* wget http://apache.mirror.phpchina.com/lucene/solr/1.2/apache-solr-1.2.0.tgz [...]]]></description>
			<content:encoded><![CDATA[</p>
<p>&#160;&#160;&#160; 由于搜索引擎功能在门户社区中对提高用户体验有着重在门户社区中涉及大量需要搜索引擎的功能需求，目前在实现搜索引擎的方案上有集中方案可供选择：</p>
<ul>
<li>基于Lucene自己进行封装实现站内搜索。 </li>
</ul>
<p>工作量及扩展性都较大，不采用。</p>
<ul>
<li>调用Google、Baidu的API实现站内搜索 </li>
</ul>
<p>同第三方搜索引擎绑定太死，无法满足后期业务扩展需要，暂时不采用。</p>
<ul>
<li>基于Compass+Lucene实现站内搜索 </li>
</ul>
<p>&#160;&#160;&#160; 适合于对数据库驱动的应用数据进行索引，尤其是替代传统的like ‘%expression%’来实现对varchar或clob等字段的索引，对于实现站内搜索是一种值得采纳的方案。但在分布式处理、接口封装上尚需要自己进行一定程度的封装，暂时不采用。</p>
<ul>
<li>基于Solr实现站内搜索 </li>
</ul>
<p>封装及扩展性较好，提供了较为完备的解决方案，因此在门户社区中采用此方案，后期加入Compass方案。</p>
<h3><b>1、 </b><b>Solr</b><b>简介</b></h3>
<p>&#160;&#160;&#160; Solr是一个基于Lucene的Java搜索引擎服务器。Solr 提供了层面搜索、命中醒目显示并且支持多种输出格式（包括 XML/XSLT 和 JSON 格式）。它易于安装和配置，而且附带了一个基于 HTTP 的管理界面。Solr已经在众多大型的网站中使用，较为成熟和稳定。Solr 包装并扩展了 Lucene，所以Solr的基本上沿用了Lucene的相关术语。更重要的是，Solr 创建的索引与 Lucene 搜索引擎库完全兼容。通过对 Solr 进行适当的配置，某些情况下可能需要进行编码，Solr 可以阅读和使用构建到其他 Lucene 应用程序中的索引。此外，很多 Lucene 工具（如Nutch、 Luke）也可以使用 Solr 创建的索引。</p>
<h3><b>2、 </b><b>Tomcat</b><b>下Solr安装配置</b></h3>
<p>&#160;&#160;&#160; 由于Solr基于java开发，因此Solr在windows及Linux都能较好部署使用，但由于Solr提供了一些用于测试及管理、维护较为方便的shell脚本，因此在生产部署时候建议安装在Linux上，测试时候可以在windows使用。</p>
<p>下面以Linux下安装配置Solr进行说明，windows与此类似。</p>
<p>wget <a href="http://apache.mirror.phpchina.com/tomcat/tomcat-6/v6.0.16/bin/apache-tomcat-6.0.16.zip" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://apache.mirror.phpchina.com/tomcat/tomcat-6/v6.0.16/bin/apache-tomcat-6.0.16.zip');">http://apache.mirror.phpchina.com/tomcat/tomcat-6/v6.0.16/bin/apache-tomcat-6.0.16.zip</a></p>
<p>unzip apache-tomcat-6.0.16.zip</p>
<p>mv apache-tomcat-6.0.16 /opt/tomcat</p>
<p>chmod 755 /opt/tomcat/bin/*</p>
<p>wget <a href="http://apache.mirror.phpchina.com/lucene/solr/1.2/apache-solr-1.2.0.tgz" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://apache.mirror.phpchina.com/lucene/solr/1.2/apache-solr-1.2.0.tgz');">http://apache.mirror.phpchina.com/lucene/solr/1.2/apache-solr-1.2.0.tgz</a></p>
<p>tar zxvf apache-solr-1.2.0.tgz</p>
<p>Solr的安装配置最为麻烦的是对solr.solr.home的理解和配置，主要有三种</p>
<ul>
<li>基于当前路径的方式 </li>
</ul>
<p>cp apache-solr-1.2.0/dist/apache-solr-1.2.0.war /opt/tomcat/webapps/solr.war</p>
<p>mkdir /opt/solr-tomcat</p>
<p>cp -r apache-solr-1.2.0/example/solr/ /opt/solr-tomcat/</p>
<p>cd /opt/solr-tomcat</p>
<p>/opt/tomcat/bin/startup.sh </p>
<p>由于在此种情况下（没有设定solr.solr.home环境变量或JNDI的情况下），Solr查找./solr，因此在启动时候需要切换到/opt/solr-tomcat</p>
<ul>
<li>基于环境变量<tt>solr.solr.home</tt> </li>
</ul>
<p>在当前用户的环境变量中（.bash_profile）或在/opt/tomcat/catalina.sh中添加如下环境变量</p>
<p>export JAVA_OPTS=&quot;$JAVA_OPTS -Dsolr.solr.home=/opt/solr-tomcat/solr&quot;</p>
<p><tt></tt></p>
<ul>
<li>基于JNDI配置 </li>
</ul>
<p>mkdir –p /opt/tomcat/conf/Catalina/localhost</p>
<p>touch /opt/tomcat/conf/Catalina/localhost/solr.xml ，内容如下:</p>
<pre>&#160;&#160;&#160;&#160;&#160; <i>&lt;Context docBase=&quot;/opt/tomcat/webapps/solr.war&quot; debug=&quot;0&quot; crossContext=&quot;true&quot; &gt;</i></pre>
<pre><i>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Environment name=&quot;solr/home&quot; type=&quot;java.lang.String&quot; value=&quot;/opt/solr-tomcat/solr&quot; override=&quot;true&quot; /&gt;</i></pre>
<pre><i>&#160;&#160;&#160; &lt;/Context&gt;</i></pre>
<p>访问solr管理界面</p>
<p><a href="http://ip:port/solr" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://ip:port/solr');">http://ip:port/solr</a></p>
<h3><b>3、 </b><b>Solr</b><b>原理</b></h3>
<p><a href="http://www.yeeach.com/wp-content/uploads/2008/07/clip-image002.gif" ><img title="clip_image002" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="479" alt="clip_image002" src="http://www.yeeach.com/wp-content/uploads/2008/07/clip-image002-thumb.gif" width="627" border="0" /></a></p>
<p>&#160;&#160;&#160; Solr对外提供标准的http接口来实现对数据的索引的增加、删除、修改、查询。在 Solr 中，用户通过向部署在servlet 容器中的 Solr Web 应用程序发送 HTTP 请求来启动索引和搜索。Solr 接受请求，确定要使用的适当SolrRequestHandler，然后处理请求。通过 HTTP 以同样的方式返回响应。默认配置返回 Solr 的标准 XML 响应，也可以配置 Solr 的备用响应格式。</p>
<p>可以向 Solr 索引 servlet 传递四个不同的索引请求：</p>
<ul>
<li>add/update 允许向 Solr 添加文档或更新文档。直到提交后才能搜索到这些添加和更新。 </li>
<li>commit 告诉 Solr，应该使上次提交以来所做的所有更改都可以搜索到。 </li>
<li>optimize 重构 Lucene 的文件以改进搜索性能。索引完成后执行一下优化通常比较好。如果更新比较频繁，则应该在使用率较低的时候安排优化。一个索引无需优化也可以正常地运行。优化是一个耗时较多的过程。 </li>
<li>delete 可以通过 id 或查询来指定。按 id 删除将删除具有指定 id 的文档；按查询删除将删除查询返回的所有文档。 </li>
</ul>
<p>一个典型的Add请求报文</p>
<p>&lt;add&gt;</p>
<p>&lt;doc&gt;</p>
<p>&#160; &lt;field name=&quot;id&quot;&gt;TWINX2048-3200PRO&lt;/field&gt;</p>
<p>&#160; &lt;field name=&quot;name&quot;&gt;CORSAIR&#160; XMS 2GB (2 x 1GB) 184-Pin DDR SDRAM Unbuffered DDR 400 (PC 3200) Dual Channel Kit System Memory &#8211; Retail&lt;/field&gt;</p>
<p>&#160; &lt;field name=&quot;manu&quot;&gt;Corsair Microsystems Inc.&lt;/field&gt;</p>
<p>&#160; &lt;field name=&quot;cat&quot;&gt;electronics&lt;/field&gt;</p>
<p>&#160; &lt;field name=&quot;cat&quot;&gt;memory&lt;/field&gt;</p>
<p>&#160; &lt;field name=&quot;features&quot;&gt;CAS latency 2, 2-3-3-6 timing, 2.75v, unbuffered, heat-spreader&lt;/field&gt;</p>
<p>&#160; &lt;field name=&quot;price&quot;&gt;185&lt;/field&gt;</p>
<p>&#160; &lt;field name=&quot;popularity&quot;&gt;5&lt;/field&gt;</p>
<p>&#160; &lt;field name=&quot;inStock&quot;&gt;true&lt;/field&gt;</p>
<p>&lt;/doc&gt;</p>
<p>&lt;doc&gt;</p>
<p>&#160; &lt;field name=&quot;id&quot;&gt;VS1GB400C3&lt;/field&gt;</p>
<p>&#160; &lt;field name=&quot;name&quot;&gt;CORSAIR ValueSelect 1GB 184-Pin DDR SDRAM Unbuffered DDR 400 (PC 3200) System Memory &#8211; Retail&lt;/field&gt;</p>
<p>&#160; &lt;field name=&quot;manu&quot;&gt;Corsair Microsystems Inc.&lt;/field&gt;</p>
<p>&#160; &lt;field name=&quot;cat&quot;&gt;electronics&lt;/field&gt;</p>
<p>&#160; &lt;field name=&quot;cat&quot;&gt;memory&lt;/field&gt;</p>
<p>&#160; &lt;field name=&quot;price&quot;&gt;74.99&lt;/field&gt;</p>
<p>&#160; &lt;field name=&quot;popularity&quot;&gt;7&lt;/field&gt;</p>
<p>&#160; &lt;field name=&quot;inStock&quot;&gt;true&lt;/field&gt;</p>
<p>&lt;/doc&gt;</p>
<p>&lt;/add&gt;</p>
<p>一个典型的搜索结果报文：</p>
<p>&lt;response&gt;</p>
<p>&#160;&#160;&#160; &lt;lst name=&quot;responseHeader&quot;&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;int name=&quot;status&quot;&gt;0&lt;/int&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;int name=&quot;QTime&quot;&gt;6&lt;/int&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;lst name=&quot;params&quot;&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;str name=&quot;rows&quot;&gt;10&lt;/str&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;str name=&quot;start&quot;&gt;0&lt;/str&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;str name=&quot;fl&quot;&gt;*,score&lt;/str&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;str name=&quot;hl&quot;&gt;true&lt;/str&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;str name=&quot;q&quot;&gt;content:&quot;faceted browsing&quot;&lt;/str&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/lst&gt;</p>
<p>&#160;&#160;&#160; &lt;/lst&gt;</p>
<p>&#160;&#160;&#160; &lt;result name=&quot;response&quot; numFound=&quot;1&quot; start=&quot;0&quot; maxScore=&quot;1.058217&quot;&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;doc&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;float name=&quot;score&quot;&gt;1.058217&lt;/float&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;arr name=&quot;all&quot;&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;str&gt;<a href="http://localhost/myBlog/solr-rocks-again.html%3c/str" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://localhost/myBlog/solr-rocks-again.html%3c/str');">http://localhost/myBlog/solr-rocks-again.html&lt;/str</a>&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;str&gt;Solr is Great&lt;/str&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;str&gt;solr,lucene,enterprise,search,greatness&lt;/str&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;str&gt;Solr has some really great features, like faceted browsing</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; and replication&lt;/str&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/arr&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;arr name=&quot;content&quot;&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;str&gt;Solr has some really great features, like faceted browsing</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; and replication&lt;/str&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/arr&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;date name=&quot;creationDate&quot;&gt;2007-01-07T05:04:00.000Z&lt;/date&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;arr name=&quot;keywords&quot;&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;str&gt;solr,lucene,enterprise,search,greatness&lt;/str&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/arr&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;int name=&quot;rating&quot;&gt;8&lt;/int&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;str name=&quot;title&quot;&gt;Solr is Great&lt;/str&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;str name=&quot;url&quot;&gt;<a href="http://localhost/myBlog/solr-rocks-again.html%3c/str" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://localhost/myBlog/solr-rocks-again.html%3c/str');">http://localhost/myBlog/solr-rocks-again.html&lt;/str</a>&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/doc&gt;</p>
<p>&#160;&#160;&#160; &lt;/result&gt;</p>
<p>&#160;&#160;&#160; &lt;lst name=&quot;highlighting&quot;&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;lst name=&quot;<a href="http://localhost/myBlog/solr-rocks-again.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://localhost/myBlog/solr-rocks-again.html');">http://localhost/myBlog/solr-rocks-again.html</a>&quot;&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;arr name=&quot;content&quot;&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;str&gt;Solr has some really great features, like &lt;em&gt;faceted&lt;/em&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;em&gt;browsing&lt;/em&gt; and replication&lt;/str&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/arr&gt;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/lst&gt;</p>
<p>&#160;&#160;&#160; &lt;/lst&gt;</p>
<p>&lt;/response&gt;</p>
<p>关于solr的详细使用说明，请参考</p>
<p><a href="http://wiki.apache.org/solr/FrontPage" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://wiki.apache.org/solr/FrontPage');">http://wiki.apache.org/solr/FrontPage</a></p>
<p><b></b></p>
<p><b></b></p>
<h3><b>4、 </b><b>Solr</b><b>测试使用</b></h3>
<p>Solr的安装包包含了相关的测试样例，路径在apache-solr-1.2.0/example/exampledocs</p>
<ul>
<li>使用shell脚本（curl）测试Solr的操作： </li>
</ul>
<p>cd apache-solr-1.2.0/example/exampledocs</p>
<p>vi post.sh，根据tomcat的ip、port修改URL变量的值URL=http://localhost:8080/solr/update</p>
<pre>./post.sh *.xml&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; # </pre>
<ul>
<li>使用Solr的java 包测试Solr的操作： </li>
</ul>
<p>查看帮助：java -jar post.jar –help</p>
<p>提交测试数据：</p>
<p>java -Durl=http://localhost:8080/solr/update -Ddata=files -jar post.jar&#160; *.xml&#160;&#160;&#160;&#160;&#160;&#160; </p>
<pre>&#160;</pre>
<p>下面以增加索引字段liangchuan、url为例，说明一下Solr中索引命令的使用</p>
<p>1) 修改solr的schema，配置需要索引字段的说明：</p>
<p>vi /opt/solr-tomcat/solr/conf/schema.xml ,在&lt;fields&gt;中增加如下内容</p>
<p>&#160;&#160; &lt;field name=&quot;liangchuan&quot;&#160; type=&quot;string&quot; indexed=&quot;true&quot; stored=&quot;true&quot;/&gt;</p>
<p>&#160;&#160; &lt;field name=&quot;url&quot;&#160; type=&quot;string&quot; indexed=&quot;true&quot; stored=&quot;true&quot;/&gt;</p>
<p>2) 创建增加索引请求的xml测试文件</p>
<p>touch /root/apache-solr-1.2.0/example/exampledocs/liangchuan.xml,内容如下：</p>
<p>&lt;add&gt;</p>
<p>&lt;doc&gt;</p>
<p>&#160; &lt;field name=&quot;id&quot;&gt;liangchuan000&lt;/field&gt;</p>
<p>&#160; &lt;field name=&quot;name&quot;&gt;Solr, the Enterprise Search Server&lt;/field&gt;</p>
<p>&#160; &lt;field name=&quot;manu&quot;&gt;Apache Software Foundation&lt;/field&gt;</p>
<p>&#160; &lt;field name=&quot;liangchuan&quot;&gt;liangchuan&#8217;s solr &quot;hello,world&quot; test&lt;/field&gt;</p>
<p>&#160; &lt;field name=&quot;url&quot;&gt;<a href="http://www.google.com%3c/field" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.google.com%3c/field');">http://www.google.com&lt;/field</a>&gt;</p>
<p>&lt;/doc&gt;</p>
<p>&lt;/add&gt;</p>
<p>3) 提交索引请求</p>
<p>cd apache-solr-1.2.0/example/exampledocs</p>
<pre>&#160;&#160;&#160; ./post.sh liangchuan.xml</pre>
<pre>&#160;&#160;&#160; </pre>
<p>4) 查询</p>
<p>通过solr的管理员界面<a href="http://localhost:8080/solr/admin" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://localhost:8080/solr/admin');">http://localhost:8080/solr/admin</a>查询</p>
<p>或通过curl 测试：</p>
<pre>&#160;&#160;&#160;&#160;&#160;&#160; export URL=&quot;<a href="http://localhost:8080/solr/select/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://localhost:8080/solr/select/');">http://localhost:8080/solr/select/</a>&quot;</pre>
<pre>&#160;&#160;&#160;&#160;&#160;&#160; curl &quot;$URL?indent=on&amp;q=liangchuan&amp;fl=*,score&quot;</pre>
<pre>&#160;</pre>
<h3>5、Solr查询条件参数说明</h3>
<pre>&#160;</pre>
<table cellspacing="0" cellpadding="2" width="809" border="0">
<tbody>
<tr>
<td valign="top" width="104"><b>参数</b></td>
<td valign="top" width="476"><b>描述</b></td>
<td valign="top" width="227"><b>示例</b></td>
</tr>
<tr>
<td valign="top" width="104">q</td>
<td valign="top" width="476">Solr 中用来搜索的查询。可以通过追加一个分号和已索引且未进行断词的字段的名称来包含排序信息。默认的排序是 score desc，指按记分降序排序。</td>
<td valign="top" width="227">
<p>q=myField:Java AND otherField:developerWorks; date asc<br />
          <br />此查询搜索指定的两个字段并根据一个日期字段对结果进行排序。</p>
</td>
</tr>
<tr>
<td valign="top" width="104">start</td>
<td valign="top" width="476">将初始偏移量指定到结果集中。可用于对结果进行分页。默认值为 0。</td>
<td valign="top" width="227">
<p>start=15<br />
          <br />返回从第 15 个结果开始的结果。</p>
</td>
</tr>
<tr>
<td valign="top" width="104">rows</td>
<td valign="top" width="476">返回文档的最大数目。默认值为 10。</td>
<td valign="top" width="227">rows=25</td>
</tr>
<tr>
<td valign="top" width="104">fq</td>
<td valign="top" width="476">
<p>提供一个可选的筛选器查询。查询结果被限制为仅搜索筛选器查询返回的结果。筛选过的查询由 Solr 进行缓存。它们对提高复杂查询的速度非常有用。</p>
</td>
<td valign="top" width="227">任何可以用 q 参数传递的有效查询，排序信息除外。</td>
</tr>
<tr>
<td valign="top" width="104">hl</td>
<td valign="top" width="476">当 hl=true 时，在查询响应中醒目显示片段。默认为 false。参看醒目显示参数上的 Solr Wiki 部分可以查看更多选项</td>
<td valign="top" width="227">hl=true</td>
</tr>
<tr>
<td valign="top" width="104">fl</td>
<td valign="top" width="476">作为逗号分隔的列表指定文档结果中应返回的 Field 集。默认为 “*”，指所有的字段。“score” 指还应返回记分。</td>
<td valign="top" width="227">
<p>*,score</p>
</td>
</tr>
</tbody>
</table>
<pre>   其中关于Solr查询相关的参数详细的信息请参看：</pre>
<pre>&#160;&#160; <a href="http://wiki.apache.org/solr/CommonQueryParameters" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://wiki.apache.org/solr/CommonQueryParameters');">http://wiki.apache.org/solr/CommonQueryParameters</a></pre>
<p>&#160;&#160;&#160; Solr的查询条件参数q的格式与Lucene相同，具体参看：</p>
<p>&#160;&#160;&#160;&#160;&#160; <a href="http://lucene.apache.org/java/docs/queryparsersyntax.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://lucene.apache.org/java/docs/queryparsersyntax.html');">http://lucene.apache.org/java/docs/queryparsersyntax.html</a></p>
<h3><b>6、 </b><b>在门户社区中solr使用模式</b></h3>
<p>在门户社区中需要使用solr，可采用如下模式：</p>
<ul>
<li>对原有系统已有的数据或需要索引的数据量较大的情况 </li>
</ul>
<p>&#160;&#160;&#160; 直接采用通过http方式调用solr的接口方式，效率较差，采用solr本身对csv 的支持（<a href="http://wiki.apache.org/solr/UpdateCSV" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://wiki.apache.org/solr/UpdateCSV');">http://wiki.apache.org/solr/UpdateCSV</a></p>
<pre>），将数据导出为csv格式，然后调用solr的csv接口<a href="http://localhost:8080/solr/update/csv" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://localhost:8080/solr/update/csv');">http://localhost:8080/solr/update/csv</a></pre>
<ul>
<li>对系统新增的数据 </li>
</ul>
<p>&#160;&#160;&#160; 先将需要索引查询的数据组装成xml格式，然后使用httpclient 将数据提交到solr 的http接口，例如<a href="http://localhost:8080/solr/update" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://localhost:8080/solr/update');">&#160;&#160;&#160;&#160; </a></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <a href="http://localhost:8080/solr/update" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://localhost:8080/solr/update');">http://localhost:8080/solr/update</a></p>
<pre>&#160;&#160; 也可以参考post.jar中的SimplePostTool的实现。</pre>
<pre><a href="http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/util/SimplePostTool.java?view=co" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/util/SimplePostTool.java?view=co');">http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/util/SimplePostTool.java?view=co</a></pre>
<ul>
<li>中文分词 </li>
</ul>
<p>&#160;&#160;&#160; 采用庖丁解牛作为solr（Lucene）缺省的中文分词方案</p>
<p>&#160;&#160;&#160; 项目库：<a href="http://code.google.com/p/paoding/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://code.google.com/p/paoding/');">http://code.google.com/p/paoding/</a></p>
<p>&#160;&#160;&#160; Google groups：<a href="http://groups.google.com/group/paoding" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://groups.google.com/group/paoding');">http://groups.google.com/group/paoding</a></p>
<p>&#160;&#160;&#160; Javaeye的groups：<a href="http://analysis.group.javaeye.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://analysis.group.javaeye.com/');">http://analysis.group.javaeye.com/</a></p>
<ul>
<li>与nutch的集成使用 </li>
</ul>
<p>&#160;&#160;&#160; <a href="http://blog.foofactory.fi/2007/02/online-indexing-integrating-nutch-with.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://blog.foofactory.fi/2007/02/online-indexing-integrating-nutch-with.html');">http://blog.foofactory.fi/2007/02/online-indexing-integrating-nutch-with.html</a></p>
<ul>
<li>嵌入式Solr </li>
</ul>
<p>&#160;&#160;&#160; <a href="http://wiki.apache.org/solr/Solrj#EmbeddedSolrServer" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://wiki.apache.org/solr/Solrj#EmbeddedSolrServer');">http://wiki.apache.org/solr/Solrj#EmbeddedSolrServer</a></p>
<ul>
<li>分布式索引 </li>
</ul>
<p>&#160;&#160;&#160; <a href="http://wiki.apache.org/solr/CollectionDistribution" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://wiki.apache.org/solr/CollectionDistribution');">http://wiki.apache.org/solr/CollectionDistribution</a></p>
<h3>7、参考资料</h3>
<p><a href="http://wiki.apache.org/solr/CollectionDistribution" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://wiki.apache.org/solr/CollectionDistribution');">http://wiki.apache.org/solr/</a></p>
<p><a href="http://www.ibm.com/developerworks/cn/java/j-solr1/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.ibm.com/developerworks/cn/java/j-solr1/');">http://www.ibm.com/developerworks/cn/java/j-solr1/</a></p>
<p><a href="http://www.ibm.com/developerworks/cn/java/j-solr2/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.ibm.com/developerworks/cn/java/j-solr2/');">http://www.ibm.com/developerworks/cn/java/j-solr2/</a></p>
<p><a href="http://www.xml.com/pub/a/2006/08/09/solr-indexing-xml-with-lucene-andrest.html?page=1" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.xml.com/pub/a/2006/08/09/solr-indexing-xml-with-lucene-andrest.html?page=1');">http://www.xml.com/pub/a/2006/08/09/solr-indexing-xml-with-lucene-andrest.html?page=1</a></p>
<p><a title="http://lucene.apache.org/java/docs/queryparsersyntax.html" href="http://lucene.apache.org/java/docs/queryparsersyntax.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://lucene.apache.org/java/docs/queryparsersyntax.html');">http://lucene.apache.org/java/docs/queryparsersyntax.html</a></p>
<p><a title="http://www.blogjava.net/RongHao/archive/2007/11/06/158621.html" href="http://www.blogjava.net/RongHao/archive/2007/11/06/158621.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.blogjava.net/RongHao/archive/2007/11/06/158621.html');">http://www.blogjava.net/RongHao/archive/2007/11/06/158621.html</a></p>
<p>&#160;</p>
<div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:8db87d22-1e0c-440c-8f0a-074c03b74e9b" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tags: <a href="http://technorati.com/tags/lucene" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/tags/lucene');" rel="tag">lucene</a>,<a href="http://technorati.com/tags/solr" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/tags/solr');" rel="tag">solr</a>,<a href="http://technorati.com/tags/%e6%90%9c%e7%b4%a2%e5%bc%95%e6%93%8e" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/tags/%e6%90%9c%e7%b4%a2%e5%bc%95%e6%93%8e');" rel="tag">搜索引擎</a>,<a href="http://technorati.com/tags/compass" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/tags/compass');" rel="tag">compass</a></div>
	<p></p>
	<hr noshade style="margin:0;height:1px" />
	<p>&copy; chuanliang for <a href="http://www.yeeach.com" >出家如初，成佛有余</a>, 2008. |
	  <a href="http://www.yeeach.com/2008/07/29/%e4%bc%81%e4%b8%9a%e7%ba%a7%e6%90%9c%e7%b4%a2%e5%bc%95%e6%93%8esolr%e4%bd%bf%e7%94%a8%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/" >Permalink</a> |
	  <a href="http://www.yeeach.com/2008/07/29/%e4%bc%81%e4%b8%9a%e7%ba%a7%e6%90%9c%e7%b4%a2%e5%bc%95%e6%93%8esolr%e4%bd%bf%e7%94%a8%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/#comments" >4 comments</a></p>
	<p>Add to <a href="http://del.icio.us/post?url=http://www.yeeach.com/2008/07/29/%e4%bc%81%e4%b8%9a%e7%ba%a7%e6%90%9c%e7%b4%a2%e5%bc%95%e6%93%8esolr%e4%bd%bf%e7%94%a8%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/&amp;title=企业级搜索引擎Solr使用入门指南" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://del.icio.us/post?url=http://www.yeeach.com/2008/07/29/%e4%bc%81%e4%b8%9a%e7%ba%a7%e6%90%9c%e7%b4%a2%e5%bc%95%e6%93%8esolr%e4%bd%bf%e7%94%a8%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/&amp;title=企业级搜索引擎Solr使用入门指南');">del.icio.us</a></p>
	<p>Search blogs linking this post with <a href="http://www.technorati.com/search/http://www.yeeach.com/2008/07/29/%e4%bc%81%e4%b8%9a%e7%ba%a7%e6%90%9c%e7%b4%a2%e5%bc%95%e6%93%8esolr%e4%bd%bf%e7%94%a8%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.technorati.com/search/http://www.yeeach.com/2008/07/29/%e4%bc%81%e4%b8%9a%e7%ba%a7%e6%90%9c%e7%b4%a2%e5%bc%95%e6%93%8esolr%e4%bd%bf%e7%94%a8%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/');" title="Search on Technorati">Technorati</a></p>
	<p>Want more on these topics ? Browse the archive of posts filed under <a href="http://www.yeeach.com/category/%e6%8a%80%e6%9c%af-%e8%bd%af%e4%bb%b6/"  title="查看 技术相关 的全部文章" rel="category tag">技术相关</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.yeeach.com/2008/07/29/%e4%bc%81%e4%b8%9a%e7%ba%a7%e6%90%9c%e7%b4%a2%e5%bc%95%e6%93%8esolr%e4%bd%bf%e7%94%a8%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>无线互联网垂直电子商务平台各系统内容运维策略思考</title>
		<link>http://www.yeeach.com/2008/05/16/%e6%97%a0%e7%ba%bf%e4%ba%92%e8%81%94%e7%bd%91%e5%9e%82%e7%9b%b4%e7%94%b5%e5%ad%90%e5%95%86%e5%8a%a1%e5%b9%b3%e5%8f%b0%e5%90%84%e7%b3%bb%e7%bb%9f%e5%86%85%e5%ae%b9%e8%bf%90%e7%bb%b4%e7%ad%96%e7%95%a5/</link>
		<comments>http://www.yeeach.com/2008/05/16/%e6%97%a0%e7%ba%bf%e4%ba%92%e8%81%94%e7%bd%91%e5%9e%82%e7%9b%b4%e7%94%b5%e5%ad%90%e5%95%86%e5%8a%a1%e5%b9%b3%e5%8f%b0%e5%90%84%e7%b3%bb%e7%bb%9f%e5%86%85%e5%ae%b9%e8%bf%90%e7%bb%b4%e7%ad%96%e7%95%a5/#comments</comments>
		<pubDate>Fri, 16 May 2008 15:21:14 +0000</pubDate>
		<dc:creator>chuanliang</dc:creator>
				<category><![CDATA[技术相关]]></category>
		<category><![CDATA[无线互联网及增值业务]]></category>
		<category><![CDATA[电子商务]]></category>
		<category><![CDATA[cobra]]></category>
		<category><![CDATA[heritrix]]></category>
		<category><![CDATA[htmlparser]]></category>
		<category><![CDATA[lucene]]></category>
		<category><![CDATA[nutch]]></category>
		<category><![CDATA[rhino]]></category>
		<category><![CDATA[内容运营]]></category>
		<category><![CDATA[垂直搜索引擎]]></category>
		<category><![CDATA[无线互联网]]></category>

		<guid isPermaLink="false">http://www.yeeach.com/2008/05/16/%e6%97%a0%e7%ba%bf%e4%ba%92%e8%81%94%e7%bd%91%e5%9e%82%e7%9b%b4%e7%94%b5%e5%ad%90%e5%95%86%e5%8a%a1%e5%b9%b3%e5%8f%b0%e5%90%84%e7%b3%bb%e7%bb%9f%e5%86%85%e5%ae%b9%e8%bf%90%e7%bb%b4%e7%ad%96%e7%95%a5/</guid>
		<description><![CDATA[&#160;&#160;&#160; 在平台的eSales系统、BSS/OSS系统、支付平台、门户这几大平台中，门户及eSales系统中有大量的关于手机软件、手机素材、手机型号参数、手机相关专业知识等相关的资源，这些内容的完备与否是各平台能否成功的关键所在。但作为一家以“渠道通路”为核心竞争力的初创性的互联网公司，内容本身的运维、运营并不是我们自己最为擅长的地方，近期也不可能招聘一批专职的内容运营人员来做网站内容本身的运营。从技术角度谈一下门户及eSales系统的内容运维策略，以更好支撑运营部门的日常运营。 1. 平台（门户、eSales系统）内容运维基本原则 门户定位：手机增值业务垂直性门户 内容运维基本原则：采用搜索引擎全自动或搜索引擎+人工（人肉搜索）方式对内容进行爬取入库 内容演进过程：垂直搜索引擎自动爬取的内容基础库（无原创内容，无筛选）-&#62;垂直搜索引擎爬取+内容运营人员编辑形成的内容库（较少原创内容，人工参与筛选）-&#62;垂直搜索引擎爬取+内容运营人员编辑+社区原创内容(具有部分原创内容)-&#62;以社区原创性内容为主的内容（UGC）。 第一阶段：垂直搜索引擎自动爬取的内容基础库 &#160;&#160;&#160; 由垂直搜索引擎的对互联网上海量的手机内容进行自动爬取入库，形成自身的基础内容库；在内容上无太多的原创内容，也无内容编辑人员对爬取的内容进行筛选和过滤。这属于内容运维的第一阶段，也是近期的技术开发重点。 第二阶段：垂直搜索引擎爬取+内容运营人员编辑形成的内容库 &#160;&#160;&#160; 在第一阶段的基础上，由内容运营人员对爬取内容进行审核、编辑，保证内容库的质量 第三阶段：垂直搜索引擎爬取+内容运营人员编辑+社区原创内容 &#160;&#160;&#160; 在第三阶段基础上，将内容平台逐步开放，并将社区人员来参与到内容平台的建设中，充分发挥群体智慧的力量。 第四阶段：以社区原创性内容为主的内容 &#160;&#160;&#160; 在社区逐步成熟后，在此阶段，平台的核心内容只要是用户参与产生的内容（UGC），这也是门户的核心价值。 2. 技术架构指导原则： &#160;&#160;&#160; 技术架构的统一：各平台核心数据模型、业务模型、技术架构必须遵循平台统一的架构，保证平台各系统的内容资源是完全复用的。 &#160;&#160;&#160; 垂直搜索引擎的建设：尽管垂直门户的建设是门户的核心内容，但围绕“渠道通路”的建设才是的核心竞争力，这包括支付通路、内容分销通路、手机通路、互联网通路等，近期的建设重点并不是社区门户的建设，因此在开发上不能投入太多的开发资源到垂直搜索引擎的开发上，在满足未来扩展性的基础上，采用相对快捷的方式开发垂直搜索引擎。 3. 垂直搜索引擎技术实现 &#160;&#160;&#160; 近期垂直搜索引擎的建设重点是爬虫，与普通的垂直性搜索引擎不同，我们是对网站内容进行爬取，而不对内容进行索引。而在内容爬取上，重点是对指定网站页面内容（例如北斗手机网）所需要内容的定向解析。 &#160;&#160;&#160; 爬取整站内容或复杂爬取需求选用的爬虫框架：Heritrix、Nutch。但这两个框架都较重，初期我们并不需要处理诸如爬取层次、增量爬取等策略，因此这两个框架后期再采用。 &#160;&#160;&#160; 对Javascript的解析：采用Rhino（SpiderMonkey） &#160;&#160;&#160; 爬取指定内容选用的爬虫框架（目前使用方式）：httpclient+htmlparser(nekohtml)。采用httpclient完成对网站内容指定页面的爬取，采用nekohtml或htmlparser包来对页面内容进行定向解析并爬取。在实现上可以参考httpunit对Rhino+httpclient+nekohtml的封装和实现。 &#160;&#160;&#160; 对采用AJAX方式生成内容的爬取：采用Cobra（http://lobobrowser.org/cobra.jsp） &#160;&#160;&#160; 搜索引擎：采用Lucene+Compass &#160; Technorati 标签: 电子商务,无线互联网,垂直搜索引擎,内容运营,heritrix,nutch,htmlparser,rhino,cobra,lucene &#169; chuanliang for 出家如初，成佛有余, 2008. &#124; Permalink &#124; No comment Add to [...]]]></description>
			<content:encoded><![CDATA[<p>&nbsp;&nbsp;&nbsp; 在平台的eSales系统、BSS/OSS系统、支付平台、门户这几大平台中，门户及eSales系统中有大量的关于手机软件、手机素材、手机型号参数、手机相关专业知识等相关的资源，这些内容的完备与否是各平台能否成功的关键所在。但作为一家以“渠道通路”为核心竞争力的初创性的互联网公司，内容本身的运维、运营并不是我们自己最为擅长的地方，近期也不可能招聘一批专职的内容运营人员来做网站内容本身的运营。从技术角度谈一下门户及eSales系统的内容运维策略，以更好支撑运营部门的日常运营。
<p><b>1. </b><b>平台（门户、eSales系统）内容运维基本原则</b>
<ul>
<li><b>门户定位</b>：手机增值业务垂直性门户
<li><b>内容运维基本原则</b>：采用搜索引擎全自动或搜索引擎+人工（人肉搜索）方式对内容进行爬取入库
<li><b>内容演进过程</b>：垂直搜索引擎自动爬取的内容基础库（无原创内容，无筛选）-&gt;垂直搜索引擎爬取+内容运营人员编辑形成的内容库（较少原创内容，人工参与筛选）-&gt;垂直搜索引擎爬取+内容运营人员编辑+社区原创内容(具有部分原创内容)-&gt;以社区原创性内容为主的内容（UGC）。</li>
</ul>
<p><b>第一阶段：垂直搜索引擎自动爬取的内容基础库</b>
<p>&nbsp;&nbsp;&nbsp; 由垂直搜索引擎的对互联网上海量的手机内容进行自动爬取入库，形成自身的基础内容库；在内容上无太多的原创内容，也无内容编辑人员对爬取的内容进行筛选和过滤。这属于内容运维的第一阶段，也是近期的技术开发重点。
<p><b>第二阶段：垂直搜索引擎爬取+内容运营人员编辑形成的内容库</b>
<p>&nbsp;&nbsp;&nbsp; 在第一阶段的基础上，由内容运营人员对爬取内容进行审核、编辑，保证内容库的质量
<p><b>第三阶段：垂直搜索引擎爬取+内容运营人员编辑+社区原创内容</b>
<p><b></b>&nbsp;&nbsp;&nbsp; 在第三阶段基础上，将内容平台逐步开放，并将社区人员来参与到内容平台的建设中，充分发挥群体智慧的力量。
<p><b>第四阶段：以社区原创性内容为主的内容</b>
<p>&nbsp;&nbsp;&nbsp; 在社区逐步成熟后，在此阶段，平台的核心内容只要是用户参与产生的内容（UGC），这也是门户的核心价值。
<p><b>2. </b><b>技术架构指导原则：</b>
<p><b>&nbsp;&nbsp;&nbsp; 技术架构的统一</b>：各平台核心数据模型、业务模型、技术架构必须遵循平台统一的架构，保证平台各系统的内容资源是完全复用的。
<p><b>&nbsp;&nbsp;&nbsp; 垂直搜索引擎的建设</b>：尽管垂直门户的建设是门户的核心内容，但围绕“渠道通路”的建设才是的核心竞争力，这包括支付通路、内容分销通路、手机通路、互联网通路等，近期的建设重点并不是社区门户的建设，因此在开发上不能投入太多的开发资源到垂直搜索引擎的开发上，在满足未来扩展性的基础上，采用相对快捷的方式开发垂直搜索引擎。
<p><b>3. </b><b>垂直搜索引擎技术实现</b>
<p>&nbsp;&nbsp;&nbsp; 近期垂直搜索引擎的建设重点是爬虫，与普通的垂直性搜索引擎不同，我们是对网站内容进行爬取，而不对内容进行索引。而在内容爬取上，重点是对指定网站页面内容（例如北斗手机网）所需要内容的定向解析。
<p><b>&nbsp;&nbsp;&nbsp; 爬取整站内容或复杂爬取需求选用的爬虫框架</b>：Heritrix、Nutch。但这两个框架都较重，初期我们并不需要处理诸如爬取层次、增量爬取等策略，因此这两个框架后期再采用。
<p><b>&nbsp;&nbsp;&nbsp; 对Javascript的解析</b>：采用Rhino（SpiderMonkey）
<p><b>&nbsp;&nbsp;&nbsp; 爬取指定内容选用的爬虫框架（目前使用方式）：</b>httpclient+htmlparser(nekohtml)。采用httpclient完成对网站内容指定页面的爬取，采用nekohtml或htmlparser包来对页面内容进行定向解析并爬取。在实现上可以参考httpunit对Rhino+httpclient+nekohtml的封装和实现。
<p><b>&nbsp;&nbsp;&nbsp; 对采用AJAX方式生成内容的爬取：</b>采用Cobra（<a href="http://lobobrowser.org/cobra.jsp" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://lobobrowser.org/cobra.jsp');">http://lobobrowser.org/cobra.jsp</a>）
<p><b>&nbsp;&nbsp;&nbsp; 搜索引擎：</b>采用Lucene+Compass
<p>&nbsp;</p>
<div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:cae3a11d-4295-400a-a420-6ee21c778c9d" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati 标签: <a href="http://technorati.com/tags/%e7%94%b5%e5%ad%90%e5%95%86%e5%8a%a1" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/tags/%e7%94%b5%e5%ad%90%e5%95%86%e5%8a%a1');" rel="tag">电子商务</a>,<a href="http://technorati.com/tags/%e6%97%a0%e7%ba%bf%e4%ba%92%e8%81%94%e7%bd%91" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/tags/%e6%97%a0%e7%ba%bf%e4%ba%92%e8%81%94%e7%bd%91');" rel="tag">无线互联网</a>,<a href="http://technorati.com/tags/%e5%9e%82%e7%9b%b4%e6%90%9c%e7%b4%a2%e5%bc%95%e6%93%8e" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/tags/%e5%9e%82%e7%9b%b4%e6%90%9c%e7%b4%a2%e5%bc%95%e6%93%8e');" rel="tag">垂直搜索引擎</a>,<a href="http://technorati.com/tags/%e5%86%85%e5%ae%b9%e8%bf%90%e8%90%a5" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/tags/%e5%86%85%e5%ae%b9%e8%bf%90%e8%90%a5');" rel="tag">内容运营</a>,<a href="http://technorati.com/tags/heritrix" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/tags/heritrix');" rel="tag">heritrix</a>,<a href="http://technorati.com/tags/nutch" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/tags/nutch');" rel="tag">nutch</a>,<a href="http://technorati.com/tags/htmlparser" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/tags/htmlparser');" rel="tag">htmlparser</a>,<a href="http://technorati.com/tags/rhino" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/tags/rhino');" rel="tag">rhino</a>,<a href="http://technorati.com/tags/cobra" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/tags/cobra');" rel="tag">cobra</a>,<a href="http://technorati.com/tags/lucene" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/tags/lucene');" rel="tag">lucene</a></div>
	<p></p>
	<hr noshade style="margin:0;height:1px" />
	<p>&copy; chuanliang for <a href="http://www.yeeach.com" >出家如初，成佛有余</a>, 2008. |
	  <a href="http://www.yeeach.com/2008/05/16/%e6%97%a0%e7%ba%bf%e4%ba%92%e8%81%94%e7%bd%91%e5%9e%82%e7%9b%b4%e7%94%b5%e5%ad%90%e5%95%86%e5%8a%a1%e5%b9%b3%e5%8f%b0%e5%90%84%e7%b3%bb%e7%bb%9f%e5%86%85%e5%ae%b9%e8%bf%90%e7%bb%b4%e7%ad%96%e7%95%a5/" >Permalink</a> |
	  <a href="http://www.yeeach.com/2008/05/16/%e6%97%a0%e7%ba%bf%e4%ba%92%e8%81%94%e7%bd%91%e5%9e%82%e7%9b%b4%e7%94%b5%e5%ad%90%e5%95%86%e5%8a%a1%e5%b9%b3%e5%8f%b0%e5%90%84%e7%b3%bb%e7%bb%9f%e5%86%85%e5%ae%b9%e8%bf%90%e7%bb%b4%e7%ad%96%e7%95%a5/#comments" >No comment</a></p>
	<p>Add to <a href="http://del.icio.us/post?url=http://www.yeeach.com/2008/05/16/%e6%97%a0%e7%ba%bf%e4%ba%92%e8%81%94%e7%bd%91%e5%9e%82%e7%9b%b4%e7%94%b5%e5%ad%90%e5%95%86%e5%8a%a1%e5%b9%b3%e5%8f%b0%e5%90%84%e7%b3%bb%e7%bb%9f%e5%86%85%e5%ae%b9%e8%bf%90%e7%bb%b4%e7%ad%96%e7%95%a5/&amp;title=无线互联网垂直电子商务平台各系统内容运维策略思考" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://del.icio.us/post?url=http://www.yeeach.com/2008/05/16/%e6%97%a0%e7%ba%bf%e4%ba%92%e8%81%94%e7%bd%91%e5%9e%82%e7%9b%b4%e7%94%b5%e5%ad%90%e5%95%86%e5%8a%a1%e5%b9%b3%e5%8f%b0%e5%90%84%e7%b3%bb%e7%bb%9f%e5%86%85%e5%ae%b9%e8%bf%90%e7%bb%b4%e7%ad%96%e7%95%a5/&amp;title=无线互联网垂直电子商务平台各系统内容运维策略思考');">del.icio.us</a></p>
	<p>Search blogs linking this post with <a href="http://www.technorati.com/search/http://www.yeeach.com/2008/05/16/%e6%97%a0%e7%ba%bf%e4%ba%92%e8%81%94%e7%bd%91%e5%9e%82%e7%9b%b4%e7%94%b5%e5%ad%90%e5%95%86%e5%8a%a1%e5%b9%b3%e5%8f%b0%e5%90%84%e7%b3%bb%e7%bb%9f%e5%86%85%e5%ae%b9%e8%bf%90%e7%bb%b4%e7%ad%96%e7%95%a5/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.technorati.com/search/http://www.yeeach.com/2008/05/16/%e6%97%a0%e7%ba%bf%e4%ba%92%e8%81%94%e7%bd%91%e5%9e%82%e7%9b%b4%e7%94%b5%e5%ad%90%e5%95%86%e5%8a%a1%e5%b9%b3%e5%8f%b0%e5%90%84%e7%b3%bb%e7%bb%9f%e5%86%85%e5%ae%b9%e8%bf%90%e7%bb%b4%e7%ad%96%e7%95%a5/');" title="Search on Technorati">Technorati</a></p>
	<p>Want more on these topics ? Browse the archive of posts filed under <a href="http://www.yeeach.com/category/%e6%8a%80%e6%9c%af-%e8%bd%af%e4%bb%b6/"  title="查看 技术相关 的全部文章" rel="category tag">技术相关</a>, <a href="http://www.yeeach.com/category/web20-%e6%97%a0%e7%ba%bf%e4%ba%92%e8%81%94%e7%bd%91/"  title="查看 无线互联网及增值业务 的全部文章" rel="category tag">无线互联网及增值业务</a>, <a href="http://www.yeeach.com/category/web20-%e7%94%b5%e5%ad%90%e5%95%86%e5%8a%a1/"  title="查看 电子商务 的全部文章" rel="category tag">电子商务</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.yeeach.com/2008/05/16/%e6%97%a0%e7%ba%bf%e4%ba%92%e8%81%94%e7%bd%91%e5%9e%82%e7%9b%b4%e7%94%b5%e5%ad%90%e5%95%86%e5%8a%a1%e5%b9%b3%e5%8f%b0%e5%90%84%e7%b3%bb%e7%bb%9f%e5%86%85%e5%ae%b9%e8%bf%90%e7%bb%b4%e7%ad%96%e7%95%a5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Compass 入门指南</title>
		<link>http://www.yeeach.com/2008/03/23/compass-%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/</link>
		<comments>http://www.yeeach.com/2008/03/23/compass-%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/#comments</comments>
		<pubDate>Sun, 23 Mar 2008 15:12:04 +0000</pubDate>
		<dc:creator>chuanliang</dc:creator>
				<category><![CDATA[技术相关]]></category>
		<category><![CDATA[compass]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[lucene]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[搜索引擎]]></category>

		<guid isPermaLink="false">http://www.yeeach.com/2008/03/23/compass-%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/</guid>
		<description><![CDATA[&#160;&#160;&#160; 在新架构中打算选择Compass或Hibernate Search作为搜索引擎框架，比较后，感觉Hibernate Search上还是没有Compass成熟，另外考虑到后期对网页的爬取及搜索需求，决定还是基于Compass来作为架构缺省的搜索引擎。网上关于Compass的文档很多，但说得相对完整其详细的入门文档基本上没有，Compass的官方文档倒是说得很详细，但是例子一塌糊涂，存在很大问题。记录一下搭建的过程，作为入门的指南。 &#160;&#160;&#160; Compass 通过OSEM(Object/Search Engine Mapping)允许把应用对象的领域模型映射到搜索引擎，最终通过访问common meta data来达到访问对象的目的。 1、几个核心概念 1.1、annotation vs. xml配置文件 &#160;&#160; Compass的配置文件主要分成三类： &#160;&#160;&#160; 第一类：*.cmd.xml文件* &#160;&#160;&#160;&#160;&#160; .cmd.xml文件是对common meta data进行定义，定义了最终搜索的结果中的最基本的元数据。 &#160;&#160;&#160; 第二类：*.cpm.xml文件 &#160;&#160;&#160;&#160;&#160; *.cpm.xml是Object/Search Engine Mapping,提供了POJO到common meta data的映射。 &#160;&#160;&#160; 第三类：*.cfg.xml文件 &#160;&#160;&#160;&#160;&#160; Compass的*.cfg.xml定义了Compass的Index存放路径、搜索引擎分词等相关信息。 &#160;&#160;&#160; 与采用xml配置文件相比较，采用Annonation方式还是相对简单，尤其是采用Spring时候，不用写*.cmd.xml文件、*.cpm.xml、*.cfg.xml，相对很方便，而且不像Hibernate的Annonation很多，Compass的Annonation的核心标注只有@Searchable、@SearchableId、@SearchableProperty、@SearchableComponent个，很容易记忆。因此推荐使用Annonation方式 １.2、Compass核心API Compass的核心API借鉴了Hibernate的术语，因此在操作上基本上与Hibernate类似，以下为Compass的几个核心接口： &#160;&#160;&#160; CompassConfiguration(类似Hibernate Configuration)：用来在一些设置参数、配置文件和映射定义上配置Compass。通常用来创建Compass接口。&#160;&#160;&#160; Compass(类似Hibernate SessionFactory)：为单线程使用，创建线程安全的实例来打开Compass Seesion。同样还提供了一些搜索引擎索引级别的操作。&#160;&#160;&#160; CompassSesssion(类似Hibernate Session)：用来执行像保存、删除、查找、装载这样的搜索操作。很轻量但是并不是线程安全的。&#160;&#160;&#160; CompassTransaction(类似Hibernate Transaction)：管理Compass事务的接口。使用它并不需要事务管理环境（像Spring、JTA）。 1.3、Compass与Spring集成 Compass已经对对spring集成做了很好的封装，同时与Spring对Hibernate的支持类似，Compass也提供了CompassTemplate来简化诸如对Session、Transaction、Exception等操作，尽量充分使用此工具，可以有效提高效率。例如： CompassTemplate ct = (CompassTemplate) [...]]]></description>
			<content:encoded><![CDATA[<p>&nbsp;&nbsp;&nbsp; 在新架构中打算选择Compass或Hibernate Search作为搜索引擎框架，比较后，感觉Hibernate Search上还是没有Compass成熟，另外考虑到后期对网页的爬取及搜索需求，决定还是基于Compass来作为架构缺省的搜索引擎。网上关于Compass的文档很多，但说得相对完整其详细的入门文档基本上没有，Compass的官方文档倒是说得很详细，但是例子一塌糊涂，存在很大问题。记录一下搭建的过程，作为入门的指南。</p>
<p>&nbsp;&nbsp;&nbsp; Compass 通过OSEM(Object/Search Engine Mapping)允许把应用对象的领域模型映射到搜索引擎，最终通过访问common meta data来达到访问对象的目的。</p>
<h3>1、几个核心概念</h3>
<p><strong><font size="2">1.1、annotation vs. xml配置文件</font></strong>
<p>&nbsp;&nbsp; Compass的配置文件主要分成三类：
<p>&nbsp;&nbsp;&nbsp; 第一类：*.cmd.xml文件*
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .cmd.xml文件是对common meta data进行定义，定义了最终搜索的结果中的最基本的元数据。
<p>&nbsp;&nbsp;&nbsp; 第二类：*.cpm.xml文件
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *.cpm.xml是Object/Search Engine Mapping,提供了POJO到common meta data的映射。
<p>&nbsp;&nbsp;&nbsp; 第三类：*.cfg.xml文件
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Compass的*.cfg.xml定义了Compass的Index存放路径、搜索引擎分词等相关信息。
<p>&nbsp;&nbsp;&nbsp; 与采用xml配置文件相比较，采用Annonation方式还是相对简单，尤其是采用Spring时候，不用写*.cmd.xml文件、*.cpm.xml、*.cfg.xml，相对很方便，而且不像Hibernate的Annonation很多，Compass的Annonation的核心标注只有@Searchable、@SearchableId、@SearchableProperty、@SearchableComponent个，很容易记忆。因此推荐使用Annonation方式</p>
<h4><font size="2">１.2、Compass核心API</font></h4>
<p>Compass的核心API借鉴了Hibernate的术语，因此在操作上基本上与Hibernate类似，以下为Compass的几个核心接口： </p>
<p>&nbsp;&nbsp;&nbsp; CompassConfiguration(类似Hibernate Configuration)：用来在一些设置参数、配置文件和映射定义上配置Compass。通常用来创建Compass接口。<br />&nbsp;&nbsp;&nbsp; Compass(类似Hibernate SessionFactory)：为单线程使用，创建线程安全的实例来打开Compass Seesion。同样还提供了一些搜索引擎索引级别的操作。<br />&nbsp;&nbsp;&nbsp; CompassSesssion(类似Hibernate Session)：用来执行像保存、删除、查找、装载这样的搜索操作。很轻量但是并不是线程安全的。<br />&nbsp;&nbsp;&nbsp; CompassTransaction(类似Hibernate Transaction)：管理Compass事务的接口。使用它并不需要事务管理环境（像Spring、JTA）。
<p><strong><font size="2">1.3、Compass与Spring集成</font></strong>
<p>Compass已经对对spring集成做了很好的封装，同时与Spring对Hibernate的支持类似，Compass也提供了CompassTemplate来简化诸如对Session、Transaction、Exception等操作，尽量充分使用此工具，可以有效提高效率。例如：
<p>CompassTemplate ct = (CompassTemplate) context.getBean(&#8220;compassTemplate&#8221;);
<p>Article article = new Article();<br />article.setTitle(&#8220;Compass Test&#8221;);<br />article.setPublishDate(new Date());<br />article.setAuthor(1);
<p>ct.save(article); //存储对象需要索引的数据到Compass的索引中。
<p>&nbsp;<br />
<h3>2、软件环境</h3>
<p>Spring ：2.5</p>
<p>Compas：1.2.1</p>
<p>Hibernate：3.2.5</p>
<p>Mysql ：5.0.5</p>
<h3>3、数据库脚本</h3>
<pre class="csharpcode"><span class="kwrd">CREATE</span> <span class="kwrd">TABLE</span> `article` ( 

`Id` <span class="kwrd">int</span>(11) <span class="kwrd">NOT</span> <span class="kwrd">NULL</span> auto_increment, 

`title` <span class="kwrd">varchar</span>(40) <span class="kwrd">NOT</span> <span class="kwrd">NULL</span> <span class="kwrd">default</span> <span class="str">''</span>, 

`author` <span class="kwrd">int</span>(11) <span class="kwrd">default</span> <span class="str">'0'</span>, 

`publish_date` <span class="kwrd">date</span> <span class="kwrd">NOT</span> <span class="kwrd">NULL</span> <span class="kwrd">default</span> <span class="str">'0000-00-00'</span>, 

<span class="kwrd">PRIMARY</span> <span class="kwrd">KEY</span> (`Id`) ) TYPE=MyISAM; 

<span class="kwrd">CREATE</span> <span class="kwrd">TABLE</span> `author` ( 

`Id` <span class="kwrd">int</span>(11) <span class="kwrd">NOT</span> <span class="kwrd">NULL</span> auto_increment, 

`username` <span class="kwrd">varchar</span>(20) <span class="kwrd">NOT</span> <span class="kwrd">NULL</span> <span class="kwrd">default</span> <span class="str">''</span>, 

`password` <span class="kwrd">varchar</span>(20) <span class="kwrd">NOT</span> <span class="kwrd">NULL</span> <span class="kwrd">default</span> <span class="str">''</span>, 

`age` <span class="kwrd">smallint</span>(6) <span class="kwrd">default</span> <span class="str">'0'</span>, 

<span class="kwrd">PRIMARY</span> <span class="kwrd">KEY</span> (`Id`) ) TYPE=MyISAM; </pre>
<h3>4、测试用例</h3>
<p>从测试用例讲起比较容易把关系理清楚，不然一堆术语和概念很让人晕乎。</p>
<pre class="csharpcode">import org.apache.log4j.Logger;
import java.util.Date;

import junit.framework.TestCase;

import org.compass.core.Compass;
import org.compass.core.CompassDetachedHits;
import org.compass.core.CompassHit;
import org.compass.core.CompassHits;
import org.compass.core.CompassSession;
import org.compass.core.CompassTemplate;
import org.compass.core.CompassTransaction;
import org.compass.core.support.search.CompassSearchCommand;
import org.compass.core.support.search.CompassSearchResults;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.mobilesoft.esales.dao.hibernate.ArticleDAO;
import com.mobilesoft.esales.dao.hibernate.AuthorDAO;
import com.mobilesoft.esales.model.Article;
import com.mobilesoft.esales.model.Author;
import com.mobilesoft.framework.search.service.CompassSearchService;

<span class="rem">/**</span>
<span class="rem"> * Compass服务使用的测试用例</span>
<span class="rem"> * </span>
<span class="rem"> * @author liangchuan@mobile-soft.cn</span>
<span class="rem"> * </span>
<span class="rem"> */</span>

<span class="kwrd">public</span> <span class="kwrd">class</span> TestCompass extends TestCase {

    <span class="kwrd">private</span> <span class="kwrd">static</span> final Logger logger = Logger.getLogger(TestCompass.<span class="kwrd">class</span>);

    <span class="kwrd">private</span> <span class="kwrd">static</span> ClassPathXmlApplicationContext context = <span class="kwrd">null</span>;
    <span class="kwrd">private</span> <span class="kwrd">static</span> CompassTemplate ct;

    <span class="kwrd">static</span> {
        context = <span class="kwrd">new</span> ClassPathXmlApplicationContext(<span class="kwrd">new</span> String[] {
                <span class="str">"applicationContext.xml"</span>, <span class="str">"applicationContext-resources.xml"</span>,
                <span class="str">"applicationContext-dao.xml"</span>, <span class="str">"applicationContext-service.xml"</span>,
                <span class="str">"applicationContext-compass.xml"</span> });
        ct = (CompassTemplate) context.getBean(<span class="str">"compassTemplate"</span>);
    }

    <span class="kwrd">protected</span> <span class="kwrd">void</span> setUp() throws Exception {

    }

    <span class="rem">/**</span>
<span class="rem">     * 插入测试数据</span>
<span class="rem">     */</span>
    <span class="kwrd">public</span> <span class="kwrd">void</span> testInsert() {

        ArticleDAO articleDao = (ArticleDAO) context.getBean(<span class="str">"articleDAO"</span>);
        AuthorDAO authorDao = (AuthorDAO) context.getBean(<span class="str">"authorDAO"</span>);
        Article article = <span class="kwrd">new</span> Article();
        Author author = <span class="kwrd">new</span> Author();
        author.setAge((<span class="kwrd">short</span>) 27);
        author.setUsername(<span class="str">"liangchuan"</span>);
        author.setPassword(<span class="str">"liangchuan"</span>);
        article.setTitle(<span class="str">"Compass Test"</span>);
        article.setPublishDate(<span class="kwrd">new</span> Date());
        article.setAuthor(1);
        authorDao.save(author);
        articleDao.save(article);
        ct.save(article);
        ct.save(author);
    }

    <span class="rem">/**</span>
<span class="rem">     * 用于测试使用CompassTransaction事务方式</span>
<span class="rem">     */</span>
    <span class="kwrd">public</span> <span class="kwrd">void</span> testTransactionalFind() {

        Compass compass = ct.getCompass();
        CompassSession session = compass.openSession();
        CompassTransaction tx = <span class="kwrd">null</span>;
        <span class="kwrd">try</span> {
            tx = session.beginTransaction();
            CompassHits hits = session.find(<span class="str">"Compass*"</span>);

            logger.error(<span class="str">"testTransactionalFind() - CompassHits hits="</span>
                    + hits.getLength());
            <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; hits.getLength(); i++) {
                Object hit = hits.data(i);
                <span class="kwrd">if</span> (hit instanceof Article) {
                    Article item = (Article) hit;
                    logger.error(<span class="str">"testTransactionalFind() - article     hits="</span>
                            + item.getTitle());
                } <span class="kwrd">else</span> <span class="kwrd">if</span> (hit instanceof Author) {
                    Author item = (Author) hit;
                    logger.error(<span class="str">"testTransactionalFind() - author hits="</span>
                            + item.getUsername());
                } <span class="kwrd">else</span> {
                    logger.error(<span class="str">"testTransactionalFind() - error hits="</span>);
                }
            }
            tx.commit();
        } <span class="kwrd">catch</span> (Exception e) {
            <span class="kwrd">if</span> (tx != <span class="kwrd">null</span>) {
                tx.rollback();
            }
        } <span class="kwrd">finally</span> {
            session.close();
        }
    }

    <span class="rem">/**</span>
<span class="rem">     * 用于演示CompassDetachedHits的使用。</span>
<span class="rem">     * 由于CompassTempalte得到的结果集必须在transactionalcontext中才能使用，</span>
<span class="rem">     * 因此必须使用CompassDetachedHits方式测试CompassDetachedHits方式</span>
<span class="rem">     */</span>
    <span class="kwrd">public</span> <span class="kwrd">void</span> testDetachedFind() {

        <span class="rem">// 由于CompassTempalte得到的结果集必须在transactional</span>
        <span class="rem">// context中才能使用，因此必须使用CompassDetachedHits方式</span>
        <span class="rem">// 测试CompassDetachedHits方式</span>
        CompassDetachedHits hits = ct.findWithDetach(<span class="str">"Compass*"</span>);

        logger.error(<span class="str">"testDetachedFind() - CompassHits hits="</span>
                + hits.getLength());
        <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; hits.getLength(); i++) {
            Object hit = hits.data(i);
            <span class="kwrd">if</span> (hit instanceof Article) {
                Article item = (Article) hit;
                logger.error(<span class="str">"testDetachedFind() - article     hits="</span>
                        + item.getTitle());
            } <span class="kwrd">else</span> <span class="kwrd">if</span> (hit instanceof Author) {
                Author item = (Author) hit;
                logger.error(<span class="str">"testDetachedFind() - author hits="</span>
                        + item.getUsername());
            } <span class="kwrd">else</span> {
                logger.error(<span class="str">"testDetachedFind() - error hits="</span>);
            }
        }

    }

    <span class="rem">/**</span>
<span class="rem">     * 用于演示com.mobilesoft.framework.search.service.CompassSearchService的使用</span>
<span class="rem">     * </span>
<span class="rem">     */</span>
    <span class="kwrd">class</span> CompassSearch extends CompassSearchService{
        CompassSearch(){
            Compass compass = ct.getCompass();
            CompassSession session = compass.openSession();
            CompassTransaction tx = <span class="kwrd">null</span>;

            <span class="kwrd">try</span> {
                tx = session.beginTransaction();
                CompassSearchCommand command = <span class="kwrd">new</span> CompassSearchCommand();
                command.setQuery(<span class="str">"Compass"</span>);
                CompassSearchResults results= performSearch(command,session);
                logger.error(<span class="str">"CompassSearch() - CompassHit TotalHits value="</span> +results.getTotalHits());

                <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; results.getHits().length; i++) {
                    CompassHit hits=results.getHits()[i];
                    Object hit=hits.getData();
                    logger.error(<span class="str">"CompassSearch() - CompassHit hit="</span> + hit); <span class="rem">//$NON-NLS-1$</span>

                    <span class="kwrd">if</span> (hit instanceof Article) {
                        Article item = (Article) hit;
                        logger.error(<span class="str">"testCompassSearchService() - article     hits="</span>
                                + item.getTitle());
                    } <span class="kwrd">else</span> <span class="kwrd">if</span> (hit instanceof Author) {
                        Author item = (Author) hit;
                        logger.error(<span class="str">"testCompassSearchService() - author hits="</span>
                                + item.getUsername());
                    } <span class="kwrd">else</span> {
                        logger.error(<span class="str">"testCompassSearchService() - error hits="</span>);
                    }

                    tx.commit();
                }
            } <span class="kwrd">catch</span> (Exception e) {
                <span class="kwrd">if</span> (tx != <span class="kwrd">null</span>) {
                    tx.rollback();
                }
            } <span class="kwrd">finally</span> {
                session.close();
            }        

        }

    }
    <span class="kwrd">public</span> <span class="kwrd">void</span> testCompassSearchService() {
        <span class="kwrd">new</span> CompassSearch();
        }

    <span class="kwrd">protected</span> <span class="kwrd">void</span> tearDown() throws Exception {
    }
}
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<h4>5、配置文件</h4>
<h4>applicationContext-compass.xml</h4>
<pre class="csharpcode"><span class="kwrd">&lt;?</span><span class="html">xml</span> <span class="attr">version</span><span class="kwrd">="1.0"</span>?<span class="kwrd">&gt;</span>
<span class="kwrd">&lt;!</span><span class="html">DOCTYPE</span> <span class="attr">beans</span> <span class="attr">PUBLIC</span> <span class="kwrd">"-//SPRING//DTD BEAN 2.0//EN"</span>
    <span class="kwrd">"http://www.springframework.org/dtd/spring-beans-2.0.dtd"</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">beans</span> <span class="attr">default-lazy-init</span><span class="kwrd">="true"</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">bean</span> <span class="attr">id</span><span class="kwrd">="compassTemplate"</span> <span class="attr">class</span><span class="kwrd">="org.compass.core.CompassTemplate"</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">property</span> <span class="attr">name</span><span class="kwrd">="compass"</span> <span class="attr">ref</span><span class="kwrd">="compass"</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">bean</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">bean</span> <span class="attr">id</span><span class="kwrd">="annotationConfiguration"</span>
        <span class="attr">class</span><span class="kwrd">="org.compass.annotations.config.CompassAnnotationsConfiguration"</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">bean</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">bean</span> <span class="attr">id</span><span class="kwrd">="compass"</span> <span class="attr">class</span><span class="kwrd">="org.compass.spring.LocalCompassBean"</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">property</span> <span class="attr">name</span><span class="kwrd">="classMappings"</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;</span><span class="html">list</span><span class="kwrd">&gt;</span>
                <span class="kwrd">&lt;</span><span class="html">value</span><span class="kwrd">&gt;</span>com.mobilesoft.esales.model.Article<span class="kwrd">&lt;/</span><span class="html">value</span><span class="kwrd">&gt;</span>
                <span class="kwrd">&lt;</span><span class="html">value</span><span class="kwrd">&gt;</span>com.mobilesoft.esales.model.Author<span class="kwrd">&lt;/</span><span class="html">value</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;/</span><span class="html">list</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;/</span><span class="html">property</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">property</span> <span class="attr">name</span><span class="kwrd">="compassConfiguration"</span> <span class="attr">ref</span><span class="kwrd">="annotationConfiguration"</span><span class="kwrd">/&gt;</span>

        <span class="kwrd">&lt;</span><span class="html">property</span> <span class="attr">name</span><span class="kwrd">="compassSettings"</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;</span><span class="html">props</span><span class="kwrd">&gt;</span>
                <span class="kwrd">&lt;</span><span class="html">prop</span> <span class="attr">key</span><span class="kwrd">="compass.engine.connection"</span><span class="kwrd">&gt;</span> file://compass <span class="kwrd">&lt;/</span><span class="html">prop</span><span class="kwrd">&gt;</span>
                <span class="kwrd">&lt;</span><span class="html">prop</span> <span class="attr">key</span><span class="kwrd">="compass.transaction.factory"</span><span class="kwrd">&gt;</span>
                    org.compass.spring.transaction.SpringSyncTransactionFactory
                    <span class="kwrd">&lt;/</span><span class="html">prop</span><span class="kwrd">&gt;</span>
                <span class="kwrd">&lt;</span><span class="html">prop</span>
                    <span class="attr">key</span><span class="kwrd">="compass.engine.highlighter.default.formatter.simple.pre"</span><span class="kwrd">&gt;</span>
                    <span class="kwrd">&lt;!</span>[CDATA[<span class="kwrd">&lt;</span><span class="html">font</span> <span class="attr">color</span><span class="kwrd">="red"</span><span class="kwrd">&gt;&lt;</span><span class="html">b</span><span class="kwrd">&gt;</span>]]<span class="kwrd">&gt;</span>
                <span class="kwrd">&lt;/</span><span class="html">prop</span><span class="kwrd">&gt;</span>
                <span class="kwrd">&lt;</span><span class="html">prop</span>
                    <span class="attr">key</span><span class="kwrd">="compass.engine.highlighter.default.formatter.simple.post"</span><span class="kwrd">&gt;</span>
                    <span class="kwrd">&lt;!</span>[CDATA[<span class="kwrd">&lt;/</span><span class="html">b</span><span class="kwrd">&gt;&lt;/</span><span class="html">font</span><span class="kwrd">&gt;</span>]]<span class="kwrd">&gt;</span>
                <span class="kwrd">&lt;/</span><span class="html">prop</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;/</span><span class="html">props</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;/</span><span class="html">property</span><span class="kwrd">&gt;</span>

        <span class="kwrd">&lt;</span><span class="html">property</span> <span class="attr">name</span><span class="kwrd">="transactionManager"</span> <span class="attr">ref</span><span class="kwrd">="transactionManager"</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">bean</span><span class="kwrd">&gt;</span>

    <span class="kwrd">&lt;</span><span class="html">bean</span> <span class="attr">id</span><span class="kwrd">="hibernateGpsDevice"</span>
        <span class="attr">class</span><span class="kwrd">="org.compass.gps.device.hibernate.HibernateGpsDevice"</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">property</span> <span class="attr">name</span><span class="kwrd">="name"</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;</span><span class="html">value</span><span class="kwrd">&gt;</span>hibernateDevice<span class="kwrd">&lt;/</span><span class="html">value</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;/</span><span class="html">property</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">property</span> <span class="attr">name</span><span class="kwrd">="sessionFactory"</span> <span class="attr">ref</span><span class="kwrd">="sessionFactory"</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">property</span> <span class="attr">name</span><span class="kwrd">="mirrorDataChanges"</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;</span><span class="html">value</span><span class="kwrd">&gt;</span>true<span class="kwrd">&lt;/</span><span class="html">value</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;/</span><span class="html">property</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">bean</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">bean</span> <span class="attr">id</span><span class="kwrd">="compassGps"</span> <span class="attr">class</span><span class="kwrd">="org.compass.gps.impl.SingleCompassGps"</span>
        <span class="attr">init-method</span><span class="kwrd">="start"</span> <span class="attr">destroy-method</span><span class="kwrd">="stop"</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">property</span> <span class="attr">name</span><span class="kwrd">="compass"</span> <span class="attr">ref</span><span class="kwrd">="compass"</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">property</span> <span class="attr">name</span><span class="kwrd">="gpsDevices"</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;</span><span class="html">list</span><span class="kwrd">&gt;</span>
                <span class="kwrd">&lt;</span><span class="html">bean</span>
                    <span class="attr">class</span><span class="kwrd">="org.compass.spring.device.SpringSyncTransactionGpsDeviceWrapper"</span><span class="kwrd">&gt;</span>
                    <span class="kwrd">&lt;</span><span class="html">property</span> <span class="attr">name</span><span class="kwrd">="gpsDevice"</span> <span class="attr">ref</span><span class="kwrd">="hibernateGpsDevice"</span><span class="kwrd">/&gt;</span>
                <span class="kwrd">&lt;/</span><span class="html">bean</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;/</span><span class="html">list</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;/</span><span class="html">property</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">bean</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">bean</span> <span class="attr">id</span><span class="kwrd">="compassSearchService"</span> <span class="attr">class</span><span class="kwrd">="com.mobilesoft.framework.search.service.CompassSearchService"</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">property</span> <span class="attr">name</span><span class="kwrd">="compass"</span> <span class="attr">ref</span><span class="kwrd">="compass"</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">property</span> <span class="attr">name</span><span class="kwrd">="pageSize"</span> <span class="attr">value</span><span class="kwrd">="15"</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">bean</span><span class="kwrd">&gt;</span>

    <span class="rem">&lt;!-- 定时重建索引(利用quartz)或随Spring ApplicationContext启动而重建索引 --&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">bean</span> <span class="attr">id</span><span class="kwrd">="compassIndexBuilder"</span> <span class="attr">class</span><span class="kwrd">="com.mobilesoft.framework.search.service.CompassIndexBuilder"</span> <span class="attr">lazy-init</span><span class="kwrd">="false"</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">property</span> <span class="attr">name</span><span class="kwrd">="compassGps"</span> <span class="attr">ref</span><span class="kwrd">="compassGps"</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">property</span> <span class="attr">name</span><span class="kwrd">="buildIndex"</span> <span class="attr">value</span><span class="kwrd">="false"</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">property</span> <span class="attr">name</span><span class="kwrd">="lazyTime"</span> <span class="attr">value</span><span class="kwrd">="10"</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">bean</span><span class="kwrd">&gt;</span>

<span class="kwrd">&lt;/</span><span class="html">beans</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>applicationContext-dao.xml、applicationContext-service.xml、applicationContext-resources.xml等略去。 </p>
<p>&nbsp;<br />
<h3>6、Service层(参考了SpringSide实现)</h3>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>AdvancedSearchCommand.java</p>
<pre class="csharpcode">package com.mobilesoft.framework.search.service;

import java.util.HashSet;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.compass.core.CompassQuery.SortDirection;
import org.compass.core.CompassQuery.SortPropertyType;
import org.compass.core.support.search.CompassSearchCommand;

import org.springframework.util.Assert;

<span class="kwrd">public</span> <span class="kwrd">class</span> AdvancedSearchCommand extends CompassSearchCommand {

    <span class="rem">/**</span>
<span class="rem">     * 封装基于Compass 的排序参数.</span>
<span class="rem">     */</span>
    <span class="kwrd">class</span> CompassSort {

        <span class="kwrd">private</span> String name;

        <span class="kwrd">private</span> SortPropertyType type;

        <span class="kwrd">private</span> SortDirection direction;

        <span class="kwrd">public</span> CompassSort() {
        }

        <span class="kwrd">public</span> CompassSort(String sortParamName, String paramType,
                           boolean isAscend) {
            Assert.isTrue(StringUtils.isNotBlank(sortParamName));
            setName(sortParamName);

            <span class="kwrd">if</span> (<span class="str">"int"</span>.equalsIgnoreCase(paramType)) {
                setType(SortPropertyType.INT);
            } <span class="kwrd">else</span> <span class="kwrd">if</span> (<span class="str">"float"</span>.equalsIgnoreCase(paramType)) {
                setType(SortPropertyType.FLOAT);
            } <span class="kwrd">else</span> <span class="kwrd">if</span> (<span class="str">"string"</span>.equalsIgnoreCase(paramType)) {
                setType(SortPropertyType.STRING);
            } <span class="kwrd">else</span> {
                setType(SortPropertyType.AUTO);
            }

            <span class="kwrd">if</span> (isAscend) {
                setDirection(SortDirection.AUTO);
            } <span class="kwrd">else</span> {
                setDirection(SortDirection.REVERSE);
            }
        }

        <span class="kwrd">public</span> String getName() {
            <span class="kwrd">return</span> name;
        }

        <span class="kwrd">public</span> <span class="kwrd">void</span> setName(String name) {
            <span class="kwrd">this</span>.name = name;
        }

        <span class="kwrd">public</span> SortPropertyType getType() {
            <span class="kwrd">return</span> type;
        }

        <span class="kwrd">public</span> <span class="kwrd">void</span> setType(SortPropertyType type) {
            <span class="kwrd">this</span>.type = type;
        }

        <span class="kwrd">public</span> SortDirection getDirection() {
            <span class="kwrd">return</span> direction;
        }

        <span class="kwrd">public</span> <span class="kwrd">void</span> setDirection(SortDirection direction) {
            <span class="kwrd">this</span>.direction = direction;
        }
    }

    <span class="rem">/**</span>
<span class="rem">     * 搜索结果排序表.</span>
<span class="rem">     */</span>
    <span class="kwrd">private</span> Set&lt;CompassSort&gt; sortMap = <span class="kwrd">new</span> HashSet&lt;CompassSort&gt;();

    <span class="kwrd">private</span> String[] highlightFields;

    <span class="rem">/**</span>
<span class="rem">     * @param paramType 现定义了三种类型： int string 以及 float。&lt;br&gt;</span>
<span class="rem">     *                  除去这三种外，其他会被自动定义为SortPropertyType.AUTO 具体的可见{@link org.compass.core.CompassQuery.SortPropertyType}</span>
<span class="rem">     * @param isAscend  顺序还是倒序排序</span>
<span class="rem">     * @see org.compass.core.CompassQuery.SortPropertyType#AUTO</span>
<span class="rem">     * @see org.compass.core.CompassQuery.SortPropertyType#INT</span>
<span class="rem">     * @see org.compass.core.CompassQuery.SortPropertyType#STRING</span>
<span class="rem">     * @see org.compass.core.CompassQuery.SortPropertyType#FLOAT</span>
<span class="rem">     * @see org.compass.core.CompassQuery.SortDirection#AUTO</span>
<span class="rem">     * @see org.compass.core.CompassQuery.SortDirection#REVERSE</span>
<span class="rem">     */</span>
    <span class="kwrd">public</span> <span class="kwrd">void</span> addSort(String sortParamName, String paramType, boolean isAscend) {
        <span class="kwrd">this</span>.sortMap.add(<span class="kwrd">new</span> CompassSort(sortParamName, paramType, isAscend));
    }

    <span class="kwrd">public</span> Set&lt;CompassSort&gt; getSortMap() {
        <span class="kwrd">return</span> sortMap;
    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> setSortMap(Set&lt;CompassSort&gt; sortMap) {
        <span class="kwrd">this</span>.sortMap = sortMap;
    }

    <span class="kwrd">public</span> String[] getHighlightFields() {
        <span class="kwrd">return</span> highlightFields;
    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> setHighlightFields(String[] highlightFields) {
        <span class="kwrd">this</span>.highlightFields = highlightFields;
    }
}
</pre>
<p>CompassIndexBuilder.java</p>
<pre class="csharpcode">package com.mobilesoft.framework.search.service;

import org.apache.log4j.Logger;
import org.compass.gps.CompassGps;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

<span class="rem">/**</span>
<span class="rem"> * 通过quartz定时调度定时重建索引或自动随Spring ApplicationContext启动而重建索引的Builder.</span>
<span class="rem"> * 会启动后延时数秒新开线程调用compassGps.index()函数.</span>
<span class="rem"> * 默认会在Web应用每次启动时重建索引,可以设置buildIndex属性为false来禁止此功能.</span>
<span class="rem"> * 也可以不用本Builder, 编写手动调用compassGps.index()的代码.</span>
<span class="rem"> *</span>
<span class="rem"> */</span>
<span class="kwrd">public</span> <span class="kwrd">class</span> CompassIndexBuilder implements InitializingBean {

    <span class="kwrd">private</span> <span class="kwrd">static</span> final Logger log = Logger.getLogger(CompassIndexBuilder.<span class="kwrd">class</span>);

    <span class="rem">// 是否需要建立索引，可被设置为false使本Builder失效.</span>
    <span class="kwrd">private</span> boolean buildIndex = <span class="kwrd">false</span>;

    <span class="rem">// 索引操作线程延时启动的时间，单位为秒</span>
    <span class="kwrd">private</span> <span class="kwrd">int</span> lazyTime = 10;

    <span class="rem">// Compass封装</span>
    <span class="kwrd">private</span> CompassGps compassGps;

    <span class="rem">// 索引线程</span>
    <span class="kwrd">private</span> Thread indexThread = <span class="kwrd">new</span> Thread() {

        @Override
        <span class="kwrd">public</span> <span class="kwrd">void</span> run() {
            <span class="kwrd">try</span> {
                Thread.sleep(lazyTime * 1000);

                log.info(<span class="str">"begin compass index..."</span>);
                <span class="kwrd">long</span> beginTime = System.currentTimeMillis();
                <span class="rem">// 重建索引.</span>
                <span class="rem">// 如果compass实体中定义的索引文件已存在，索引过程中会建立临时索引，</span>
                <span class="rem">// 索引完成后再进行覆盖.</span>
                compassGps.index();
                <span class="kwrd">long</span> costTime = System.currentTimeMillis() - beginTime;
                log.info(<span class="str">"compss index finished."</span>);
                log.info(<span class="str">"costed "</span> + costTime + <span class="str">" milliseconds"</span>);
            } <span class="kwrd">catch</span> (InterruptedException e) {
                <span class="rem">// simply proceed</span>
            }
        }
    };

    <span class="rem">/**</span>
<span class="rem">     * 实现&lt;code&gt;InitializingBean&lt;/code&gt;接口，在完成注入后调用启动索引线程.</span>
<span class="rem">     *</span>
<span class="rem">     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()</span>
<span class="rem">     */</span>
    <span class="kwrd">public</span> <span class="kwrd">void</span> afterPropertiesSet() throws Exception {
        <span class="kwrd">if</span> (buildIndex) {
            Assert.notNull(compassGps, <span class="str">"CompassIndexBuilder not set CompassGps yet."</span>);
            indexThread.setDaemon(<span class="kwrd">true</span>);
            indexThread.setName(<span class="str">"Compass Indexer"</span>);
            indexThread.start();
        }
    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> setBuildIndex(boolean buildIndex) {
        <span class="kwrd">this</span>.buildIndex = buildIndex;
    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> setLazyTime(<span class="kwrd">int</span> lazyTime) {
        <span class="kwrd">this</span>.lazyTime = lazyTime;
    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> setCompassGps(CompassGps compassGps) {
        <span class="kwrd">this</span>.compassGps = compassGps;
    }
}
</pre>
<p>CompassSearchService.java</p>
<pre class="csharpcode">package com.mobilesoft.framework.search.service;

import org.compass.core.Compass;
import org.compass.core.CompassCallback;
import org.compass.core.CompassDetachedHits;
import org.compass.core.CompassHits;
import org.compass.core.CompassQuery;
import org.compass.core.CompassSession;
import org.compass.core.CompassTemplate;
import org.compass.core.CompassTransaction;
import org.compass.core.support.search.CompassSearchCommand;
import org.compass.core.support.search.CompassSearchResults;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

import com.mobilesoft.framework.search.service.AdvancedSearchCommand.CompassSort;
<span class="rem">/**</span>
<span class="rem"> * 仿照 {@link org.compass.spring.web.mvc.CompassSearchController}</span>
<span class="rem"> * 中的代码，构建了一个Service，方便不使用Spring MVC </span>
<span class="rem"> *</span>
<span class="rem"> * @see org.compass.spring.web.mvc.CompassSearchController</span>
<span class="rem"> * @see org.compass.spring.web.mvc.AbstractCompassCommandController</span>
<span class="rem"> */</span>
<span class="kwrd">public</span> <span class="kwrd">class</span> CompassSearchService implements InitializingBean {

    <span class="rem">//每页显示的条目数量</span>
    <span class="kwrd">private</span> Integer pageSize = 15;

    <span class="kwrd">private</span> Compass compass;

    <span class="kwrd">private</span> CompassTemplate compassTemplate;

    <span class="rem">/**</span>
<span class="rem">     * 公开的搜索接口，返回匹配的搜索结果，与</span>
<span class="rem">     * {@link org.compass.spring.web.mvc.CompassSearchController#handle(javax.servlet.http.HttpServletRequest,</span>
<span class="rem">     *javax.servlet.http.HttpServletResponse,Object,org.springframework.validation.BindException) 处理相似</span>
<span class="rem">     *</span>
<span class="rem">     * @see org.compass.spring.web.mvc.CompassSearchController#handle(javax.servlet.http.HttpServletRequest,</span>
<span class="rem">     *javax.servlet.http.HttpServletResponse,java.lang.Object,org.springframework.validation.BindException)</span>
<span class="rem">     */</span>
    <span class="kwrd">public</span> CompassSearchResults search(final CompassSearchCommand command) {
        <span class="kwrd">return</span> (CompassSearchResults) getCompassTemplate().execute(
                CompassTransaction.TransactionIsolation.READ_ONLY_READ_COMMITTED, <span class="kwrd">new</span> CompassCallback() {
            <span class="kwrd">public</span> Object doInCompass(CompassSession session) {
                <span class="kwrd">return</span> performSearch(command, session);
            }
        });
    }

    <span class="rem">/**</span>
<span class="rem">     * 通过此方法调用搜索引擎,进行结果匹配搜索.</span>
<span class="rem">     *</span>
<span class="rem">     * @see org.compass.spring.web.mvc.CompassSearchController#performSearch(</span>
<span class="rem">     *org.compass.spring.web.mvc.CompassSearchCommand,org.compass.core.CompassSession)</span>
<span class="rem">     */</span>
    <span class="kwrd">protected</span> CompassSearchResults performSearch(CompassSearchCommand searchCommand, CompassSession session) {
        <span class="kwrd">long</span> time = System.currentTimeMillis();
        CompassQuery query = buildQuery(searchCommand, session);
        CompassHits hits = query.hits();
        CompassDetachedHits detachedHits;
        CompassSearchResults.Page[] pages = <span class="kwrd">null</span>;
        <span class="kwrd">if</span> (pageSize == <span class="kwrd">null</span>) {
            doProcessBeforeDetach(searchCommand, session, hits, -1, -1);
            detachedHits = hits.detach();
        } <span class="kwrd">else</span> {
            <span class="kwrd">int</span> iPageSize = pageSize;
            <span class="kwrd">int</span> page = 0;
            <span class="kwrd">int</span> hitsLength = hits.getLength();
            <span class="kwrd">if</span> (searchCommand.getPage() != <span class="kwrd">null</span>) {
                page = searchCommand.getPage();
            }
            <span class="kwrd">int</span> from = page * iPageSize;

            <span class="kwrd">if</span> (from &gt; hits.getLength()) {

                <span class="rem">// 如果起始的条目大于搜索到的条目</span>
                from = hits.getLength() - iPageSize;
                doProcessBeforeDetach(searchCommand, session, hits, from, hitsLength);
                detachedHits = hits.detach(from, hitsLength);
            } <span class="kwrd">else</span> <span class="kwrd">if</span> ((from + iPageSize) &gt; hitsLength) {

                <span class="rem">// 结束的条目大于搜索到的结果</span>
                doProcessBeforeDetach(searchCommand, session, hits, from, hitsLength);
                detachedHits = hits.detach(from, hitsLength);
            } <span class="kwrd">else</span> {

                <span class="rem">// 中间的页码，直接取出相应的条目</span>
                doProcessBeforeDetach(searchCommand, session, hits, from, iPageSize);
                detachedHits = hits.detach(from, iPageSize);
            }
            doProcessAfterDetach(searchCommand, session, detachedHits);
            <span class="kwrd">int</span> numberOfPages = (<span class="kwrd">int</span>) Math.ceil((<span class="kwrd">float</span>) hitsLength / iPageSize);
            pages = <span class="kwrd">new</span> CompassSearchResults.Page[numberOfPages];
            <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; pages.length; i++) {
                pages[i] = <span class="kwrd">new</span> CompassSearchResults.Page();
                pages[i].setFrom(i * iPageSize + 1);
                pages[i].setSize(iPageSize);
                pages[i].setTo((i + 1) * iPageSize);
                <span class="kwrd">if</span> (from &gt;= (pages[i].getFrom() - 1) &amp;&amp; from &lt; pages[i].getTo()) {
                    pages[i].setSelected(<span class="kwrd">true</span>);
                } <span class="kwrd">else</span> {
                    pages[i].setSelected(<span class="kwrd">false</span>);
                }
            }
            <span class="kwrd">if</span> (numberOfPages &gt; 0) {
                CompassSearchResults.Page lastPage = pages[numberOfPages - 1];
                <span class="kwrd">if</span> (lastPage.getTo() &gt; hitsLength) {
                    lastPage.setSize(hitsLength - lastPage.getFrom());
                    lastPage.setTo(hitsLength);
                }
            }
        }
        time = System.currentTimeMillis() - time;
        CompassSearchResults searchResults = <span class="kwrd">new</span> CompassSearchResults(detachedHits.getHits(), time, pageSize);
        searchResults.setPages(pages);
        <span class="kwrd">return</span> searchResults;
    }

    <span class="rem">/**</span>
<span class="rem">     * 构建Lucene搜索器.</span>
<span class="rem">     */</span>
    <span class="kwrd">protected</span> CompassQuery buildQuery(CompassSearchCommand searchCommand, CompassSession session) {
        CompassQuery query = session.queryBuilder().queryString(searchCommand.getQuery().trim()).toQuery();

        <span class="kwrd">if</span> (AdvancedSearchCommand.<span class="kwrd">class</span>.isAssignableFrom(searchCommand.getClass())) {
            AdvancedSearchCommand advancedSearchCommand = (AdvancedSearchCommand) searchCommand;

            <span class="kwrd">for</span> (CompassSort sort : advancedSearchCommand.getSortMap()) {
                query.addSort(sort.getName(), sort.getType(), sort.getDirection());
            }
        }
        <span class="kwrd">return</span> query;
    }

    <span class="rem">/**</span>
<span class="rem">     * 在detach 之前，可以做一些操作。比如highlighting...</span>
<span class="rem">     *</span>
<span class="rem">     * @param from 需要注意的是，如果pageSize 没有指定，那么这里传入的参数为-1</span>
<span class="rem">     */</span>
    <span class="kwrd">protected</span> <span class="kwrd">void</span> doProcessBeforeDetach(CompassSearchCommand searchCommand, CompassSession session, CompassHits hits,
                                         <span class="kwrd">int</span> from, <span class="kwrd">int</span> size) {
        <span class="kwrd">if</span> (AdvancedSearchCommand.<span class="kwrd">class</span>.isAssignableFrom(searchCommand.getClass())) {
            <span class="kwrd">if</span> (from &lt; 0) {
                from = 0;
                size = hits.getLength();
            }
            String[] highlightFields = ((AdvancedSearchCommand) searchCommand).getHighlightFields();

            <span class="kwrd">if</span> (highlightFields == <span class="kwrd">null</span>) {
                <span class="kwrd">return</span>;
            }

            <span class="rem">// highlight fields</span>
            <span class="kwrd">for</span> (<span class="kwrd">int</span> i = from; i &lt; size; i++) {
                <span class="kwrd">for</span> (String highlightField : highlightFields) {
                    hits.highlighter(i).fragment(highlightField);
                }
            }
        }
    }

    <span class="rem">/**</span>
<span class="rem">     * An option to perform any type of processing before the hits are detached.</span>
<span class="rem">     */</span>
    <span class="kwrd">protected</span> <span class="kwrd">void</span> doProcessAfterDetach(CompassSearchCommand searchCommand, CompassSession session,
                                        CompassDetachedHits hits) {

    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> afterPropertiesSet() throws Exception {
        Assert.notNull(compass, <span class="str">"Must set compass property"</span>);
        <span class="kwrd">this</span>.compassTemplate = <span class="kwrd">new</span> CompassTemplate(compass);
    }

    <span class="kwrd">public</span> Integer getPageSize() {
        <span class="kwrd">return</span> pageSize;
    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> setPageSize(Integer pageSize) {
        <span class="kwrd">this</span>.pageSize = pageSize;
    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> setCompass(Compass compass) {
        <span class="kwrd">this</span>.compass = compass;
    }

    <span class="kwrd">protected</span> CompassTemplate getCompassTemplate() {
        <span class="kwrd">return</span> <span class="kwrd">this</span>.compassTemplate;
    }

}
</pre>
<h3>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>8、Model层</h3>
<p>@SearchableId 声明Document的id列； </p>
<p>@SearchableProperty 声明要索引的field； </p>
<p>@SearchableComponent 声明要索引的其他关联对象。 </p>
<p><strong>Article.java</strong></p>
<pre class="csharpcode">package com.mobilesoft.esales.model;

import java.util.Date;

import org.compass.annotations.Searchable;
import org.compass.annotations.SearchableId;
import org.compass.annotations.SearchableProperty;
import org.compass.core.CompassTemplate;

@Searchable
<span class="kwrd">public</span> <span class="kwrd">class</span> Article  implements java.io.Serializable {

    @SearchableId
    <span class="kwrd">private</span> Integer id;
    @SearchableProperty(name=<span class="str">"title"</span>)
    <span class="kwrd">private</span> String title;
    @SearchableProperty(name=<span class="str">"author"</span>)
    <span class="kwrd">private</span> Integer author;
    @SearchableProperty(name=<span class="str">"publishDate"</span>)
    <span class="kwrd">private</span> Date publishDate;

    <span class="rem">/** default constructor */</span>
    <span class="kwrd">public</span> Article() {
    }

    <span class="rem">/** minimal constructor */</span>
    <span class="kwrd">public</span> Article(String title, Date publishDate) {
        <span class="kwrd">this</span>.title = title;
        <span class="kwrd">this</span>.publishDate = publishDate;
    }

    <span class="rem">/** full constructor */</span>
    <span class="kwrd">public</span> Article(String title, Integer author, Date publishDate) {
        <span class="kwrd">this</span>.title = title;
        <span class="kwrd">this</span>.author = author;
        <span class="kwrd">this</span>.publishDate = publishDate;
    }

    <span class="kwrd">public</span> Integer getId() {
        <span class="kwrd">return</span> <span class="kwrd">this</span>.id;
    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> setId(Integer id) {
        <span class="kwrd">this</span>.id = id;
    }

    <span class="kwrd">public</span> String getTitle() {
        <span class="kwrd">return</span> <span class="kwrd">this</span>.title;
    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> setTitle(String title) {
        <span class="kwrd">this</span>.title = title;
    }

    <span class="kwrd">public</span> Integer getAuthor() {
        <span class="kwrd">return</span> <span class="kwrd">this</span>.author;
    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> setAuthor(Integer author) {
        <span class="kwrd">this</span>.author = author;
    }

    <span class="kwrd">public</span> Date getPublishDate() {
        <span class="kwrd">return</span> <span class="kwrd">this</span>.publishDate;
    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> setPublishDate(Date publishDate) {
        <span class="kwrd">this</span>.publishDate = publishDate;
    }

}
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p><strong>Author.java</strong></p>
<pre class="csharpcode">package com.mobilesoft.esales.model;

import org.compass.annotations.Searchable;
import org.compass.annotations.SearchableId;
import org.compass.annotations.SearchableProperty;
import org.compass.core.CompassTemplate;

@Searchable
<span class="kwrd">public</span> <span class="kwrd">class</span> Author  implements java.io.Serializable {

    @SearchableId
    <span class="kwrd">private</span> Integer id;
    @SearchableProperty(name=<span class="str">"username"</span>)
    <span class="kwrd">private</span> String username;
    <span class="kwrd">private</span> String password;
    @SearchableProperty(name=<span class="str">"age"</span>)
    <span class="kwrd">private</span> Short age;

    <span class="kwrd">public</span> Author() {
    }

    <span class="rem">/** minimal constructor */</span>
    <span class="kwrd">public</span> Author(String username, String password) {
        <span class="kwrd">this</span>.username = username;
        <span class="kwrd">this</span>.password = password;
    }

    <span class="rem">/** full constructor */</span>
    <span class="kwrd">public</span> Author(String username, String password, Short age) {
        <span class="kwrd">this</span>.username = username;
        <span class="kwrd">this</span>.password = password;
        <span class="kwrd">this</span>.age = age;
    }

    <span class="rem">// Property accessors</span>

    <span class="kwrd">public</span> Integer getId() {
        <span class="kwrd">return</span> <span class="kwrd">this</span>.id;
    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> setId(Integer id) {
        <span class="kwrd">this</span>.id = id;
    }

    <span class="kwrd">public</span> String getUsername() {
        <span class="kwrd">return</span> <span class="kwrd">this</span>.username;
    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> setUsername(String username) {
        <span class="kwrd">this</span>.username = username;
    }

    <span class="kwrd">public</span> String getPassword() {
        <span class="kwrd">return</span> <span class="kwrd">this</span>.password;
    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> setPassword(String password) {
        <span class="kwrd">this</span>.password = password;
    }

    <span class="kwrd">public</span> Short getAge() {
        <span class="kwrd">return</span> <span class="kwrd">this</span>.age;
    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> setAge(Short age) {
        <span class="kwrd">this</span>.age = age;
    }

}
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<h3>9、DAO层</h3>
<p>ArticleDAO.java和AuthorDAO.java省略</p>
<p>直接用MyEclipse生成的，没有什么特别的。</p>
<h3>10、参考文档</h3>
<p><a title="http://www.compass-project.org/docs/1.2.1/reference/html/" href="http://www.compass-project.org/docs/1.2.1/reference/html/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.compass-project.org/docs/1.2.1/reference/html/');">http://www.compass-project.org/docs/1.2.1/reference/html/</a></p>
<p><a title="http://www.nljug.org/pages/events/content/jfall_2006/sessions/00015/slides/" href="http://www.nljug.org/pages/events/content/jfall_2006/sessions/00015/slides/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.nljug.org/pages/events/content/jfall_2006/sessions/00015/slides/');">The Compass Framework Search made easy.pdf</a></p>
<p><a title="https://compass.dev.java.net/files/documents/4669/36943/file_36943.dat?filename=Compass%20TSSJS%20Europe%20%30%36%2epdf" href="https://compass.dev.java.net/files/documents/4669/36943/file_36943.dat?filename=Compass%20TSSJS%20Europe%20%30%36%2epdf" onclick="javascript:pageTracker._trackPageview('/outbound/article/https://compass.dev.java.net/files/documents/4669/36943/file_36943.dat?filename=Compass%20TSSJS%20Europe%20%30%36%2epdf');">Compass TSSJS Europe 06.pdf</a></p>
<p><a title="http://www.geocities.com/sja085/community/tutorials/compass/compass01/" href="http://www.geocities.com/sja085/community/tutorials/compass/compass01/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.geocities.com/sja085/community/tutorials/compass/compass01/');">Hello World Tutorial</a></p>
<p><a href="http://www.infoq.com/articles/compass-search-tutorial" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.infoq.com/articles/compass-search-tutorial');">InfoQ:&nbsp; Compass: Integrate Search into your apps</a></p>
<p><a href="http://www.infoq.com/news/compass-11" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.infoq.com/news/compass-11');">InfoQ: Compass: Simplifying and Extending Lucene to Provide Google-like Search</a></p>
<p><a href="http://www.infoq.com/cn/articles/compass-search-tutorial" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.infoq.com/cn/articles/compass-search-tutorial');">InfoQ: Compass: 在你的应用中集成搜索功能</a></p>
<p><a href="http://wiki.springside.org.cn/display/springside/Compass" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://wiki.springside.org.cn/display/springside/Compass');">Compass 指南</a></p>
<p><a title="http://www.kimchy.org/" href="http://www.kimchy.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.kimchy.org/');">http://www.kimchy.org/</a></p>
<p>&nbsp;</p>
<div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:4796c142-0224-42c8-9c30-9dc055be1dce" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati 标签: <a href="http://technorati.com/tags/compass" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/tags/compass');" rel="tag">compass</a>,<a href="http://technorati.com/tags/lucene" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/tags/lucene');" rel="tag">lucene</a>,<a href="http://technorati.com/tags/spring" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/tags/spring');" rel="tag">spring</a>,<a href="http://technorati.com/tags/hibernate" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/tags/hibernate');" rel="tag">hibernate</a>,<a href="http://technorati.com/tags/%e6%90%9c%e7%b4%a2%e5%bc%95%e6%93%8e" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://technorati.com/tags/%e6%90%9c%e7%b4%a2%e5%bc%95%e6%93%8e');" rel="tag">搜索引擎</a></div>
	<p></p>
	<hr noshade style="margin:0;height:1px" />
	<p>&copy; chuanliang for <a href="http://www.yeeach.com" >出家如初，成佛有余</a>, 2008. |
	  <a href="http://www.yeeach.com/2008/03/23/compass-%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/" >Permalink</a> |
	  <a href="http://www.yeeach.com/2008/03/23/compass-%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/#comments" >No comment</a></p>
	<p>Add to <a href="http://del.icio.us/post?url=http://www.yeeach.com/2008/03/23/compass-%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/&amp;title=Compass 入门指南" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://del.icio.us/post?url=http://www.yeeach.com/2008/03/23/compass-%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/&amp;title=Compass 入门指南');">del.icio.us</a></p>
	<p>Search blogs linking this post with <a href="http://www.technorati.com/search/http://www.yeeach.com/2008/03/23/compass-%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.technorati.com/search/http://www.yeeach.com/2008/03/23/compass-%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/');" title="Search on Technorati">Technorati</a></p>
	<p>Want more on these topics ? Browse the archive of posts filed under <a href="http://www.yeeach.com/category/%e6%8a%80%e6%9c%af-%e8%bd%af%e4%bb%b6/"  title="查看 技术相关 的全部文章" rel="category tag">技术相关</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.yeeach.com/2008/03/23/compass-%e5%85%a5%e9%97%a8%e6%8c%87%e5%8d%97/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
