ES搜索(ElasticSearch)(三) 创建索引

采用Java的方式创建ElasticSearch的index、settings、mapping

settings可采用XContentType.JSON也可以采用settingsJson的方式

mapping可以采用数据库Model的方式根据自定义规则映射成ES的数据类型

package com.demo.plugin;

import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.client.IndicesClient;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetMappingsRequest;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentType;

import com.jfinal.plugin.activerecord.Table;
import com.jfinal.plugin.activerecord.TableMapping;

@SuppressWarnings("all")
public class IniIndex {

	private RestHighLevelClient restHighLevelClient = ElasticSearchPlugin.getHighLevelClient();
	
	private RequestOptions options = RequestOptions.DEFAULT;
	
	private static final Map<String, String> MAPPINGS = new HashMap<>();
	
	/**
     * settings处理
     * @throws IOException 
     * indexName 类名_版本号   test_v1.0
     * 别名统一 	类名_alias
     */
    public void settings(String indexName) throws IOException {
    	CreateIndexRequest params = new CreateIndexRequest(indexName); 
    	params.alias(new Alias(indexName+"_alias"));
    	
    	/*params.settings("     {\n" +
						"        \"number_of_shards\" : 1,\n" +
						"        \"number_of_replicas\" : 0,\n" +
						"	\"analysis\": {\n" +
						"    	\"analyzer\": {\n" +
						"      		\"rebuilt_thai\": {\n" +
						"       	 \"tokenizer\": \"thai\"\n" +
						"      		}\n" +
						"   	}\n" +
						"  	}\n" +
						"}", XContentType.JSON);*/
    	params.settings(" {\n" +
    					"  \"number_of_shards\" : 1,\n" +
    					"   \"number_of_replicas\" : 0,\n" +
    					"	 \"analysis\": {\n" +
    					"    	\"analyzer\": {\n" +
    					"      		\"icu_analyzer\": {\n" +
    					"       	 \"tokenizer\": \"icu_tokenizer\",\n" +
    					"        	  \"filter\": [\n" +
    					"         		 \"lowercase\",\n" +
    					"          		 \"decimal_digit\"\n" +
    					"        		]\n" +
    					"      		}\n" +
    					"   	}\n" +
    					"  	}\n" +
    					"}", XContentType.JSON);
    	/*params.settings(
    			"     {\n" +
    					"        \"number_of_shards\" : 1,\n" +
    					"        \"number_of_replicas\" : 0,\n" +
    					"	\"analysis\": {\n" +
    					"    	\"analyzer\": {\n" +
    					"      		\"ik_analyzer\": {\n" +
    					"       	 \"tokenizer\": \"ik_max_word\",\n" +
    					"        	  \"filter\": [\n" +
    					"         		 \"lowercase\",\n" +
    					"          		 \"decimal_digit\"\n" +
    					"        		]\n" +
    					"      		}\n" +
    					"   	}\n" +
    					"  	}\n" +
    					"}", XContentType.JSON);*/
    	
    	/*params.settings("{\n" +
				"        \"number_of_shards\" : 1,\n" +
				"        \"number_of_replicas\" : 0,\n" +
				"		\"analysis\": {\n" +
				"    		\"tokenizer\": {\n" + 
				"     			 \"ik_max_word\": {\n" +
				"        	  	\"type\": \"pattern\",\n" +
				"       	   	\"pattern\": \"[ .,*,~,|,!,?,\\/,。,,,-,+,=,,]\"\n" +
				"      		 	}\n" +
				"    	 	},\n" +
				"    		\"analyzer\": {\n" +
				"      			\"ik_analyzer\": {\n" +
				"       	 	\"tokenizer\": \"ik_max_word\",\n" +
				"        	  	\"filter\": [\n" +
				"         			 \"lowercase\",\n" +
				"          			 \"decimal_digit\"\n" +
				"        			]\n" +
				"      			}\n" +
				"   		}\n" +
				"  		}\n" +
				"	}", XContentType.JSON);*/
    	
    	restHighLevelClient.indices().create(params, options);
    }
	/**
	 * 初始化索引
	 * 
	 * @param indexName			索引名称
	 * @param indexNameAlia		索引别名
	 * @param settingsJson		settings数据
	 * @param mappingJson		mapping数据
	 * @return
	 */
	public static boolean iniIndex(String indexName,String indexNameAlia,String settingsJson,String mappingJson){
		// 判断索引是否存在
        boolean result = isIndexExists(indexName);
		if(result){
			log.error("索引已存在: "+indexName);
			return false;
		}
		try {
			CreateIndexRequest params = new CreateIndexRequest(indexName); 
	    	params.alias(new Alias(indexNameAlia));
	    	params.settings(settingsJson, XContentType.JSON);
	    	params.mapping(mappingJson, XContentType.JSON);
			restHighLevelClient.indices().create(params, options);
		} catch (IOException e) {
			//e.printStackTrace();
			log.error("索引: "+indexName+",初始化异常:"+ e);
			return false;
		}
		return true;
	}    

