我们一般浏览的网站都提供搜索功能。有些是搜索数据库,简单但是局限。有些是调用第三方搜索接口 互联网搜索,功能强大。
不管怎么说,都是后台执行数据匹配的搜索。
目前来看,java全文搜索都是solr,elasticsearch 用得居多。网上传闻Redis-search也可以全文搜索。我大概百度了一下,其实Redis-search 还不成熟。
上个月玩了下solr和elasticsearch.现在总结一下心得。
首先,solr很强大,上手很快。基本上下载,启动。 就可以用了。
elasticsearch 也差不多,只是elasticsearch 没有自带可视化的web管理程序。
solr 什么都可以索引,包括图片,office文档,pdf,xml,txt,json 无所不能。elasticsearch 看上去只接收json 数据。
性能上看,基本都很快。 网上说elasticsearch 接近实时搜索,这个有待论证。
solr 有两种方式去建索引。 一种是dataimport方式。这种方式只需要简单的配置manager-schema.xml 文件即可。
还有一种就是用solr-solrj jar包程序实现。
贴个代码
/** * 索引pdf,word,txt等文档方法 * * @param myFile * -- 文件对象 * @param fileName * -- 文件名 * * @param fileType * --文件类型 * @param otherFields * -- 记录字段Map对象 * * @throws IOException * @throws SolrServerException */ public void indexFiles(File myFile, String fileName, String fileType, String tableName, String uniqueKey, String primaryKeyValue) throws IOException, SolrServerException { ContentStreamUpdateRequest up = new ContentStreamUpdateRequest("/update/extract"); String contentType = ""; if (StringUtil.isEmpty(fileType)) { int dotPosition = fileName.indexOf('.'); String tmpFileType = fileName.substring(dotPosition + 1); contentType = "application/" + tmpFileType; } else { contentType = fileType; } up.addFile(myFile, contentType); ModifiableSolrParams p = new ModifiableSolrParams(); p.add("literal.id", uniqueKey); p.add("literal.doc_id", primaryKeyValue); p.add("literal.doc_table_name", tableName); p.add("literal.doc_type", "file");// 文档类型为文件 p.add("literal.doc_file_name", fileName);// 文档类型为文件 p.add("fmap.content", "doc_content"); p.add("extractFormat", "text"); p.add("captureAttr", "false"); solrClient = SolrClient.getInstance(); up.setParams(p); up.setAction(AbstractUpdateRequest.ACTION.COMMIT, true, true); solrClient.request(up); }
另外,程序建索引也要定义需要索引的字段。比如:
<field name="my_content" type="text_ik" indexed="true" stored="true"/>
定义字段类别,声明使用IKAnalyzer分词分析器(这是支持中文的,需要把对应的jar及配置文件包拷贝到Solr的发布目录)
<fieldType name="text_ik" class="solr.TextField">
<analyzer type="index" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
<analyzer type="query" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
程序查询的使用,需要指定查询字段
if (StringUtils.isEmpty(searchVO.getKeyWord())) { query.setQuery("*:*"); } else { query.setQuery("my_content:" + searchVO.getKeyWord()); } if (StringUtils.isNoneEmpty(searchVO.getNodeCode())) { query.addFilterQuery("my_table_name:" + searchVO.getNodeCode()); }
之前使用*xx*做模糊查询,实际全文搜索不需要。因为搜索引擎已经把大文本内容 分词化了。如果是简单的搜索少量字符串信息。那么用索引字符串类型String即可。没必要用text.
而且用*xx*做模糊查询 查String的字符串更好。但是String 字段有长度限制。这要注意下。