elasticsearch动态索引(基于9300端口)


public class CustomElasticsearchRepositoryFactory extends RepositoryFactorySupport {
    private final ElasticsearchOperations elasticsearchOperations;
    private final ElasticsearchEntityInformationCreator entityInformationCreator;
    private String indexName;
    private String indexType;
 
    public CustomElasticsearchRepositoryFactory(ElasticsearchOperations elasticsearchOperations, String indexName,String indexType) {
        Assert.notNull(elasticsearchOperations, "ElasticsearchOperations must not be null!");
        this.elasticsearchOperations = elasticsearchOperations;
        this.indexName = indexName;
        this.indexType = indexType;
        this.entityInformationCreator = new ElasticsearchEntityInformationCreatorImpl(elasticsearchOperations.getElasticsearchConverter().getMappingContext());
    }
 
    private void setEntityInformationIndexName(MappingElasticsearchEntityInformation entityInformation) {
        try {
            Field field = MappingElasticsearchEntityInformation.class.getDeclaredField("indexName");
            field.setAccessible(true);
            String indexDefault = field.get(entityInformation).toString();
            if (!StringUtils.isEmpty(this.indexName)) {
                field.set(entityInformation, this.indexName);
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
 
    public <T, ID> ElasticsearchEntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
        ElasticsearchEntityInformation entityInformation = this.entityInformationCreator.getEntityInformation(domainClass);
        if (!StringUtils.isEmpty(this.indexName)) {
            setEntityInformationIndexName((MappingElasticsearchEntityInformation) entityInformation);
        }
        return entityInformation;
 
    }
 
    protected Object getTargetRepository(RepositoryInformation metadata) {
        return this.getTargetRepositoryViaReflection(metadata, new Object[]{this.getEntityInformation(metadata.getDomainType()), this.elasticsearchOperations});
    }
    
    
    @Override
	protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
		if (isQueryDslRepository(metadata.getRepositoryInterface())) {
			throw new IllegalArgumentException("QueryDsl Support has not been implemented yet.");
		}
		return SimpleElasticsearchRepository.class;
	}
    
    private static boolean isQueryDslRepository(Class<?> repositoryInterface) {
        return QuerydslUtils.QUERY_DSL_PRESENT && QuerydslPredicateExecutor.class.isAssignableFrom(repositoryInterface);
    }
 
    private class ElasticsearchQueryLookupStrategy implements QueryLookupStrategy {
        private ElasticsearchQueryLookupStrategy() {
        }
 
        public RepositoryQuery resolveQuery(java.lang.reflect.Method method, RepositoryMetadata metadata, ProjectionFactory factory, NamedQueries namedQueries) {
        	ElasticsearchQueryMethod queryMethod = new ElasticsearchQueryMethod(method, metadata, factory,
					elasticsearchOperations.getElasticsearchConverter().getMappingContext());
            String namedQueryName = queryMethod.getNamedQueryName();
            if (namedQueries.hasQuery(namedQueryName)) {
                String namedQuery = namedQueries.getQuery(namedQueryName);
                return new ElasticsearchStringQuery(queryMethod, CustomElasticsearchRepositoryFactory.this.elasticsearchOperations, namedQuery);
            } else {
                return (RepositoryQuery) (queryMethod.hasAnnotatedQuery() ? new ElasticsearchStringQuery(queryMethod, CustomElasticsearchRepositoryFactory.this.elasticsearchOperations, queryMethod.getAnnotatedQuery()) : new ElasticsearchPartQuery(queryMethod, CustomElasticsearchRepositoryFactory.this.elasticsearchOperations));
            }
        }
    }
 
    protected Optional<QueryLookupStrategy> getQueryLookupStrategy(QueryLookupStrategy.Key key, EvaluationContextProvider evaluationContextProvider) {
        return Optional.of(new CustomElasticsearchRepositoryFactory.ElasticsearchQueryLookupStrategy());
    }
}


@Component
@Scope("prototype")
public class DynamicIndexElasticsearchTemplate implements ApplicationContextAware {
    private ApplicationContext applicationContext;
    @Autowired
    private ESTransportClient eSTransportClient;
    protected ElasticsearchTemplate getElasticsearchTemplate() {
    	return new ElasticsearchTemplate(eSTransportClient.client());
    }
    
    public ElasticsearchTemplate getElasticsearchTemplate(String indexName,String indexType, Class cls) {
        ElasticsearchTemplate esTemplate = getElasticsearchTemplate();
        setIndex(indexName, cls, esTemplate);
        setType(indexType, cls, esTemplate);
        return esTemplate;
    }
 