    /**
     * Mapping处理
     *
     * @param obj			model类
     * @param indexName		索引名
     * @param analyzerList	需要分词的字段
     * @param objType			对象类型
     * @throws IOException 
     */
    public void mapping(Object obj,String indexName,List<String> analyzerList,int objType) throws IOException {
    	String type = obj.getClass().getSimpleName().toLowerCase();
    	GetMappingsRequest request = new GetMappingsRequest();
    	if (!MAPPINGS.containsKey(type)) {
    		synchronized (ElasticSearchPlugin.class) {
    			createIndex(indexName);
    			//获取所有的Mapping
                //ImmutableOpenMap<String, MappingMetaData> mappings = client.admin().cluster().prepareState().execute()
                //       .actionGet().getState().getMetaData().getIndices().get(clusterName).getMappings();
                //MappingMetaData mmd = mappings.get(type);
    			Map<String, MappingMetaData> mappings = restHighLevelClient.indices().getMapping(request, options).mappings();
    			MappingMetaData mmd = mappings.get("type");
    			if (null == mmd) {
    				createMapping(obj,indexName,analyzerList,objType);
    			} else {
    				CompressedXContent xContent = mappings.get(type).source();
    				if (xContent == null) {
    					createMapping(obj,indexName,analyzerList,objType);
    				} else {
    					String mapping = xContent.toString();
    					MAPPINGS.put(type, mapping);
    				}
    			}
    		}
    	}
    }
 
    /**
     * 创建Mapping
     *
     */
	public void createMapping(Object obj,String indexName,List<String> analyzerList,int objType) {
        String type = obj.getClass().getSimpleName().toLowerCase();
        PutMappingRequest mapping = null;
        if(objType == 1){
        	mapping = Requests.putMappingRequest(indexName).type(type).source(saveMapping(obj,analyzerList));
        	
        }else{
        	mapping = Requests.putMappingRequest(indexName).type(type).source(setMapping(obj,analyzerList));
        }
        //AcknowledgedResponse actionGet = client.admin().indices().putMapping(mapping).actionGet();
        //AcknowledgedResponse putMapping = restHighLevelClient.indices().putMapping(mapping, options);
        try {
			restHighLevelClient.indices().putMapping(mapping, options);
		} catch (IOException e) {
			e.printStackTrace();
		}
    }
 
