我们一般浏览的网站都提供搜索功能。有些是搜索数据库,简单但是局限。有些是调用第三方搜索接口 互联网搜索,功能强大。
不管怎么说,都是后台执行数据匹配的搜索。
目前来看,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 字段有长度限制。这要注意下。