在目前的生产过程中全文检索技术应用越来越广,其中涌现了一批非常好得开源搜索引擎框架,如solr,elasticsearch等等。其中我工作使用最多的是solr,并在此对之前工作做一个总结。
solr的索引添加:这里我是直接使用solrj对solr进行操作的,基本流程如下:
一、简单描述
1、对需要建索引的数据库表给一个索引建立与否的标记字段
2、数据库方面使用mybatis + spring 对表进行查询操作,通过分页查询和标记字段判断,查询出数据
3、将查询的数据用solrj 添加到 solr服务之中
4、判断生成索引成功之后将数据库标记更改
二、详细流程
数据库标记字段
查询数据库sql:(很简单)
<select id="selectByHaveIndex" resultMap="opinionNewsMapper">
select * from where iHaveIndexedOneWord= 0
<if test="rows>0">
limit #{beginIndex},#{rows}
</if>
</select>
查询后的数据处理后向solr建立索引
@Override
public boolean createIndexList(List<WebChatNews> list, String tablename) {
List<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
for (WebChatNews webChatNews : list) {
webChatNews.setTablename(tablename);
SolrInputDocument doc = parseWebChatNews(webChatNews);
docs.add(doc);
}
try {
solrTermClient.add(docs);
UpdateRequest req = new UpdateRequest();
req.add(docs);
req.setCommitWithin(10000); //这里是设置的批量提交量
req.process(solrTermClient);
} catch (Exception e) {
Logginfo.saveLog(Logginfo.createFile(), "solr.SolrIndexExstablishImpl","createIndexList", "创建索引异常", 1, true);
e.printStackTrace();
}
return true;
}
@Override
public SolrInputDocument parseWebChatNews(WebChatNews webChatNews) {
SolrInputDocument doc = new SolrInputDocument();
SpiderBizTable spiderBizTable = webChatNews.getSpiderBizTable();
doc.addField("id", webChatNews.getsId());
return doc;
}
然后成功之后修改数据库标记即可
在创建索引的时候我们需要把数据库的需要建立索引的字段添加solr的SolrInputDocument 的filed字段里面如:
SolrInputDocument doc = new SolrInputDocument();
//把新闻中的sId放到id里面
doc.addField("id", webChatNews.getsId());
。。。
当然这远远还不够,光这样我们的solr服务器怎么知道去对应这些字段呢,因此我们要去solr的solr_home的conf目录下去配置managed-schema :
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
。。。以此类推每增加一个索引就要在这里去配置一个field name就是 doc.addField的里面的key
<uniqueKey>id</uniqueKey> 这个配置意思把id设置为唯一的主键
sql如下:
<update id="creatIndexBatch" parameterType="QueryList" >
update tablename set
iHaveIndex = 1
where sId in
<foreach item="item" index="index" collection="array"
open="(" separator="," close=")">
#{item}
</foreach>
</update>
这样批量修改效率会高很多;以上任务用定时任务去调用即可,定时任务用spring自带的定时任务,然后项目就跑起来了,再通过一些配置和数据库可以对solr的索引进行管理即可。
以上是对solr的增量索引的操作,当然也可以用solr自带的jar包实现增量索引也可以。
solr的更新其实就是添加索引操作,主要是保证索引的主键不变,插入一条索引会自动去更新已有主键的索引。
索引删除:
@Override
public boolean deleteAll() {
try {
solrClient.deleteByQuery("*:*");
solrClient.commit();
} catch (Exception e) {
Logginfo.saveLog(Logginfo.createFile(), "solr.SolrIndexExstablishImpl","deleteAll", "删除索引失败", 1, true);
e.printStackTrace();
}
return true;
}
@Override
public boolean deleteIndexList(List<OpinionNews> list,String tablename) {
String keyWords = null;
List<String> ids = new ArrayList<>();
for (OpinionNews opinionNews : list) {
String sId = opinionNews.getsId();
ids.add(sId);
}
keyWords = "tablename:"+tablename ;
try {
solrClient.deleteById(ids);
solrClient.commit();
} catch (Exception e) {
Logginfo.saveLog(Logginfo.createFile(), "solr.SolrIndexExstablishImpl","deleteIndexList", "批量删除索引失败", 1, true);
e.printStackTrace();
}
return true;
}
@Override
public boolean deleIndexByIds(List<String> ids){
try {
solrClient.deleteById(ids);
solrClient.commit();
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
每次对数据库的数据操作一次就要对索引进行一次操作,如果要重建索引只需要把索引创建标记改为初始值即可,这要一套自动建立索引的系统就建立好了,查询的操作,solrj也提供了非常全面的api,当然你也可以用http请求去调用solr页面上的接口,方法很多,当然如果要考虑调用的效率,如果是用java去调用最好还是用solrj,效率更高也更好操作。