导入依赖
<!--提供与 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工具测试即可
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论