目前搜索分为两种。
一种是sql的搜索,比如like '%abc%'
。这种搜索方式符合大部分人的认知,用这种方式客户一般都不会有什么意见。但这种方式存在一些缺陷,一是很多情况下搜索不到想要的内容,比如搜北京哪家饭店最好吃
,就很难得到想要的结果;二是性能很差,需要全表扫描,如果数据量较大,搜索的用户多一些,搜一次花可能十几秒甚至更长的时间,很多系统会限制使用搜索的频率就是这个原因。
还有一种就是全文检索,例如百度、google、必应。全文检索最大的特点就是性能好,还有就是会对搜索条件进行分词,非常容易找到自己想要的内容。比如搜索this is my book
,会分别搜索this
is
my
book
。但对于中文北京哪家饭店最好吃
就很难分词了,有几个策略。
单字分词。分别搜索北
京
哪
家
饭
店
最
好
吃
,只要出现任何一个字,都会算匹配成功。好处是避免客户说,我搜北京
为什么带北
的内容没搜索出来呀,这个有bug。坏处也非常明显,就是得到的结果太多了。
双字分词。分别搜索北京
京哪
哪家
家饭
饭店
店最
最好
好吃
。缺点也是非常明显的。
中文分词。有专门的词库,比如北京
在词库里,就知道北京
是词,而不会拆成北
京
进行搜索,也就是说,搜索北京
不会搜索单字的北
和京
。同样的搜北
不会搜索出北京
,因为北
是指方向,而北京
是地名,和北
其实没有关系。另外还有停止词,就是很多文章都会出现但没有具体意义的词,如的
在
它
之类的词,会自动忽略这些词,否则搜索好吃的饼干
,只要带的
的内容都搜索出来,那几乎90%的文章都会出现在搜索结果里。
中文分词的缺点是什么呢,可能最大的缺点是大家对这种搜索方式不太习惯,比如客户搜的
然后没有结果;或者搜索年轻漂亮
,结果年轻
和漂亮
的结果都出来了,客户会觉得只有完整的年轻漂亮
才是准确的结果;或者搜索北
而北京
没有被搜出来。
说了这么多理论性的东西,那么这些都在哪里配置呢?在/WEB-INF/classes/custom.xml
。
<!-- 中文智能分词器。使用词库对中文进行分词,可达到较好的分词效果,但对内存的要求也较高,需有200M以上的内存 -->
<bean id="analyzer" class="org.wltea.analyzer.lucene.IKAnalyzer" destroy-method="close">
<!-- false分词粒度最细, true分词粒度较粗。-->
<!-- “一个开源的软件”细粒度分词为: “一个 | 一 | 个 | 开源 | 的 | 软件” -->
<!-- “一个开源的软件”粗粒度分词为: “一个 | 开源 | 的 | 软件” -->
<constructor-arg type="boolean" value="false"/>
</bean>
<!-- 中文双字分词器。所有的中文都按两个字分词。如“我的世界”分词为“我的 | 的世 | 世界” -->
<!--
<bean id="analyzer" class="org.apache.lucene.analysis.cjk.CJKAnalyzer" destroy-method="close">
<constructor-arg><util:constant static-field="org.apache.lucene.util.Version.LUCENE_36"/></constructor-arg>
</bean>
-->
<!-- 中文单字分词器。所有的中文都按两个字分词。如“我的世界”分词为“我 | 的 | 世 | 界” -->
<!--
<bean id="analyzer" class="org.apache.lucene.analysis.standard.StandardAnalyzer" destroy-method="close">
<constructor-arg><util:constant static-field="org.apache.lucene.util.Version.LUCENE_36"/></constructor-arg>
</bean>
-->
全文为检索性能好,可是客户却要sql搜索的效果,那全文检索能不能不分词,实现sql的搜索效果呢?很遗憾,答案是不能。全文检索的核心就是分词,让全文检索不分词就像让燃油发动机不用燃料一样不可能。
系统中使用全文检索的标签是InfoFulltextList和InfoFulltextPage标签。
如果想使用sql的方式搜索,可以使用InfoList和InfoPage标签,使用其中的title
参数,可以对标题进行搜索。由于搜索正文性能太差,该标签不支持对正文sql搜索。