TransportClient中实现es索引创建的应用

随着ElasticSearch应用的不断增多,我发现它作为全文数据库功能确实非常强大。
我本人使用的是java客户端TransportClient操作es,如果采用原生的API,或多或少存在一些不便之处。比如创建索引,添加索引文件,修改索引文件,删除索引文件,如果不加以封装,在实际应用时需要花大量时间学习api的使用,同时造成大量代码重复。
因为项目需要,我针对索引创建,修改和删除进行了一定的代码封装。 特别是在索引的创建,我在这里封装了创建静态mapping索引的方法,并且提供了一个只需要传入任意javabean对象,就为其创建符合使用要求的静态mapping索引的方法。
以下代码在使用时,可直接在springboot创建的项目中写一个配置类,需要传入一个client对象,或者同时传入client和Jedis对象(如果需要的话)。
话不多说,直接上代码:

package cn.yumi.common.utils;

import jdk.nashorn.internal.ir.RuntimeNode;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.IndicesAdminClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import redis.clients.jedis.JedisCluster;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @ClassName IndexUtil
 * @Description TODO
 * @Author GrainRain
 * @Date 2020/1/13 21:09
 * @Version v1.0
 */
public class IndexClient {
    private TransportClient client;
    private JedisCluster jedisCluster;
    public IndexClient(TransportClient client){
        this.client = client;
    }
    public IndexClient(TransportClient client,JedisCluster jedisCluster){
        this.client = client;
        this.jedisCluster = jedisCluster;
    }

    //根据indexName创建索引
    public void createIndexByJson(String indexName) throws IOException {
        IndicesAdminClient indices = client.admin().indices();
        boolean exists = indices.prepareExists(indexName).get().isExists();
        if(exists)
            return;
        //索引不存在,指定mapping,此处采用json指定,需注意json结构
        CreateIndexRequestBuilder request = indices.prepareCreate(indexName);   //指定索引名称
        //提交并创建索引
        request.get();
    }

    //根据静态mapping创建索引
    public void createIndexByJson(String indexName, String type, Map<String, Map<String,String>> fieldsMap) throws IOException {
        //获取索引管理器
        IndicesAdminClient indices = client.admin().indices();
        boolean exists = indices.prepareExists(indexName).get().isExists();
        //指定索引名称
        CreateIndexRequestBuilder request = indices.prepareCreate(indexName);
        if(exists) {    //索引已存在,执行新增操作
            return;
        }

        //获取构建静态mapping的builder
        XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("properties");
        //将传入的静态mapping参数依次封装到mapping中
        Set<String> fields = fieldsMap.keySet();
        for(String field: fields){
            Map<String, String> fieldType = fieldsMap.get(field);
            mapping.startObject(field);
            for(Map.Entry<String,String> entry :fieldType.entrySet()){
                mapping.field(entry.getKey(),entry.getValue());
            }
            mapping.endObject();
        }
        //关闭json构造
        mapping.endObject().endObject();
        //添加mapping并创建索引
        request.addMapping(type, mapping);
        request.execute().actionGet();
    }

    //根据javaBean创建静态索引
    /*
		按照javabean的属性值创建具有静态mapping的索引
		如果值为null,采用keyword类型
		如果值为中文,采用text类型并默认ik分词器
		如果值为数值,采用long类型
	*/
    public void createIndex(String indexName, String type, Object o){
        Map<String,Map<String,String>> mapping = new HashMap<>();

        try {
            Field[] fields = o.getClass().getDeclaredFields();
            for (Field field:fields) {
                field.setAccessible(true);
                String name = field.getName();
                Object value = field.get(o);
                if(value==null){
                    Map<String,String> map = new HashMap<>();
                    map.put("type","keyword");
                    mapping.put(name,map);
                } else if(value.getClass()==Integer.class || value.getClass()==Long.class || value.getClass()==int.class || value.getClass()==long.class){
                    Map<String,String> map = new HashMap<>();
                    map.put("type","long");
                    mapping.put(name,map);
                }else if(value.getClass()==String.class){
                    String key = (String)value;
                    Map<String,String> map = new HashMap<>();
                    if(key.matches("[a-zA-z0-9\\\\/\\-\\.\\?=!]+")){
                        map.put("type","keyword");
                        mapping.put(name,map);
                    }else{
                        map.put("type","text");
                        map.put("analyzer","ik_max_word");
                        mapping.put(name,map);
                    }
                }
            }
            System.out.println(mapping);
            this.createIndexByJson(indexName,type,mapping);
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException();
        }
    }

    //添加文档到索引中
    public void addDoc(String indexName,String type,List<String> docs) {
        if(docs != null){
            for (String doc:docs){
                IndexRequestBuilder request = client.prepareIndex(indexName, type,IDCreateUtil.getId()).setSource(doc);
                request.get();
            }
        }
    }
    public void addDoc(String indexName,String type,String doc) {
        IndexRequestBuilder request = client.prepareIndex(indexName, type,IDCreateUtil.getId()).setSource(doc);
        request.get();
    }
    //支持指定id后添加到数据库
    public void addDoc(String indexName,String type,Map<String,String> idAndDocs){
        if(idAndDocs != null){
            for(Map.Entry<String,String> entry : idAndDocs.entrySet()){
                String id = entry.getKey();
                String doc = entry.getValue();
                IndexRequestBuilder request = client.prepareIndex(indexName,type,id).setSource(doc);
                request.get();
            }
        }
    }

    public void addDoc(String indexName,String type,String id,String doc){
        IndexRequestBuilder request = client.prepareIndex(indexName, type,id).setSource(doc);
        request.get();
    }

    //扫描redis数据并加入全文数据库
    public void scanDoc(String indexName,String type) {
        String typeName = "es_index:" + type;
        List<String> list = new ArrayList<String>();
        while (jedisCluster.llen(typeName) != 0) {
            String  json = jedisCluster.rpop(typeName);
            list.add(json);
            //达到1000条数据,先处理这批数据,然后再继续扫描
            if(list.size()>1000)
                this.addDoc(indexName,type,list);
        }
        //数据量小于1000,直接处理
        this.addDoc(indexName,type,list);
    }

    //将接收的数据加入redis以等待被加入es,或者直接加入
    public void addDocToRedis(String indexName,String type,String oJson,String isAddNow) {
        if ("true".equals(isAddNow) && indexName != null && !"".equals(indexName)) {
            this.addDoc(indexName,type,oJson);

        } else {
            String key = "es_index:" + type;
            jedisCluster.lpush(key, oJson);
        }
    }
	//此处map的key-value为需要更新的文档属性及对应更新后的值
    public void updateDoc(String indexName,String type,String id,Map<String,Object> sources){
        UpdateRequest request = new UpdateRequest(indexName,type,id);
        request.doc(sources);
        client.update(request);
    }

    public void updateDoc(String indexName,String type,String id,String sources){
        UpdateRequest request = new UpdateRequest(indexName,type,id);
        request.doc(sources);
        client.update(request);
    }

    public void deleteDoc(String indexName,String type,String id){
        DeleteRequest request = new DeleteRequest(indexName,type,id);
        client.delete(request);
    }

    public List<String> queryIndexId(QueryBuilder query, String ...indices){
        SearchRequestBuilder request = client.prepareSearch(indices);
        request.setQuery(query);
        SearchHits hits = request.get().getHits();
        List<String> idList = new ArrayList<String>();
        for(SearchHit hit:hits){
            idList.add(hit.getId());
        }
        return idList;
    }

}

你可能感兴趣的:(TransportClient中实现es索引创建的应用)