自制一个 elasticsearch-spring-boot-starter

本贴最后更新于 2124 天前,其中的信息可能已经水流花落

Samsung Galaxy S10


概 述

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)) ? "更新文档成功" : "更新文档失败";
}

后 记

由于能力有限,若有错误或者不当之处,还请大家批评指正,一起学习交流!



  • Elasticsearch

    Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    117 引用 • 99 回帖 • 209 关注
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    943 引用 • 1460 回帖 • 3 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...