导入依赖
<!--提供与 elasticsearch 交互的高层次客户端,便于在 java 应用中使用 elasticsearch 的功能。--> <dependency> <groupid>org.elasticsearch.client</groupid> <artifactid>elasticsearch-rest-high-level-client</artifactid> </dependency> <!-- spring boot 的起始器,简化了与 elasticsearch 的集成 --> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-data-elasticsearch</artifactid> </dependency> <!-- 高性能的 json 处理库,用于 json 的解析和生成 --> <dependency> <groupid>com.alibaba</groupid> <artifactid>fastjson</artifactid> <version>1.2.83</version> <!-- 请使用最新的版本 --> </dependency> <!-- 通过注解简化 java 代码,自动生成 getter、setter、构造函数等代码,减少样板代码的编写 --> <dependency> <groupid>org.projectlombok</groupid> <artifactid>lombok</artifactid> </dependency>
导入 elasticsearchutil 工具
@component @slf4j public class elasticsearchutil { @autowired private resthighlevelclient resthighlevelclient; /** * 取对象id * * @param data * @return */ private string getobjectid(object data) { string idvalue = null; try { string idname = "id"; //获取object类下所有字段 field[] declaredfields = data.getclass().getdeclaredfields(); //循环遍历 for (field field : declaredfields) { //获取字段上的'idindex'的注解实例 idindex annotation = field.getannotation(idindex.class); //如果不为空 if (annotation != null) { //将annotation中的idname赋给变量idname idname = annotation.idname(); //终止循环 break; } } //查找一个名为 idname 的字段,并返回一个 field 对象,表示这个字段 field declaredfield = data.getclass().getdeclaredfield(idname); //设置对象的访问权限 declaredfield.setaccessible(true); idvalue = declaredfield.get(data).tostring(); log.info(" >>>>>> idvalue:{}", idvalue); } catch (exception e) { log.error(e.getmessage()); } return idvalue; } /** * 创建索引 * * @return * @params index */ public string createindex(object data) throws exception { //根据实体注解取索引名字 documentindex annotation = data.getclass().getannotation(documentindex.class); string indexname = annotation.indexname(); //索引已经存在,不需要创建索引 if (isindexexist(indexname)) return indexname; //1.创建索引请求 createindexrequest request = new createindexrequest(indexname); //创建基础配置 settings.builder builder = settings.builder().put("index.max_result_window", annotation.maxsize());//10亿数据 builder.put("index.number_of_shards", annotation.shards()) // 分片数量 .put("index.number_of_replicas", annotation.replicas()); // 副本数量 request.settings(builder);//索引文档基础配置 //mapping结构 jsonobject mapping = new jsonobject(); jsonobject props = new jsonobject(); mapping.put("properties", props); class<?> aclass = data.getclass(); //aclass.getconstructors(); //aclass.getmethods(); //取对象所有私有属性 field[] declaredfields = aclass.getdeclaredfields(); for (field field : declaredfields) { class type = field.gettype(); string name = field.getname(); jsonobject prop = new jsonobject(); propertyindex propindex = field.getannotation(propertyindex.class); if (propindex != null) {//自定义属性各种配置 if (propindex.name() != null && !"".equals(propindex.name())) { name = propindex.name(); } props.put(name, prop);//通过注解可以指定索引字段名称 prop.put("type", propindex.type()); prop.put("index", true);//默认true if ("text".equals(propindex.type())) { prop.put("analyzer", propindex.analyzer());//"analyzer": "ik_max_word", prop.put("search_analyzer", propindex.searchanalyzer());//"search_analyzer": "ik_smart" } if (!propindex.index()) { //设置非索引 prop.put("index", false); } } else { //默认处理 props.put(name, prop); if (type.newinstance() instanceof string) { prop.put("type", "keyword"); } else if (type.newinstance() instanceof date) { prop.put("type", "date"); prop.put("format", "yyyy-mm-dd hh:mm:ss");//"format": "yyyy-mm-dd hh:mm:ss" } else if (type.newinstance() instanceof integer) { prop.put("type", "integer"); } else if (type.newinstance() instanceof long) { prop.put("type", "long"); } else { prop.put("type", "text"); prop.put("analyzer", "ik_smart");//"analyzer": "ik_max_word", prop.put("search_analyzer", "ik_smart");//"search_analyzer": "ik_smart" } } } string jsonstring = mapping.tojsonstring(); log.info("jsonstring: " + jsonstring); request.mapping("_doc", jsonstring, xcontenttype.json); //2.执行客户端请求 createindexresponse createindexresponse = resthighlevelclient.indices() .create(request, requestoptions.default); return indexname; } /** * 判断索引是否存在 * * @param index * @return */ public boolean isindexexist(string index) throws ioexception { getindexrequest request = new getindexrequest(index); boolean exists = resthighlevelclient.indices().exists(request, requestoptions.default); return exists; } /** * 删除索引 * * @param index * @return */ public boolean deleteindex(string index) throws ioexception { if (!isindexexist(index)) { log.error("index is not exits!"); return false; } deleteindexrequest request = new deleteindexrequest(index); org.elasticsearch.action.support.master.acknowledgedresponse delete = resthighlevelclient.indices() .delete(request, requestoptions.default); return delete.isacknowledged(); } /** * 写入数据 */ public boolean insertdata(object data, string indexname) { try { indexrequest request = new indexrequest(indexname).id(getobjectid(data)).source(json.tojsonstring(data), xcontenttype.json); resthighlevelclient.index(request, requestoptions.default); } catch (exception e) { log.info(" >>>>>>> insertdata error: {}", e.getmessage()); e.printstacktrace(); } return true; } /** * 批量写入数据 */ public boolean batchinsert(list<object> datas) { //参数校验 if (collectionutils.isempty(datas)) return false; documentindex annotation = datas.get(0).getclass().getannotation(documentindex.class); string indexname = annotation.indexname(); try { bulkrequest bulkrequest = new bulkrequest(); datas.foreach(data -> { bulkrequest.add(new indexrequest(indexname).id(getobjectid(data)) .source(json.tojsonstring(data), xcontenttype.json)); }); resthighlevelclient.bulk(bulkrequest, requestoptions.default); } catch (exception e) { log.info(" >>>>>>> insertdata error: {}", e.getmessage()); e.printstacktrace(); } return true; } /** * 更新数据,可以直接修改索引结构 */ public boolean batchupdate(list<object> datas) { if (collectionutils.isempty(datas)) return false; documentindex annotation = datas.get(0).getclass().getannotation(documentindex.class); string indexname = annotation.indexname(); try { bulkrequest bulkrequest = new bulkrequest(); datas.foreach(data -> { bulkrequest.add(new updaterequest(indexname, "doc", getobjectid(data)).doc(json.tojsonstring(data))); }); resthighlevelclient.bulk(bulkrequest, requestoptions.default); } catch (exception e) { log.info(" >>>>>>> insertdata error: {}", e.getmessage()); e.printstacktrace(); } return true; } /** * 修改 * * @param data * @return */ public boolean updatedata(object data) { try { //获取索引名 string indexname = data.getclass().getannotation(documentindex.class).indexname(); //创建修改请求 updaterequest updaterequest = new updaterequest(indexname, "_doc", getobjectid(data)).doc(json.tojsonstring(data), xcontenttype.json); resthighlevelclient.update(updaterequest, requestoptions.default); } catch (ioexception e) { log.info(" >>>>>>> updatedata error: {}", e.getmessage()); e.printstacktrace(); } return true; } /** * 删除数据 */ public boolean delete(string indexname, string id) { try { deleterequest deleterequest = new deleterequest(indexname, "_doc", id); resthighlevelclient.delete(deleterequest, requestoptions.default); } catch (exception e) { log.error(" delete exception:{}", e.getmessage()); e.printstacktrace(); } return true; } }
导入config
@configuration public class initresthighlevelclient { @value("${es.hostname:ip}") private string hostname; @value("${es.port:端口}") private int port; /** * 初始化 resthighlevelclient 对象 * * @return */ @bean public resthighlevelclient resthighlevelclient() { resthighlevelclient client = new resthighlevelclient( restclient.builder(new httphost(hostname, port, "http")) ); return client; } }
注解类documentindex
/** * @author:guoyangsheng * @description: * @name:documentindex * @date:2024/9/12 16:43 */ @target(elementtype.type)//指定注解可以应用于类、接口或枚举 @retention(retentionpolicy.runtime)//可以通过反射机制访问和读取 public @interface documentindex { //指定索引的名称。默认为空字符串,表示未指定 string indexname() default ""; //默认为索引的文档数量上限为10000 int maxsize() default 10000; //指定索引的分片数量 默认为3 分片可以提高索引的性能和可扩展性 int shards() default 3; //指定索引的副本数量 默认为1 副本可以提高数据的可靠性和查询性能 int replicas() default 1; }
注解类idindex
/** * @author:guoyangsheng * @description: * @name:idindex * @date:2024/9/12 16:50 */ @target(elementtype.field)//指定 ‘idindex' 可以应用于类中字段上 @retention(retentionpolicy.runtime)//可以通过反射机制访问和读取 public @interface idindex { //指定属性标识符名称为 'id' string idname() default "id"; }
注解类propertyindex
/** * @author:guoyangsheng * @description: * @name:propertyindex * @date:2024/9/12 16:58 */ import java.lang.annotation.elementtype; import java.lang.annotation.retention; import java.lang.annotation.retentionpolicy; import java.lang.annotation.target; /** * es索引字段注解 */ @target(elementtype.field)//指定 ‘idindex' 可以应用于类中字段上 @retention(retentionpolicy.runtime)//可以通过反射机制访问和读取 public @interface propertyindex { //用于指定字段在elasticsearch索引中的名称 string name() default ""; //指定字段的数据类型 string type() default "keyword"; //指定用于字段的分词器 string analyzer() default "ik_smart"; //是否建立索引 boolean index() default true; //指定用于搜索时的分词器 string searchanalyzer() default "ik_smart"; //指定是否忽略该字段的索引 boolean ignore() default true; }
controller
/** * @author:guoyangsheng * @description: * @name:sysdeptcontroller * @date:2024/9/12 20:26 */ @restcontroller @requestmapping("/sysdept") public class sysdeptcontroller { @autowired private sysdeptservice sysdeptservice; /** * 创建索引 * * @param sysdept * @return */ @getmapping("/createindex") public void createindex(sysdept sysdept) { sysdeptservice.createindex(sysdept); } /** * 保存 * * @param sysdept */ @postmapping("/save") public boolean save(@requestbody sysdept sysdept) { return sysdeptservice.save(sysdept); } /** * 删除数据 * * @param indexname * @param id * @return */ @deletemapping("/deletebyid") public boolean deletebyid(string indexname, string id) { return sysdeptservice.deletebyid(indexname, id); } /** * 修改数据 * * @param sysdept * @return */ @putmapping("/updatesysdept") public boolean updatesysdept(@requestbody sysdept sysdept) { return sysdeptservice.updatesysdept(sysdept); } }
service
/** * @author:guoyangsheng * @description: * @name:sysdeptservice * @date:2024/9/12 20:26 */ public interface sysdeptservice { /** * 创建索引 * * @param sysdept */ void createindex(sysdept sysdept); /** * 保存 * * @param sysdept */ boolean save(sysdept sysdept); /** * 删除数据 * * @param indexname * @param id * @return */ boolean deletebyid(string indexname, string id); /** * 修改数据 * * @param sysdept * @return */ boolean updatesysdept(sysdept sysdept); }
实现层 直接调用工具类方法即可
/** * @author:guoyangsheng * @description: * @name:sysdeptserviceimpl * @date:2024/9/12 20:26 */ @service public class sysdeptserviceimpl implements sysdeptservice { @resource private elasticsearchutil elasticsearchutil; /** * 创建索引 * * @param sysdept */ @override public void createindex(sysdept sysdept) { try { elasticsearchutil.createindex(sysdept); } catch (exception e) { throw new runtimeexception(e); } } /** * 保存 * * @param sysdept */ @override public boolean save(sysdept sysdept) { return elasticsearchutil.insertdata(sysdept); } /** * 删除数据 * * @param indexname * @param id * @return */ @override public boolean deletebyid(string indexname, string id) { return elasticsearchutil.delete(indexname, id); } /** * 修改数据 * * @param sysdept * @return */ @override public boolean updatesysdept(sysdept sysdept) { return elasticsearchutil.updatedata(sysdept); } }
在elastic开发工具中查看效果,或者下载apipost工具测试即可
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论