最近在用elasticSearch做全文检索工作,但是项目中使用的jdk为1.7,所以选用了2.3.5版本的elasticSearch,网上的资料大都很乱,所以抽出时间来写一篇详细一点的,如果你的情况和我一样,希望能帮助到你,不建议直接复制,下面的代码由于环境原因并不是从IDE复制而来,很多都是手打,容易出错。本项目用到的资源elasticSearch2.3.5+对应版本的ik分词器+gson的jar包。如果转载本文,请注明出处。
1.安装elasticSearch
去官网下载当然是最好的,也可以到文章末尾地址下载,下载完直接解压到某个目录中,进入bin目录下双击bat文件开启服务,然后在浏览器中输入
http://localhost:9200可以看到以下页面:
如果想要看到更直观的页面,可以添加head插件,在cmd中进入到bin目录下,输入
plugin install mobz/elasticsearch-head命令(好像是这个︿( ̄︶ ̄)︿忘了)。输入http://localhost:9200/_plugin/head/可以看到如下的图:
这样可以直观的看到自己加入了哪些索引,索引的内容是什么。好了,安装成功后我们便开始集成到项目中去。
2.elasticSearch的创建连接
我这连接的是集群里一个elasticSearch,ip是172.24.5.33,你可以修改成localhost。代码如下:
public Client createClient() throws UnknowHostException{
Client client = TransportClient.builder().build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("172.24.5.33"), 9300));
client.close();
}
如果你和我一样是连接其他ip的服务器,需要修改config文件下elasticsearch.yml文件。如下图:
3.elasticSearch创建索引
这里拿一个实体类来说明,contentExt实体类代表的是一篇文章,拿一些出来举例
public class ContentExt implements Serializable{
private Integer id;
private String title;//文章的标题
private String description;//文章的摘要
private String author;//文章的作者
private Integer contentId;//文章内容的ID
.....
}
接着我们为contentExt实体类创建索引,所采用的Gson包可以去官网下载,也可以到文章末尾地址下载。当然也可以使用其他的方式转换成Json格式
public void indexCreate(Client client,ContentExt contentExt){
String s = new Gson().toJson(contentExt);//elasticsearch服务器中保存的是json格式,我们使用Google的Gson包来帮助我们将实体类转为json格式
IndexResponse res = null;
res = client.prepareIndex("index","type").setSource(s).execute.actionGet();//这里的index和type是索引名和类型名,可以自己定义
client.close();
}
index表示的是索引名称,相当于数据库的库,type表示的是索引类型,相当于数据库的表。
4.elasticSearch删除索引
这里我们是根据contentExt中文章内容的id:contentId这个字段来查询删除的,我们在删除时不会知道某个索引的ID,我们只知道需要删除的是某篇文章,并将这一篇文章的一个字段作为条件来删除。我们这里选用contentId。
public void indexDelete(Client client, String contentId){
BulkRequestBuilder bulkRequestBuilder = client.prepareBulk();
SearchRequestBuilder searchRequestBuilder = client.prepareSearch("index").setTypes("type");
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
queryBuilder.must(QueryBuilders.termQuery("contentId",contentId));
searchRequestBuilder.setQuery(queryBuilder);
SearchResponse response = searchRequestBuilder.execute().get();
for(SearchHit hit : response.getHits()){
String id = hit.getId();
bulkRequest.add(client.prepareDelete("index", "type", id).request());
}
BulkResponse bulkResponse = bulkRequestBuilder.get();
if (bulkResponse.hasFailures()) {
for(BulkItemResponse item : bulkResponse.getItems()){
System.out.println(item.getFailureMessage());
}
}else {
System.out.println("delete ok");
}
client.close();
}
5.elasticSearch更新索引
更新与删除很像,不同的是传入的并不是一个字段,而是整个实体类。
public void indexDelete(Client client, ContentExt contentExt){
String s = new Gson().toJson(contentExt);
BulkRequestBuilder bulkRequestBuilder = client.prepareBulk();
SearchRequestBuilder searchRequestBuilder = client.prepareSearch("index").setTypes("type");
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
queryBuilder.must(QueryBuilders.termQuery("contentId",contentExt.getContentId().toString()));
searchRequestBuilder.setQuery(queryBuilder);
SearchResponse response = searchRequestBuilder.execute().get();
for(SearchHit hit : response.getHits()){
String id = hit.getId();
bulkRequest.add(client.prepareUpdate("index", "type", id).setDoc(s));
}
BulkResponse bulkResponse = bulkRequestBuilder.get();
if (bulkResponse.hasFailures()) {
for(BulkItemResponse item : bulkResponse.getItems()){
System.out.println(item.getFailureMessage());
}
}else {
System.out.println("delete ok");
}
client.close();
}
6.elasticSearch的查询
查询是elasticsearch的关键,是最难的地方,也是变化最多和需求最不同的,我只能拿自己的出来给大家做个参考。
public ModelMap matchQuery(Client client, String query, int offset, int limit){// offset,limit为起始量和偏移量,是分页用的
SearchResponse res = null;
QueryBuilder qb = QueryBuilders.queryStringQuery(query);
res = client.prepareSearch("index")
.setTypes("type")
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)//精确查询
.setQuery(qb)
.setFrom(offset)
.setSize(limit)
.setHighlighterPreTags("<span style=\"color:red\">")//将查询出来的字设置为高亮显示
.setHighlighterPostTags("</span>")
.setHighlightedField("*")
.setHighlighterRequireFieldMatch(flase)
.addSort("contentId", SortOrder.DESC)//将内容根据ID倒排
.execute().actionGet();
long length = res.getHits().getTotalHits();//将查询的总数也返回
List<ContentExt> list = new ArrayList<>();
Gson gson = new Gson();
for(SearchHit hit : res.getHits().getHits()){
Map<String, Object> source = hit.getSource();
Map<String HighlightField> highlightField = hit.getHighlightFields();
HighlightField titleField = highlightField.get("title");//将标题设置为高亮字段
HighlightField descField = highlightField.get("description");//将描述设置为高亮字段
if(titleField != null){
Text[] fragments = titleField.fragments();
String nameTmp = "";
for(Text text:fragments){
nameTmp+=text;
}
source.put("title", nameTmp);
}
if(descField != null){
Text[] fragments = descField.fragments();
String nameTmp = "";
for(Text text:fragments){
nameTmp+=text;
}
source.put("description", nameTmp);
}
ContentExt contentExt = gson.fromJson(gson.toJson(source), ContentExt.class);
list.add(contentExt);
}
client.close();
ModelMap modelMap = new ModelMap();
modelMap.addAttribute("count", length);
modelMap.addAttribute("list", list);
modelMap.addAttribute("keywords", query);
return modelMap;
}
以下是elasticsearch2.3.5和Gson包和该版本对应的ik分词器的下载链接,如果你不愿去官网找的话。
https://download.csdn.net/download/qq_39071530/10420311