    /**
     * 设置对象的ElasticSearch的Mapping
     *
     * jfinal
     * @param obj
     * @return
     */
    public XContentBuilder setMapping(Object obj,List<String> analyzerList) {
        List<Map.Entry<String,Object>> fieldList = getFieldList(obj);
        XContentBuilder mapping = null;
        try {
            mapping = jsonBuilder().startObject().startObject("properties");
            for (Map.Entry<String,Object> atrrValue : fieldList) {
                
            	String key = (String) atrrValue.getKey();
            	String value = atrrValue.getValue().toString();
            	String name = value.substring(value.lastIndexOf(".")+1);
            	String type = getElasticSearchMappingType(name.toLowerCase());
                if (analyzerList.contains(key)) {
                    mapping.startObject(key)
                        .field("type", type)
                        //使用icu_analyzer分词器
                        .field("analyzer", "icu_analyzer")
                        .field("search_analyzer", "icu_analyzer")
                        .endObject();
                } else {
                    mapping.startObject(key)
                     	.field("type", type)
                    .endObject();
                }
            }
            mapping.endObject().endObject();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return mapping;
    }
 
    /**
     * 设置对象的ElasticSearch的Mapping
     *
     * 普通对象
     * @param obj
     * @return
     */
    public XContentBuilder saveMapping(Object obj,List<String> analyzerList) {
    	List<Field> fieldList = getFields(obj);
        XContentBuilder mapping = null;
        try {
            mapping = jsonBuilder().startObject().startObject("properties");
            for (Field field : fieldList) {
                //修饰符是static的字段不处理
                if (Modifier.isStatic(field.getModifiers())){
                    continue;
                }
                if (field.getType().isInterface()){
         		   //处理list
                	List<Field> listFields = getListFields(obj,field.getName());
                	mapping.startObject(field.getName())
                			.field("type", "nested")
                		.startObject("properties");
                	for (Field f : listFields) {
	                	String name = f.getName();
	          		  	String type = getElasticSearchMappingType(f.getType().getSimpleName().toLowerCase());
	          		  	mapping.startObject(name)
    			   			.field("type", type)
    			   		.endObject();
                	}
                	mapping.endObject().endObject();
         	   }else{
         		   String name = field.getName();
         		   String type = getElasticSearchMappingType(field.getType().getSimpleName().toLowerCase());
         		   if (analyzerList.contains(name)) {
         			   mapping.startObject(name)
         			   		.field("type", type)
         			   		//使用icu_analyzer分词器
         			   		.field("analyzer", "icu_analyzer")
         			   		.field("search_analyzer", "icu_analyzer")
         			   .endObject();
         		   } else {
         			   mapping.startObject(name)
         			   		.field("type", type)
         			   .endObject();
         		   }
         	   }
            }
            mapping.endObject().endObject();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return mapping;
    }

    
    /**
     * 获取对象所有自定义的属性
     *
     * jfinal反射
     * @param obj
     * @return
     */
	public List<Map.Entry<String,Object>> getFieldList(Object obj) {
        List<Map.Entry<String,Object>> fieldList = new ArrayList<>();
        Class objClass = obj.getClass();
        Table table = TableMapping.me().getTable(objClass);
        Map<String, Class<?>> columnTypeMap = table.getColumnTypeMap();
        Iterator it = columnTypeMap.entrySet().iterator();
        while (it.hasNext()) {
           Map.Entry<String,Object> atrrValue = (Map.Entry<String,Object>)it.next();
           fieldList.add(atrrValue);
        }
        return fieldList;
    }

    /**
     * 获取对象所有自定义的属性
     * 
     * 普通对象映射
     * @param obj
     * @return
     */
	public List<Field> getFields(Object obj) {
		Field[] fields = obj.getClass().getDeclaredFields();
        List<Field> fieldList = new ArrayList<>();
        fieldList.addAll(Arrays.asList(fields));
        return fieldList;
    }
	
	/**
	 * 获取对象所有自定义的属性
	 * 普通对象List映射
	 * @param obj
	 * @param listName
	 * @return
	 */
    private List<Field> getListFields(Object obj,String listName) {
    	Field listField;
    	List<Field> fieldList = new ArrayList<>();
		try {
			listField = obj.getClass().getDeclaredField(listName);
			//获取 list 字段的泛型参数
			ParameterizedType listGenericType = (ParameterizedType) listField.getGenericType();
			Type[] listActualTypeArguments = listGenericType.getActualTypeArguments();
			Class objClass =(Class)listActualTypeArguments[0];
			Field[] fields = objClass.getDeclaredFields();
			fieldList.addAll(Arrays.asList(fields));
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
		return fieldList;
    }
    
    /**
     * java类型与ElasticSearch类型映射
     *
     * @param varType
     * @return
     */
    public String getElasticSearchMappingType(String varType) {
        String es;
        switch (varType) {
	        case "date":
	        	//默认格式2020-06-06 || 1420070400001
	            es = "date";
	            break;
	        case "double":
	            es = "double";
	            break;
	        case "bigdecimal":
	        	//scaled_float 会缩放存储
	        	es = "double";
	        	break;
            case "long":
                es = "long";
                break;
            case "int":
                es = "long";
                break;
            case "integer":
            	es = "long";
            	break;
            case "list":
            	es = "nested";
            	break;
            default:
                es = "text";
                break;
        }
        return es;
    }
 
 
    /**
     * 创建索引
     * @throws IOException 
     */
    public void createIndex(String indexName) {
        /*if (!indexExists()) {
            CreateIndexRequest request = new CreateIndexRequest("ice");
            client.admin().indices().create(request);
        }*/
    	try {
	    	if (!indexExists(indexName)) {
	           CreateIndexRequest request = new CreateIndexRequest(indexName);
	           IndicesClient indices = restHighLevelClient.indices();
	           indices.create(request, options);
			} 
    	}catch (IOException e) {
			e.printStackTrace();
		}
    }
    
    /**
     * 判断ElasticSearch中的索引是否存在
     * @throws IOException 
     */
    public boolean indexExists(String indexName){
    	/*IndicesExistsRequest request = new IndicesExistsRequest(clusterName);
        IndicesAdminClient adminClient = client.admin().indices();
        IndicesExistsResponse response = adminClient.exists(request).actionGet();
        if (response.isExists()) {
            return true;
        }
        return false;*/
    	
        GetIndexRequest request = new GetIndexRequest(indexName);
        IndicesClient indices = restHighLevelClient.indices();
    	boolean exists = false;
		try {
			exists = indices.exists(request, options);
		} catch (IOException e) {
			e.printStackTrace();
		}
        return exists;
    }

}

高版本ES的mapping一旦设定不可修改 参考官方文档

采用Java的方式创建ES的 index、settings、mapping属于硬编码的形式,我是是可以选择更简便的方式 Kibana 去创建

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值