    protected void setIndex(String indexName, Class cls, ElasticsearchTemplate elasticsearchTemplate) {
        ElasticsearchPersistentEntity entity = elasticsearchTemplate.getPersistentEntityFor(cls);
        try {
            Field field = SimpleElasticsearchPersistentEntity.class.getDeclaredField("indexName");
            field.setAccessible(true);
            String indexDefault = field.get(entity).toString();
            if (!StringUtils.isEmpty(indexName)) {
                field.set(entity, indexName);
            }
            String indexDefault2 = field.get(entity).toString();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
    
    protected void setType(String type, Class cls, ElasticsearchTemplate elasticsearchTemplate) {
        ElasticsearchPersistentEntity entity = elasticsearchTemplate.getPersistentEntityFor(cls);
        try {
            Field field = SimpleElasticsearchPersistentEntity.class.getDeclaredField("indexType");
            field.setAccessible(true);
            String indexDefault = field.get(entity).toString();
            if (!StringUtils.isEmpty(type)) {
                field.set(entity, type);
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
 
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}


public class ESDynamicIndexRepository<T,D> {
    @Autowired
    private DynamicIndexElasticsearchTemplate dynamicIndexElasticsearchTemplate;
	private Class<? extends Object> class1;
 
    private CustomElasticsearchRepositoryFactory getFactory(ElasticsearchTemplate elasticsearchTemplate,String indexName,String indexType) {
        CustomElasticsearchRepositoryFactory elasticFactory = new CustomElasticsearchRepositoryFactory(elasticsearchTemplate, indexName,indexType);
        return elasticFactory;
    }
 
    @SuppressWarnings("unchecked")
    private Class<T> resolveReturnedClassFromGenericType() {
        ParameterizedType parameterizedType = resolveReturnedClassFromGenericType(getClass());
        return (Class<T>) parameterizedType.getActualTypeArguments()[0];
    }
 
    private ParameterizedType resolveReturnedClassFromGenericType(Class<?> clazz) {
        Object genericSuperclass = clazz.getGenericSuperclass();
        if (genericSuperclass instanceof ParameterizedType) {
            return (ParameterizedType) genericSuperclass;
        }
        return resolveReturnedClassFromGenericType(clazz.getSuperclass());
    }
 
    /**
     * @param indexPrefix
     * @param cls         domain.class  interview.class
     * @return
     */
    public ElasticsearchTemplate getElasticsearchTemplate(String indexPrefix,String indexType, Class cls) {
        ElasticsearchTemplate esTemplate = dynamicIndexElasticsearchTemplate.getElasticsearchTemplate();
        dynamicIndexElasticsearchTemplate.setIndex(indexPrefix, cls, esTemplate);
        dynamicIndexElasticsearchTemplate.setType(indexPrefix, cls, esTemplate);
        return esTemplate;
    }
 
    private Class<?> getClazz(Class proxy) {
        Type[] types = proxy.getGenericInterfaces();
        Type t1 = ((ParameterizedType) types[0]).getActualTypeArguments()[0];
        return (Class) t1;
    }
 
 
    public T proxyRepository() {
        return getProxyRepository(null,null,null);
    }
 
    public T getProxyRepository(String indexName,String indexType,D info) {
        Class<T> proxy = resolveReturnedClassFromGenericType();
        if (proxy.getClass().isInstance(ElasticsearchRepository.class)) {
            ElasticsearchTemplate esTemplate = dynamicIndexElasticsearchTemplate.getElasticsearchTemplate();
            Class<D> class_info= (Class<D>) info.getClass();
            Document annotation = class_info.getAnnotation(Document.class);
            Map mapping = esTemplate.getMapping(annotation.indexName(),annotation.type());
            //动态处理索引需要的mapping结构,比如分词器什么的
            handlerMapping(mapping,class_info);
            ElasticsearchTemplate esTemplatenew = dynamicIndexElasticsearchTemplate.getElasticsearchTemplate();
            if(!esTemplatenew.indexExists(indexName)){
            	//指定索引分片数量
            	esTemplatenew.getClient().admin().indices().prepareCreate(indexName)
                .setSettings(Settings.builder()             
                        .put("index.number_of_shards", 5)
                        .put("index.number_of_replicas", 1)
                ).get();
            	//刷新分片数量
            	esTemplatenew.getClient().admin().indices().prepareRefresh(indexName).get();
            	
            }
            esTemplatenew.putMapping(indexName, indexType, mapping);
            CustomElasticsearchRepositoryFactory esFactory = getFactory(esTemplatenew,indexName,indexType);
            T proxyRepository = esFactory.getRepository(proxy);
            if (!StringUtils.isEmpty(indexName)) {
                dynamicIndexElasticsearchTemplate.setIndex(indexName, getClazz(proxy), esTemplatenew);
                dynamicIndexElasticsearchTemplate.setType(indexType, getClazz(proxy), esTemplatenew);
                
            }
            return proxyRepository;
        } else {
            throw new RuntimeException("do not support thie proxy class");
        }
    }
    
    /**
     * 动态处理mapping
     * @param mapping
     * @param class_info 
     */
	@SuppressWarnings("rawtypes")
	private void handlerMapping(Map mapping, Class<D> class_info) {
		LinkedHashMap list = (LinkedHashMap) mapping.get("properties");
		Field[] fields = class_info.getDeclaredFields();
		for (int i = 0; i < fields.length; i++) {
			String fieldname = fields[i].getName();
			LinkedHashMap m = (LinkedHashMap) list.get(fieldname);
			if(m==null){
			    continue;
            }
			if(m.containsKey("analyzer")){
              //如果类型是text,满足既要支持分词查询,也要支持关键字查询,需要增加一个keyword类型,便于查询
				m = handerUntouched(m,fieldname,"text");
			}
			//处理CodeChildrenInfo
			if(class_info==CodeInfo.class){
				if("nested".equals(m.get("type"))){
					LinkedHashMap list_codevalue = (LinkedHashMap) m.get("properties");
					Field[] fields_codevalue=null;
					if("codeChildrenInfos".equals(fieldname)){
						fields_codevalue = CodeChildrenInfo.class.getDeclaredFields();
					}else if("codevalueInfos".equals(fieldname)){
						fields_codevalue = CodeChildrenInfo.class.getDeclaredFields();
					}
					for (int j = 0; fields_codevalue!=null && j < fields_codevalue.length; j++) {
						String fieldname_codevalue = fields_codevalue[j].getName();
						LinkedHashMap m_codevalue = (LinkedHashMap) list_codevalue.get(fieldname_codevalue);
						//如果类型是text,满足既要支持分词查询,也要支持关键字查询,需要增加一个keyword类型,便于查询
						if(m_codevalue!=null  ){
							String type =StringUtils.toString(m_codevalue.get("type"));
							if(!"keyword".equals(type)){
								m_codevalue = handerUntouched(m_codevalue,fieldname_codevalue,type);
							}
						}
					}
					
				}
			}
			
		}
	}
	
	@SuppressWarnings("rawtypes")
	public LinkedHashMap handerUntouched(LinkedHashMap m ,String fieldname,String defaulttype){
		LinkedHashMap<String, Object> temp = new LinkedHashMap<String, Object>();
		LinkedHashMap<String, Object> temp1 = new LinkedHashMap<String, Object>();
		temp1.put("type",defaulttype);
		temp1.put("store", "true");
		temp1.put("index", true);
		if("text".equals(defaulttype)){
			temp1.put("analyzer", "ik_max_word");
			temp1.put("search_analyzer", "ik_smart");
		}
		temp.put(fieldname, temp1);
		Map<String, Object> temp2 = new HashMap<String, Object>();
		temp2.put("type", "keyword");
		temp2.put("store", "true");
		temp2.put("index", true);
		temp.put("untouched", temp2);
		m.put("type", defaulttype);
		m.put("fields",temp);
		return m;
	}
 
}


/**
 * 接口关系:
 * ElasticsearchRepository --> ElasticsearchCrudRepository --> PagingAndSortingRepository --> CrudRepository
 * @param <T>
 */
@Repository
public interface CodeInfoRepository extends ElasticsearchRepository<CodeInfo , String> {

}

/**
基本索引字段bean,对应mapping结构
**/
@Document(indexName = "base_index_name",type = "index")
public class CodeInfo {
    @ID
    @Field(type = FieldType.Keyword,index=true,store=true)
    private String codeid;
    
    @Field(type = FieldType.Text, analyzer = "ik_max_word",searchAnalyzer="ik_smart",index=true,store=true)
    private String desc1;
    
    @Field(type = FieldType.Text, analyzer = "ik_max_word",searchAnalyzer="ik_smart",index=true,store=true)
    private String desc2;
    
    //子文档
    @Field(type = FieldType.Nested,index = true,store=true)
    private List<CodeChildrenInfo> codeChildrenInfos;
    //......
    //get和set方法
}


public class CodeChildrenInfo {
    @ID
    @Field(type = FieldType.Keyword,index=true,store=true)
    private String codeChildrenid;
    
    @Field(type = FieldType.Keyword,index=true,store=true)
    private String codeid;
    
 @Field(type = FieldType.Text, analyzer = "ik_max_word",searchAnalyzer="ik_smart",index=true,store=true)
    private String desc1;
    //......
    //get和set方法
}

/**
定义连接9300的client,防止template模版串了,导致查询到别的索引的数据
**/
@Configuration
@EnableConfigurationProperties(ElasticsearchProperties.class)
public class ESTransportClient{
    
    @value("${spring.data.elasticsearch.cluster-name:elasticsearch}")
    private String clustername;
    @value("${spring.data.elasticsearch.cluster-nodes:127.0.0.1:9300}")
    private String clusternodes;

    private TransportClient client=null;
    private final ElasticsearchProperties properties;
    public ESTransportClient(ElasticsearchProperties properties){
         this.properties=properties;
    }

    @Bean
    public TransportClient client(){
        if(client!=null){
          return client;
        }else {
          //建立连接
            ......
        }
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hspringh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值