当前位置: 代码网 > it编程>游戏开发>ar > ElasticSearch自定义注解增删改方式

ElasticSearch自定义注解增删改方式

2025年04月17日 ar 我要评论
导入依赖<!--提供与 elasticsearch 交互的高层次客户端,便于在 java 应用中使用 elasticsearch 的功能。--><dependency>

导入依赖

<!--提供与 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工具测试即可

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com