概 述
Elasticsearch 在企业里落地的场景越来越多了,但是大家在项目里使用 Elasticsearch 的姿势也是千奇百怪,这次正好自己需要使用,所以干脆就封装一个 elasticsearch-spring-boot-starter 以供复用好了。如果不知道 spring-boot-starter 该如何制作,可以参考文章《如何自制一个 Spring Boot Starter 并推送到远端公服》,下面就来简述一下自制的 elasticsearch-spring-boot-starter 该如何使用。
依赖引入
<dependency>
<groupId>com.github.hansonwang99</groupId>
<artifactId>elasticsearch-spring-boot-starter</artifactId>
<version>0.0.8</version>
</dependency>
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
配置文件
如果你还没有一个属于自己的 Elasticsearch 集群,可以参考文章《CentOS7 上搭建多节点 Elasticsearch 集群》来一步步搭建之,本文实验所用的集群即来源于此。
elasticsearch:
host: 192.168.31.75
httpPort: 9200
tcpPort: 9300
clusterName: codesheep
docFields: title,filecontent
auth:
enable: false
各个字段解释如下:
host:Elasticsearch 节点地址
httpPort: Elasticsearch REST 端口
tcpPort:Elasticsearch TCP 端口
clusterName:集群名
docFields:文档字段,以英文逗号间隔,比如我这里的业务场景是文档包含 标题(title)和 内容(filecontent)字段
auth:是否需要权限认证
由于我这里安装的实验集群并无 x-pack 权限认证的加持,因此无需权限认证,实际使用的集群或者阿里云上的 Elasticsearch 集群均有完善的 x-pack 权限认证,此时可以加上用户名 / 密码的配置:
elasticsearch:
host: 192.168.199.75
httpPort: 9200
tcpPort: 9300
clusterName: codesheep
docFields: title,filecontent
auth:
enable: true
username: elasticsearch
password: xxxxxx
用法例析
首先注入相关资源
@Autowired
private ISearchService iSearchService;
@Autowired
private DocModel docModel;
这些都是在 elasticsearch-spring-boot-starter 中定义的
创建索引
public String createIndex() throws IOException {
IndexModel indexModel = new IndexModel();
indexModel.setIndexName(“testindex2”); // 注意索引名字必须小写,否则 ES 抛异常
indexModel.setTypeName(“testtype2”);
indexModel.setReplicaNumber(2); // 两个节点,因此两个副本
indexModel.setShardNumber(3);
XContentBuilder builder = null;
builder = XContentFactory.jsonBuilder();
builder.startObject();
{
builder.startObject(“properties”);
{
builder.startObject(“title”);
{
builder.field(“type”, “text”);
builder.field(“analyzer”, “ik_max_word”);
}
builder.endObject();
builder.startObject(“filecontent”);
{
builder.field(“type”, “text”);
builder.field(“analyzer”, “ik_max_word”);
builder.field(“term_vector”, “with_positions_offsets”);
}
builder.endObject();
}
builder.endObject();
}
builder.endObject();
indexModel.setBuilder(builder);
Boolean res = iSearchService.createIndex(indexModel);
if(true==res)
return “ 创建索引成功 ”;
else
return “ 创建索引失败 ”;
}
删除索引
public String deleteIndex() {
return (iSearchService.deleteIndex(“testindex2”)==true) ? “ 删除索引成功 ”:” 删除索引失败 ”;
}
判断索引是否存在
if (existIndex(indexName) ) {
…
} else {
…
}
插入单个文档
public String insertSingleDoc() {
SingleDoc singleDoc = new SingleDoc();
singleDoc.setIndexName(“testindex2”);
singleDoc.setTypeName(“testtype2”);
Map<String,Object> doc = new HashMap<>();
doc.put(“title”,” 人工智能标题 1 ″);
doc.put(“filecontent”,” 人工智能内容 1 ″);
singleDoc.setDocMap(doc);
return (true== iSearchService.insertDoc( singleDoc) ) ? “ 插入单个文档成功 ” : “ 插入单个文档失败 ”;
}
批量插入文档
public String insertDocBatch() {
BatchDoc batchDoc = new BatchDoc();
batchDoc.setIndexName(“testindex2”);
batchDoc.setTypeName(“testtype2”);
Map<String,Object> doc1 = new HashMap<>();
doc1.put(“title”,” 人工智能标题 1 ″);
doc1.put(“filecontent”,” 人工智能内容 1 ″);
Map<String,Object> doc2 = new HashMap<>();
doc2.put(“title”,” 人工智能标题 2 ″);
doc2.put(“filecontent”,” 人工智能内容 2 ″);
Map<String,Object> doc3 = new HashMap<>();
doc3.put(“title”,” 人工智能标题 3 ″);
doc3.put(“filecontent”,” 人工智能内容 3 ″);
Map<String,Object> doc4 = new HashMap<>();
doc4.put(“title”,” 人工智能标题 4 ″);
doc4.put(“filecontent”,” 人工智能内容 4 ″);
List<Map<String,Object>> docList = new ArrayList<>();
docList.add(doc1);
docList.add(doc2);
docList.add(doc3);
docList.add(doc4);
batchDoc.setBatchDocMap(docList);
return (true== iSearchService.insertDocBatch( batchDoc) ) ? “ 批量插入文档成功 ” : “ 批量插入文档失败 ”;
}
搜索文档
public List<Map<String,Object>> searchDoc() {
SearchModel searchModel = new SearchModel();
searchModel.setIndexName(“testindex2”);
List<String> fields = new ArrayList<>();
fields.add(“title”);
fields.add(“filecontent”);
fields.add(“id”);
searchModel.setFields(fields);
searchModel.setKeyword(“ 人工 ”);
searchModel.setPageNum(1);
searchModel.setPageSize(5);
return iSearchService.queryDocs(searchModel);
}
删除文档
public String deleteDoc() {
SingleDoc singleDoc = new SingleDoc();
singleDoc.setIndexName(“testindex2”);
singleDoc.setTypeName(“testtype2”);
singleDoc.setId(“vPHMY2cBcGZ3je_1EgIM”);
return (true== iSearchService.deleteDoc(singleDoc)) ? “ 删除文档成功 ” : “ 删除文档失败 ”;
}
批量删除文档
public String deleteDocBatch() {
BatchDoc batchDoc = new BatchDoc();
batchDoc.setIndexName(“testindex2”);
batchDoc.setTypeName(“testtype2”);
List<String> ids = new ArrayList<>();
ids.add(“vfHMY2cBcGZ3je_1EgIM”);
ids.add(“vvHMY2cBcGZ3je_1EgIM”);
batchDoc.setDocIds(ids);
return (true== iSearchService.deleteDocBatch(batchDoc) ) ? “ 批量删除文档成功 ” : “ 批量删除文档失败 ”;
}
更新文档
public String updateDoc(@RequestBody SingleDoc singleDoc) {
SingleDoc singleDoc = new SingleDoc();
singleDoc.setId(“wPH6Y2cBcGZ3je_1OwI7”);
singleDoc.setIndexName(“testindex2”);
singleDoc.setTypeName(“testtype2”);
Map<String,Object> doc = new HashMap<>();
doc.put(“title”,” 人工智能标题 ( 更新后)”);
doc.put(“filecontent”,” 人工智能内容 ( 更新后)”);
singleDoc.setUpdateDocMap(doc);
return (true== iSearchService.updateDoc(singleDoc)) ? “ 更新文档成功 ” : “ 更新文档失败 ”;
}
后 记
由于能力有限,若有错误或者不当之处,还请大家批评指正,一起学习交流!
My Personal Blog:CodeSheep 程序羊