feat: 升级es8.0

This commit is contained in:
jaime 2025-02-25 16:37:43 +08:00
parent e6317a4da8
commit 4f193f0f24
86 changed files with 3230 additions and 2138 deletions

View File

@ -46,7 +46,7 @@ Easy-Es是一款简化ElasticSearch搜索引擎操作的开源框架,全自动
简化`CRUD`及其它高阶操作,可以更好的帮助开发者减轻开发负担
底层采用Es官方提供的RestHighLevelClient,保证其原生性能及拓展性.
底层采用Es官方提供的ElasticsearchClient,保证其原生性能及拓展性.
技术讨论 QQ 群 897570597 群内可在群文件中免费领取 颈椎保护 | 增肌 | 减脂 等健身计划 无套路
@ -62,7 +62,7 @@ Easy-Es是一款简化ElasticSearch搜索引擎操作的开源框架,全自动
- **全自动索引托管:** 全球开源首创的索引托管模式,开发者无需关心索引的创建更新及数据迁移等繁琐步骤,索引全生命周期皆可托管给框架,由框架自动完成,过程零停机,用户无感知,彻底解放开发者
- **智能字段类型推断:** 根据索引类型和当前查询类型上下文综合智能判断当前查询是否需要拼接.keyword后缀,减少小白误用的可能
- **屏蔽语言差异:** 开发者只需要会MySQL语法即可使用Es
- **代码量极少:** 与直接使用RestHighLevelClient相比,相同的查询平均可以节3-80倍左右的代码量
- **代码量极少:** 与直接使用ElasticsearchClient相比,相同的查询平均可以节3-80倍左右的代码量
- **零魔法值:** 字段名称直接从实体中获取,无需输入字段名称字符串这种魔法值
- **零额外学习成本:** 开发者只要会国内最受欢迎的Mybatis-Plus语法,即可无缝迁移至Easy-Es
- **降低开发者门槛:** 即便是只了解ES基础的初学者也可以轻松驾驭ES完成绝大多数需求的开发
@ -82,7 +82,7 @@ Easy-Es是一款简化ElasticSearch搜索引擎操作的开源框架,全自动
```java
// 传统方式, 直接用RestHighLevelClient进行查询 需要19行代码,还不包含下划线转驼峰,自定义字段处理及_id处理等代码
// 传统方式, 直接用ElasticsearchClient进行查询 需要19行代码,还不包含下划线转驼峰,自定义字段处理及_id处理等代码
String indexName = "document";
SearchRequest searchRequest = new SearchRequest(indexName);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
@ -90,7 +90,7 @@ Easy-Es是一款简化ElasticSearch搜索引擎操作的开源框架,全自动
TermsQueryBuilder creatorTerm = QueryBuilders.termsQuery("creator", "码保国");
boolQueryBuilder.must(titleTerm);
boolQueryBuilder.must(creatorTerm);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
try {

View File

@ -21,7 +21,7 @@
## What is Easy-Es?
---
Easy-Es is a powerfully enhanced toolkit of RestHighLevelClient for simplify development. This toolkit provides some efficient, useful, out-of-the-box features for ElasticSearch. By using Easy-Es, you can use MySQL syntax to complete Es queries. Use it can effectively save your development time.
Easy-Es is a powerfully enhanced toolkit of ElasticsearchClient for simplify development. This toolkit provides some efficient, useful, out-of-the-box features for ElasticSearch. By using Easy-Es, you can use MySQL syntax to complete Es queries. Use it can effectively save your development time.
## Official website
---
@ -69,7 +69,7 @@ LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
```
```java
// Query with RestHighLevelClient requires 11 lines of code, not including parsing JSON code
// Query with ElasticsearchClient requires 11 lines of code, not including parsing JSON code
String indexName = "document";
SearchRequest searchRequest = new SearchRequest(indexName);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
@ -77,7 +77,7 @@ String indexName = "document";
TermsQueryBuilder creatorTerm = QueryBuilders.termsQuery("creator", "Guy");
boolQueryBuilder.must(titleTerm);
boolQueryBuilder.must(creatorTerm);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
try {
@ -166,8 +166,8 @@ String indexName = "document";
| max | max |AggregationBuilders.max|
| avg | avg |AggregationBuilders.avg|
| sum | sum |AggregationBuilders.sum|
| order by xxx asc | orderByAsc | fieldSortBuilder.order(SortOrder.ASC)|
| order by xxx desc | orderByDesc |fieldSortBuilder.order(SortOrder.DESC)|
| order by xxx asc | orderByAsc | fieldSortBuilder.order(SortOrder.Asc)|
| order by xxx desc | orderByDesc |fieldSortBuilder.order(SortOrder.Desc)|
| - | match |matchQuery|
| - | matchPhrase |QueryBuilders.matchPhraseQuery|
| - | matchPrefix |QueryBuilders.matchPhrasePrefixQuery|

View File

@ -14,8 +14,15 @@
<artifactId>easy-es-annotation</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -2,7 +2,7 @@ package org.dromara.easyes.annotation;
import org.dromara.easyes.annotation.rely.Analyzer;
import org.dromara.easyes.annotation.rely.DefaultNestedClass;
import org.dromara.easyes.annotation.rely.DefaultNestedOrObjectClass;
import org.dromara.easyes.annotation.rely.FieldStrategy;
import org.dromara.easyes.annotation.rely.FieldType;
@ -115,5 +115,5 @@ public @interface IndexField {
*
* @return 默认嵌套类
*/
Class<?> nestedClass() default DefaultNestedClass.class;
Class<?> nestedOrObjectClass() default DefaultNestedOrObjectClass.class;
}

View File

@ -36,7 +36,7 @@ public @interface Settings {
*
* @return 默认1w条
*/
int maxResultWindow() default DEFAULT_MAX_RESULT_WINDOW;
long maxResultWindow() default DEFAULT_MAX_RESULT_WINDOW;
/**
* 索引的刷新间隔 es默认值为1s ms表示毫秒 s表示秒 m表示分钟

View File

@ -29,7 +29,7 @@ public interface AnnotationConstants {
/**
* 默认最大返回数
*/
int DEFAULT_MAX_RESULT_WINDOW = 10000;
long DEFAULT_MAX_RESULT_WINDOW = 10000L;
/**
* 默认索引别名
*/

View File

@ -5,5 +5,5 @@ package org.dromara.easyes.annotation.rely;
* <p>
* Copyright © 2021 xpc1024 All Rights Reserved
**/
public class DefaultNestedClass {
public class DefaultNestedOrObjectClass {
}

View File

@ -1,7 +1,6 @@
package org.dromara.easyes.annotation.rely;
import java.util.Collections;
import java.util.Map;
import co.elastic.clients.elasticsearch.indices.IndexSettings;
/**
* es 索引 默认settings 如需拓展须继承此类并覆写getSettings方法提供自定义索引settings实现
@ -10,7 +9,6 @@ import java.util.Map;
**/
public class DefaultSettingsProvider implements ISettingsProvider {
@Override
public Map<String, Object> getSettings() {
return Collections.emptyMap();
public void settings(IndexSettings.Builder builder) {
}
}

View File

@ -25,7 +25,6 @@ public enum FieldType {
SCALED_FLOAT("scaled_float"),
BOOLEAN("boolean"),
DATE("date"),
RANGE("range"),
BINARY("binary"),
KEYWORD("keyword"),
TEXT("text"),
@ -34,18 +33,6 @@ public enum FieldType {
*/
KEYWORD_TEXT("keyword&text"),
WILDCARD("wildcard"),
/**
* mix
*/
/**
* If it is an array, configure its field type to text, and use match for query如果是数组请配置其字段类型为text查询用match
*/
@Deprecated
ARRAY("array"),
/**
* If it is an object, configure its field type as nested, and indicate nested Class如果是对象请配置其字段类型为nested并在@IndexField注解中指明nestedClass
*/
@Deprecated
OBJECT("object"),
NESTED("nested"),
JOIN("join"),

View File

@ -1,6 +1,6 @@
package org.dromara.easyes.annotation.rely;
import java.util.Map;
import co.elastic.clients.elasticsearch.indices.IndexSettings;
/**
* es 索引 settings 提供接口
@ -10,8 +10,6 @@ import java.util.Map;
public interface ISettingsProvider {
/**
* 获取settings
*
* @return settingsMap
*/
Map<String, Object> getSettings();
void settings(IndexSettings.Builder builder);
}

View File

@ -13,8 +13,8 @@
<artifactId>easy-es-boot-starter</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<dependencies>

View File

@ -1,13 +1,9 @@
package org.dromara.easyes.starter;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import org.dromara.easyes.common.property.EasyEsDynamicProperties;
import org.dromara.easyes.common.property.EasyEsProperties;
import org.dromara.easyes.common.strategy.AutoProcessIndexStrategy;
import org.dromara.easyes.common.utils.RestHighLevelClientUtils;
import org.dromara.easyes.core.index.AutoProcessIndexNotSmoothlyStrategy;
import org.dromara.easyes.core.index.AutoProcessIndexSmoothlyStrategy;
import org.dromara.easyes.spring.factory.IndexStrategyFactory;
import org.elasticsearch.client.RestHighLevelClient;
import org.dromara.easyes.common.utils.EsClientUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@ -16,28 +12,26 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
/**
* es自动配置
* <p>
* Copyright © 2021 xpc1024 All Rights Reserved
**/
@Configuration
@ConditionalOnClass(RestHighLevelClient.class)
@ConditionalOnClass(ElasticsearchClient.class)
@ConditionalOnExpression("'${easy-es.address:x}'!='x'")
@ConditionalOnProperty(prefix = "easy-es", name = {"enable"}, havingValue = "true", matchIfMissing = true)
public class EsAutoConfiguration {
/**
* 装配RestHighLevelClient
* 装配ElasticsearchClient
*
* @return RestHighLevelClient bean
* @return ElasticsearchClient bean
*/
@Bean
@ConditionalOnMissingBean
public RestHighLevelClient restHighLevelClient() {
return RestHighLevelClientUtils.restHighLevelClient(easyEsProperties());
public ElasticsearchClient elasticClient() {
return EsClientUtils.buildClient(easyEsProperties());
}
@Bean

View File

@ -1,8 +1,8 @@
package org.dromara.easyes.starter.config;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import org.dromara.easyes.core.config.GeneratorConfig;
import org.dromara.easyes.core.toolkit.Generator;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -15,7 +15,7 @@ import org.springframework.stereotype.Component;
public class GeneratorConfiguration extends Generator {
@Autowired
private RestHighLevelClient client;
private ElasticsearchClient client;
@Override
public Boolean generate(GeneratorConfig config) {

View File

@ -13,8 +13,8 @@
<artifactId>easy-es-common</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<dependencies>
@ -22,22 +22,50 @@
<groupId>org.dromara.easy-es</groupId>
<artifactId>easy-es-annotation</artifactId>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<artifactId>elasticsearch-geo</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version> <!-- 或者更高版本 -->
<configuration>
<source>21</source>
<target>21</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,5 +1,8 @@
package org.dromara.easyes.common.constants;
import co.elastic.clients.elasticsearch._types.Conflicts;
import co.elastic.clients.elasticsearch._types.OpType;
/**
* EasyEs的常量
* <p>
@ -174,11 +177,11 @@ public interface BaseEsConstants {
/**
* 默认迁移操作规则
*/
String DEFAULT_DEST_OP_TYPE = "create";
OpType DEFAULT_DEST_OP_TYPE = OpType.Create;
/**
* 默认冲突处理
*/
String DEFAULT_CONFLICTS = "proceed";
Conflicts DEFAULT_CONFLICTS = Conflicts.Proceed;
/**
* 更新索引时自动创建的索引后缀s 灵感来源于jvm young区s0,s1垃圾回收
*/

View File

@ -1,6 +1,6 @@
package org.dromara.easyes.common.strategy;
import org.elasticsearch.client.RestHighLevelClient;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
/**
* 自动托管索引策略接口
@ -21,5 +21,5 @@ public interface AutoProcessIndexStrategy {
* @param entityClass 实体类
* @param client restHighLevelClient
*/
void processIndexAsync(Class<?> entityClass, RestHighLevelClient client);
void processIndexAsync(Class<?> entityClass, ElasticsearchClient client);
}

View File

@ -1,9 +1,8 @@
package org.dromara.easyes.common.utils;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import java.io.IOException;
import java.util.Optional;
@ -43,11 +42,11 @@ public class EEVersionUtils {
* @param restHighLevelClient es高级客户端
* @return client version
*/
public static String getClientVersion(RestHighLevelClient restHighLevelClient) {
public static String getClientVersion(ElasticsearchClient restHighLevelClient) {
try {
return restHighLevelClient.info(RequestOptions.DEFAULT)
.getVersion()
.getNumber();
return restHighLevelClient.info()
.version()
.number();
} catch (IOException e) {
LogUtils.formatWarn("get client version error");
}

View File

@ -1,5 +1,8 @@
package org.dromara.easyes.common.utils;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
@ -11,52 +14,49 @@ import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
import org.apache.http.ssl.SSLContextBuilder;
import org.dromara.easyes.common.enums.SchemaEnum;
import org.dromara.easyes.common.property.EasyEsProperties;
import org.dromara.easyes.common.utils.jackson.JsonUtils;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import javax.net.ssl.SSLContext;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import static org.dromara.easyes.common.constants.BaseEsConstants.*;
/**
* @author lyy
*/
public class RestHighLevelClientUtils {
public class EsClientUtils {
public static final String DEFAULT_DS = "DEFAULT_DS";
private final static Map<String, RestHighLevelClient> restHighLevelClientMap = new ConcurrentHashMap<>();
private final static Map<String, ElasticsearchClient> restHighLevelClientMap = new ConcurrentHashMap<>();
public RestHighLevelClientUtils() {
public EsClientUtils() {
}
public static RestHighLevelClient getRestHighLevelClient(String restHighLevelClientId) {
public static ElasticsearchClient getElasticsearchClient(String restHighLevelClientId) {
if (DEFAULT_DS.equals(restHighLevelClientId)) {
return restHighLevelClientMap.values()
.stream()
.findFirst()
.orElseThrow(() -> ExceptionUtils.eee("Could not found RestHighLevelClient,restHighLevelClientId:%s", restHighLevelClientId));
.orElseThrow(() -> ExceptionUtils.eee("Could not found ElasticsearchClient,restHighLevelClientId:%s", restHighLevelClientId));
}
RestHighLevelClient restHighLevelClient = restHighLevelClientMap.get(restHighLevelClientId);
if (restHighLevelClient == null) {
ElasticsearchClient client = restHighLevelClientMap.get(restHighLevelClientId);
if (client == null) {
LogUtils.formatError("restHighLevelClientId: %s can not find any data source, please check your config", restHighLevelClientId);
throw ExceptionUtils.eee("Cloud not found RestHighLevelClient,restHighLevelClientId:%s", restHighLevelClientId);
throw ExceptionUtils.eee("Cloud not found ElasticsearchClient,restHighLevelClientId:%s", restHighLevelClientId);
}
return restHighLevelClient;
return client;
}
public RestHighLevelClient getClient(String restHighLevelClientId) {
return RestHighLevelClientUtils.getRestHighLevelClient(restHighLevelClientId);
public static void registerClient(String restHighLevelClientId, Supplier<ElasticsearchClient> restHighLevelClient) {
EsClientUtils.restHighLevelClientMap.putIfAbsent(restHighLevelClientId, restHighLevelClient.get());
}
public static void registerRestHighLevelClient(String restHighLevelClientId, RestHighLevelClient restHighLevelClient) {
RestHighLevelClientUtils.restHighLevelClientMap.putIfAbsent(restHighLevelClientId, restHighLevelClient);
}
public static RestHighLevelClient restHighLevelClient(EasyEsProperties easyEsConfigProperties) {
public static ElasticsearchClient buildClient(EasyEsProperties easyEsConfigProperties) {
// 处理地址
String address = easyEsConfigProperties.getAddress();
if (StringUtils.isEmpty(address)) {
@ -118,6 +118,11 @@ public class RestHighLevelClientUtils {
.ifPresent(requestConfigBuilder::setConnectionRequestTimeout);
return requestConfigBuilder;
});
return new RestHighLevelClient(builder);
return new ElasticsearchClient(new RestClientTransport(builder.build(), new JacksonJsonpMapper(JsonUtils.base())));
}
public ElasticsearchClient getClient(String clientId) {
return getElasticsearchClient(clientId);
}
}

View File

@ -1,33 +1,33 @@
package org.dromara.easyes.common.utils;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.util.Set;
/**
* fastjson 工具类
* <p>
* Copyright © 2022 xpc1024 All Rights Reserved
**/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class FastJsonUtils {
/**
* 设置fastjson toJsonString字段
*
* @param clazz
* @param fields 字段列表
* @return 前置过滤器
*/
public static SimplePropertyPreFilter getSimplePropertyPreFilter(Class<?> clazz, Set<String> fields) {
if (CollectionUtils.isEmpty(fields)) {
return null;
}
SimplePropertyPreFilter simplePropertyPreFilter = new SimplePropertyPreFilter(clazz);
fields.forEach(field -> simplePropertyPreFilter.getExcludes().add(field));
return simplePropertyPreFilter;
}
}
//package org.dromara.easyes.common.utils;
//
//import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
//import lombok.AccessLevel;
//import lombok.NoArgsConstructor;
//
//import java.util.Set;
//
///**
// * fastjson 工具类
// * <p>
// * Copyright © 2022 xpc1024 All Rights Reserved
// **/
//@NoArgsConstructor(access = AccessLevel.PRIVATE)
//public class FastJsonUtils {
// /**
// * 设置fastjson toJsonString字段
// *
// * @param clazz
// * @param fields 字段列表
// * @return 前置过滤器
// */
// public static SimplePropertyPreFilter getSimplePropertyPreFilter(Class<?> clazz, Set<String> fields) {
// if (CollectionUtils.isEmpty(fields)) {
// return null;
// }
// SimplePropertyPreFilter simplePropertyPreFilter = new SimplePropertyPreFilter(clazz);
// fields.forEach(field -> simplePropertyPreFilter.getExcludes().add(field));
// return simplePropertyPreFilter;
// }
//
//
//}

View File

@ -1,60 +0,0 @@
package org.dromara.easyes.common.utils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import static org.dromara.easyes.common.constants.BaseEsConstants.UNKNOWN;
/**
* elasticsearch 构造器
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class RestHighLevelClientBuilder {
/**
* 支持的版本 目前支持版本为7.17.8 稳定无漏洞版
*/
private final static String SUPPORTED_JAR_VERSION = "7.17.8";
/**
* 支持的客户端版本 目前支持7.xx 推荐7.17.8
*/
private final static String SUPPORTED_CLIENT_VERSION = "7";
/**
* 构建RestHighLevelClient
*
* @param builder 构建连接对象
* @return es高级客户端
*/
public static RestHighLevelClient build(RestClientBuilder builder) {
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(builder);
// 检验es版本是否对应
verify(restHighLevelClient);
return restHighLevelClient;
}
/**
* 校验es client版本及jar包版本
*
* @param restHighLevelClient es高级客户端
*/
private static void verify(RestHighLevelClient restHighLevelClient) {
// 校验jar包版本是否为推荐使用版本
String jarVersion = EEVersionUtils.getJarVersion(restHighLevelClient.getClass());
LogUtils.formatInfo("Elasticsearch jar version:%s", jarVersion);
if (!jarVersion.equals(SUPPORTED_JAR_VERSION) && !UNKNOWN.equals(jarVersion)) {
LogUtils.formatError("Easy-Es supported elasticsearch and restHighLevelClient jar version is:%s ,Please resolve the dependency conflict!", SUPPORTED_JAR_VERSION);
}
String clientVersion = EEVersionUtils.getClientVersion(restHighLevelClient);
LogUtils.formatInfo("Elasticsearch client version:%s", clientVersion);
if (!clientVersion.startsWith(SUPPORTED_CLIENT_VERSION)) {
// 这里校验客户端为非强制客户端版本非推荐版本对应提醒即可es会报错提醒
LogUtils.formatWarn("Easy-Es supported elasticsearch client version is:%s.xx", SUPPORTED_CLIENT_VERSION);
}
if (!jarVersion.equals(clientVersion)) {
// 提示jar包与客户端版本不对应es官方推荐jar包版本对应客户端版本
LogUtils.formatWarn("Elasticsearch clientVersion:%s not equals jarVersion:%s, It does not affect your use, but we still recommend keeping it consistent!", clientVersion, jarVersion);
}
}
}

View File

@ -0,0 +1,105 @@
package org.dromara.easyes.common.utils.jackson;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonIncludeProperties;
import com.fasterxml.jackson.databind.PropertyName;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.introspect.*;
import java.util.Optional;
/**
* jackson自定义注解解析
*
* @author jaime
* @version 1.0
* @since 2025/2/21
*/
public class JacksonCustomAnnotationIntrospector extends JacksonAnnotationIntrospector {
/**
* 获取序列化和反序列化时的名称
*/
private static PropertyName getPropertyName(Annotated m) {
if (m instanceof AnnotatedField f) {
JacksonCustomConfig config = JacksonCustomConfig.jacksonConfigMap.get(f.getDeclaringClass());
if (config != null) {
String jsonName = config.javaJsonFieldNameMap.get(f.getName());
if (jsonName != null) {
return new PropertyName(jsonName);
}
}
}
return null;
}
/**
* 序列化名称
* 序列化
*/
@Override
public PropertyName findNameForSerialization(Annotated m) {
return Optional.ofNullable(getPropertyName(m)).orElse(super.findNameForSerialization(m));
}
/**
* 反序列化名称
* 反序列化
*/
@Override
public PropertyName findNameForDeserialization(Annotated m) {
return Optional.ofNullable(getPropertyName(m)).orElse(super.findNameForDeserialization(m));
}
/**
* 字段包含
* 序列化 + 反序列化
*/
@Override
public JsonIncludeProperties.Value findPropertyInclusionByName(MapperConfig<?> c, Annotated a) {
if (a instanceof AnnotatedClass f) {
JacksonCustomConfig config = JacksonCustomConfig.jacksonConfigMap.get(f.getAnnotated());
if (config != null) {
return config.allJsonField;
}
}
return super.findPropertyInclusionByName(c, a);
}
/**
* 时间格式
* 序列化 + 反序列化
*/
@Override
public JsonFormat.Value findFormat(Annotated a) {
if (a instanceof AnnotatedMethod f) {
JacksonCustomConfig config = JacksonCustomConfig.jacksonConfigMap.get(f.getDeclaringClass());
if (config != null) {
JsonFormat.Value value = config.formatMap.get(f.getName());
if (value != null) {
return value;
}
}
}
return super.findFormat(a);
}
/**
* 是否包含
* 序列化
*/
@Override
public JsonInclude.Value findPropertyInclusion(Annotated a) {
if (a instanceof AnnotatedMember f) {
JacksonCustomConfig config = JacksonCustomConfig.jacksonConfigMap.get(f.getDeclaringClass());
if (config != null) {
JsonInclude.Value value = config.includeMap.get(f.getName());
if (value != null) {
return value;
}
}
}
return super.findPropertyInclusion(a);
}
}

View File

@ -0,0 +1,52 @@
package org.dromara.easyes.common.utils.jackson;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonIncludeProperties;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
/**
* jackson自定义配置
*
* @author jaime
* @version 1.0
* @since 2025/2/21
*/
@Data
public class JacksonCustomConfig {
public static Map<Class<?>, JacksonCustomConfig> jacksonConfigMap = new HashMap<>();
/**
* 类名
*/
public Class<?> clz;
/**
* 字段名称映射
* java字段 - json字段
*/
public Map<String, String> javaJsonFieldNameMap = new HashMap<>();
/**
* 所有json字段名称
*/
public JsonIncludeProperties.Value allJsonField = JsonIncludeProperties.Value.all();
/**
* 序列化时时间格式配置
* get/set方法名称 - 配置
*/
public Map<String, JsonFormat.Value> formatMap = new HashMap<>();
/**
* 序列化时, 是否序列化
* get方法名称/java字段名称 - 配置
*/
public Map<String, JsonInclude.Value> includeMap = new HashMap<>();
}

View File

@ -0,0 +1,368 @@
package org.dromara.easyes.common.utils.jackson;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.dromara.easyes.common.utils.StringUtils;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* JSON工具类
*
* @author jaime
* @version 1.0
* @since 2023/08/09
*/
public class JsonUtils {
/**
* 默认jackson配置
* 不打印类信息
* 时间序列化为字符串
*/
public static final ObjectMapper OM_DEFAULT = base();
private static final DefaultPrettyPrinter DEFAULT_PRETTY_PRINTER = new DefaultPrettyPrinter();
public static JsonMapper base() {
JsonMapper base = JsonMapper.builder()
// 反序列化时是否将一个对象封装成单元素数组
.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
.configure(SerializationFeature.INDENT_OUTPUT, false)
.build();
AnnotationIntrospector anno = base.getSerializerProviderInstance().getAnnotationIntrospector();
base.setAnnotationIntrospector(new AnnotationIntrospectorPair(anno, new JacksonCustomAnnotationIntrospector()));
return base;
}
/**
* 打印字符串
*
* @param data 数据
* @return json字符串
*/
public static String toJsonStr(Object data) {
return toJsonStr(OM_DEFAULT, data);
}
/**
* 字符数组
*
* @param data 数据
* @return json字符串
*/
public static byte[] toBytes(Object data) {
return toBytes(OM_DEFAULT, data);
}
/**
* 格式化打印字符串
*
* @param data 数据
* @return json字符串
*/
public static String toJsonPrettyStr(Object data) {
return toJsonPrettyStr(OM_DEFAULT, data);
}
/**
* 字符串 == bean
*
* @param json 字符串
* @param type 类型
* @param <T> 数据泛型
* @return bean
*/
public static <T> T toBean(String json, Class<T> type) {
return toBean(OM_DEFAULT, json, type);
}
/**
* 字符串 == bean
*
* @param json 字符串
* @param type 类型
* @param <T> 数据泛型
* @return bean
*/
public static <T> T toBean(String json, TypeReference<T> type) {
return toBean(OM_DEFAULT, json, type);
}
/**
* 字符串 == bean
*
* @param json 字符串
* @param type 类型
* @param <T> 数据泛型
* @return bean
*/
public static <T> T toBean(String json, Type type) {
return toBean(OM_DEFAULT, json, type);
}
/**
* 字符串 == List
*
* @param json 字符串
* @param <V> 数据泛型
* @return List
*/
public static <V> List<V> toList(String json, Class<V> v) {
return toList(OM_DEFAULT, json, v);
}
/**
* 字符串 == Set
*
* @param json 字符串
* @param <V> 数据泛型
* @return Set
*/
public static <V> Set<V> toSet(String json, Class<V> v) {
return toSet(OM_DEFAULT, json, v);
}
/**
* 字符串 == Map
*
* @param json 字符串
* @param <K> 键泛型
* @param <V> 值泛型
* @return Map
*/
public static <K, V> Map<K, V> toMap(String json, Class<K> k, Class<V> v) {
return toMap(OM_DEFAULT, json, k, v);
}
/**
* 字符串 == 集合Map, List, Set等
*
* @param json 字符串
* @param parametrized 主类型
* @param parameterClasses 类型参数
* @param <T> 集合泛型
* @return 集合
* @throws Exception 异常
*/
public static <T> T toCollection(String json, Class<?> parametrized, Class<?>... parameterClasses) throws Exception {
return toCollection(OM_DEFAULT, json, parametrized, parameterClasses);
}
/**
* 字符串 == JsonNode
*
* @param json 字符串
* @return JsonNode
*/
public static JsonNode readTree(String json) {
return readTree(OM_DEFAULT, json);
}
/**
* 打印字符串
*
* @param data 数据
* @return json字符串
*/
public static String toJsonStr(ObjectMapper om, Object data) {
try {
if (data == null) {
return null;
}
return om.writeValueAsString(data);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 字符数组
*
* @param data 数据
* @return json字符串
*/
public static byte[] toBytes(ObjectMapper om, Object data) {
try {
if (data == null) {
return null;
}
return om.writeValueAsBytes(data);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 格式化打印字符串
*
* @param data 数据
* @return json字符串
*/
public static String toJsonPrettyStr(ObjectMapper om, Object data) {
try {
if (data == null) {
return null;
}
return om.writer(DEFAULT_PRETTY_PRINTER).writeValueAsString(data);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 字符串 == bean
*
* @param json 字符串
* @param type 类型
* @param <T> 数据泛型
* @return bean
*/
public static <T> T toBean(ObjectMapper om, String json, Class<T> type) {
try {
if (StringUtils.isEmpty(json)) {
return null;
}
return om.readValue(json, type);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}
/**
* 字符串 == bean
*
* @param json 字符串
* @param type 类型
* @param <T> 数据泛型
* @return bean
*/
public static <T> T toBean(ObjectMapper om, String json, TypeReference<T> type) {
try {
if (StringUtils.isEmpty(json)) {
return null;
}
return om.readValue(json, type);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}
/**
* 字符串 == bean
*
* @param json 字符串
* @param type 类型
* @param <T> 数据泛型
* @return bean
*/
public static <T> T toBean(ObjectMapper om, String json, Type type) {
try {
if (StringUtils.isEmpty(json)) {
return null;
}
return om.readValue(json, TypeFactory.defaultInstance().constructType(type));
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}
/**
* 字符串 == List
*
* @param json 字符串
* @param <V> 数据泛型
* @return List
*/
public static <V> List<V> toList(ObjectMapper om, String json, Class<V> v) {
try {
return toCollection(om, json, List.class, v);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 字符串 == Set
*
* @param json 字符串
* @param <V> 数据泛型
* @return Set
*/
public static <V> Set<V> toSet(ObjectMapper om, String json, Class<V> v) {
try {
return toCollection(om, json, Set.class, v);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 字符串 == Map
*
* @param json 字符串
* @param <K> 键泛型
* @param <V> 值泛型
* @return Map
*/
public static <K, V> Map<K, V> toMap(ObjectMapper om, String json, Class<K> k, Class<V> v) {
try {
return toCollection(om, json, Map.class, k, v);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 字符串 == 集合Map, List, Set等
*
* @param json 字符串
* @param parametrized 主类型
* @param parameterClasses 类型参数
* @param <T> 集合泛型
* @return 集合
* @throws Exception 异常
*/
public static <T> T toCollection(ObjectMapper om, String json, Class<?> parametrized, Class<?>... parameterClasses) throws Exception {
if (StringUtils.isEmpty(json)) {
return null;
}
JavaType type = om.getTypeFactory().constructParametricType(parametrized, parameterClasses);
return om.readValue(json, type);
}
/**
* 字符串 == JsonNode
*
* @param json 字符串
* @return JsonNode
*/
public static JsonNode readTree(ObjectMapper om, String json) {
try {
if (StringUtils.isEmpty(json)) {
return null;
}
return om.readTree(json);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -14,8 +14,8 @@
<artifactId>easy-es-core</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<dependencies>

View File

@ -1,13 +1,11 @@
package org.dromara.easyes.core.biz;
import org.dromara.easyes.common.enums.OrderTypeEnum;
import co.elastic.clients.elasticsearch._types.*;
import lombok.Builder;
import lombok.Data;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.dromara.easyes.common.enums.OrderTypeEnum;
import java.util.List;
/**
* 排序基本参数
@ -30,7 +28,7 @@ public class BaseSortParam {
/**
* 用户自定义的原生语法排序器
*/
private SortBuilder<?> sortBuilder;
private SortOptions sortBuilder;
/**
* 排序类型
@ -40,7 +38,7 @@ public class BaseSortParam {
/**
* 计算方式 ARC PLANE 默认PLANE
*/
private GeoDistance geoDistance;
private GeoDistanceType geoDistance;
/**
* 距离单位 默认为km
*/
@ -48,5 +46,5 @@ public class BaseSortParam {
/**
* 排序坐标点
*/
private GeoPoint[] geoPoints;
private List<GeoLocation> geoPoints;
}

View File

@ -1,11 +1,11 @@
package org.dromara.easyes.core.biz;
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
import co.elastic.clients.elasticsearch.indices.IndexSettings;
import lombok.Data;
import org.elasticsearch.common.settings.Settings;
import java.util.List;
import java.util.Map;
/**
* 创建索引参数
@ -37,7 +37,7 @@ public class CreateIndexParam {
/**
* 最大返回数
*/
private Integer maxResultWindow;
private Long maxResultWindow;
/**
* 索引字段及类型分词器等信息
*/
@ -45,13 +45,13 @@ public class CreateIndexParam {
/**
* 用户手动指定的mapping信息,优先级最高
*/
private Map<String, Object> mapping;
private TypeMapping.Builder mapping;
/**
* 用户通过自定义注解指定的settings信息
*/
private Map<String, Object> settingsMap;
private IndexSettings.Builder indexSettings;
/**
* 用户手动指定的settings信息,优先级最高
*/
private Settings settings;
private IndexSettings.Builder settings;
}

View File

@ -1,8 +1,8 @@
package org.dromara.easyes.core.biz;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.parser.deserializer.ExtraProcessor;
import com.alibaba.fastjson.serializer.SerializeFilter;
import co.elastic.clients.elasticsearch.indices.IndexSettings;
import co.elastic.clients.transport.TransportOptions;
import co.elastic.clients.transport.rest_client.RestClientOptions;
import lombok.Data;
import lombok.experimental.Accessors;
import org.dromara.easyes.annotation.rely.IdType;
@ -28,9 +28,9 @@ import static org.dromara.easyes.common.constants.BaseEsConstants.ZERO;
@Accessors(chain = true)
public class EntityInfo {
/**
* 请求配置 默认值为官方内置的默认配置
* 嵌套类 实体字段->高亮返回结果字段
*/
private RequestOptions requestOptions = RequestOptions.DEFAULT;
private final Map<Class<?>, Map<String, String>> nestedOrObjectHighlightFieldMap = new HashMap<>();
/**
* 表主键ID 类型
*/
@ -56,9 +56,9 @@ public class EntityInfo {
*/
private String retrySuccessIndexName;
/**
* 最大返回数
* 嵌套类不需要序列化JSON的字段 不存在字段,高亮字段等
*/
private Integer maxResultWindow = DEFAULT_MAX_RESULT_WINDOW;
private final Map<Class<?>, Set<String>> nestedOrObjectNotSerializeField = new HashMap<>();
/**
* 表映射结果集
*/
@ -116,9 +116,9 @@ public class EntityInfo {
*/
private Class<?> joinFieldClass = JoinField.class;
/**
* 嵌套类的字段信息列表
* 嵌套类 实体字段名->字段类型
*/
private Map<Class<?>, List<EntityFieldInfo>> nestedFieldListMap = new HashMap<>();
private final Map<Class<?>, Map<String, String>> nestedOrObjectClassFieldTypeMap = new HashMap<>();
/**
* 表字段信息列表
*/
@ -148,25 +148,17 @@ public class EntityInfo {
*/
private List<HighLightParam> highlightParams = new ArrayList<>();
/**
* 嵌套类-高亮字段列表
* 嵌套类 实体字段->es实际字段映射
*/
private Map<Class<?>, List<HighLightParam>> nestedHighLightParamsMap = new HashMap<>();
/**
* fastjson 字段命名策略
*/
private PropertyNamingStrategy propertyNamingStrategy;
/**
* fastjson 实体中不存在的字段处理器
*/
private ExtraProcessor extraProcessor;
private final Map<Class<?>, Map<String, String>> nestedOrObjectClassMappingColumnMap = new HashMap<>();
/**
* 实体字段->高亮返回结果 键值对
*/
private final Map<String, String> highlightFieldMap = new HashMap<>();
/**
* 嵌套类 实体字段->高亮返回结果字段
* 嵌套类型 es实际字段映射->实体字段 (仅包含被重命名字段)
*/
private final Map<Class<?>, Map<String, String>> nestedHighlightFieldMap = new HashMap<>();
private final Map<Class<?>, Map<String, String>> nestedOrObjectClassColumnMappingMap = new HashMap<>();
/**
* 实体字段名->es字段类型
*/
@ -184,33 +176,29 @@ public class EntityInfo {
*/
private final Set<String> notSerializeField = new HashSet<>();
/**
* 嵌套类不需要序列化JSON的字段 不存在字段,高亮字段等
* 父子类型 join字段名字 K为父,v为子
*/
private final Map<Class<?>, Set<String>> nestedNotSerializeField = new HashMap<>();
private final Map<String, List<String>> relationMap = new HashMap<>();
/**
* 嵌套类型 path和class对应关系
*/
private final Map<String, Class<?>> pathClassMap = new HashMap<>();
/**
* 嵌套类型 实体字段名->字段类型
* 通过自定义注解指定的索引settings
*/
private final Map<Class<?>, Map<String, String>> nestedClassFieldTypeMap = new HashMap<>();
private final IndexSettings.Builder indexSettings = new IndexSettings.Builder();
/**
* 嵌套类型 实体字段->es实际字段映射
* 请求配置 默认值为官方内置的默认配置
*/
private final Map<Class<?>, Map<String, String>> nestedClassMappingColumnMap = new HashMap<>();
private TransportOptions requestOptions = new RestClientOptions(RequestOptions.DEFAULT, true);
/**
* 嵌套类型 es实际字段映射->实体字段 (仅包含被重命名字段)
* 最大返回数
*/
private final Map<Class<?>, Map<String, String>> nestedClassColumnMappingMap = new HashMap<>();
private Long maxResultWindow = DEFAULT_MAX_RESULT_WINDOW;
/**
* fastjson 过滤器
* 嵌套类/object类的字段信息列表
*/
private final Map<Class<?>, List<SerializeFilter>> classSimplePropertyPreFilterMap = new HashMap<>();
/**
* 父子类型 join字段名字 K为父,v为子
*/
private final Map<String, Object> relationMap = new HashMap<>();
private Map<Class<?>, List<EntityFieldInfo>> nestedOrObjectFieldListMap = new HashMap<>();
/**
* 父子类型 join字段类 K为父,v为子
*/
@ -220,9 +208,9 @@ public class EntityInfo {
*/
private RefreshPolicy refreshPolicy;
/**
* 通过自定义注解指定的索引settings
* 嵌套类-高亮字段列表
*/
private final Map<String, Object> settingsMap = new HashMap<>();
private Map<Class<?>, List<HighLightParam>> nestedOrObjectHighLightParamsMap = new HashMap<>();
/**
* 日期字段格式规则Map
*/
@ -271,8 +259,8 @@ public class EntityInfo {
*
* @return 嵌套类集合
*/
public Set<Class<?>> getAllNestedClass() {
return nestedClassColumnMappingMap.keySet();
public Set<Class<?>> getAllNestedOrObjectClass() {
return nestedOrObjectClassColumnMappingMap.keySet();
}
/**
@ -281,9 +269,9 @@ public class EntityInfo {
* @param path 路径
* @return 字段关系map
*/
public Map<String, String> getNestedMappingColumnMapByPath(String path) {
public Map<String, String> getNestedOrObjectMappingColumnMapByPath(String path) {
return Optional.ofNullable(pathClassMap.get(path))
.map(nestedClassMappingColumnMap::get)
.map(nestedOrObjectClassMappingColumnMap::get)
.orElse(Collections.emptyMap());
}

View File

@ -1,11 +1,10 @@
package org.dromara.easyes.core.biz;
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Map;
/**
* es索引信息
* <p>
@ -33,5 +32,5 @@ public class EsIndexInfo {
/**
* 索引字段信息
*/
private Map<String, Object> mapping;
private TypeMapping.Builder mapping;
}

View File

@ -38,7 +38,7 @@ public class EsIndexParam {
/**
* 索引权重
*/
private Float boost;
private Double boost;
/**
* 查询分词器
*/

View File

@ -1,9 +1,9 @@
package org.dromara.easyes.core.biz;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import lombok.Data;
import org.dromara.easyes.common.enums.EsQueryTypeEnum;
import org.dromara.easyes.core.toolkit.Tree;
import lombok.Data;
import org.elasticsearch.index.query.QueryBuilder;
/**
* 查询参数树
@ -68,5 +68,5 @@ public class Param extends Tree {
/**
* 混合查询 原生查询条件
*/
private QueryBuilder queryBuilder;
private Query.Builder queryBuilder;
}

View File

@ -1,18 +1,21 @@
package org.dromara.easyes.core.biz;
import co.elastic.clients.elasticsearch._types.FieldValue;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
* searchAfter 分页参数
**/
@EqualsAndHashCode(callSuper = true)
@Data
public class SAPageInfo<T> extends PageSerializable<T> {
/**
* 当前sort
*/
private List<Object> searchAfter;
private List<FieldValue> searchAfter;
/**
* 每页的数量
*/
@ -24,7 +27,7 @@ public class SAPageInfo<T> extends PageSerializable<T> {
/**
* 下一页sort
*/
private List<Object> nextSearchAfter;
private List<FieldValue> nextSearchAfter;
@Override
public String toString() {

View File

@ -1,5 +1,6 @@
package org.dromara.easyes.core.cache;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import org.dromara.easyes.common.constants.BaseEsConstants;
import org.dromara.easyes.common.utils.CollectionUtils;
import org.dromara.easyes.common.utils.ExceptionUtils;
@ -7,7 +8,6 @@ import org.dromara.easyes.core.biz.EntityInfo;
import org.dromara.easyes.core.kernel.BaseEsMapperImpl;
import org.dromara.easyes.core.toolkit.EntityInfoHelper;
import org.dromara.easyes.core.toolkit.FieldUtils;
import org.elasticsearch.client.RestHighLevelClient;
import java.lang.reflect.Method;
import java.util.*;
@ -29,27 +29,34 @@ public class BaseCache {
private static final Map<Class<?>, Map<String, Method>> baseEsEntityMethodMap = new ConcurrentHashMap<>();
/**
* 初始化缓存
* 初始化mapper缓存
*
* @param mapperInterface mapper接口
* @param client es客户端
* @param entityClass 实体类
*/
public static void initCache(Class<?> mapperInterface, Class<?> entityClass, RestHighLevelClient client) {
public static <T> void initMapperCache(Class<?> mapperInterface, Class<T> entityClass, ElasticsearchClient client) {
// 初始化baseEsMapper的所有实现类实例
BaseEsMapperImpl baseEsMapper = new BaseEsMapperImpl();
BaseEsMapperImpl<T> baseEsMapper = new BaseEsMapperImpl<>();
baseEsMapper.setClient(client);
baseEsMapper.setEntityClass(entityClass);
baseEsMapperInstanceMap.put(mapperInterface, baseEsMapper);
}
/**
* 初始化entity缓存
*
* @param entityClass 实体类
*/
public static void initEntityCache(Class<?> entityClass) {
// 初始化entity中所有字段(注解策略生效)
Map<String, Method> invokeMethodsMap = initInvokeMethodsMap(entityClass);
baseEsEntityMethodMap.putIfAbsent(entityClass, invokeMethodsMap);
EntityInfo entityInfo = EntityInfoHelper.getEntityInfo(entityClass);
// 初始化嵌套类中的所有方法
Set<Class<?>> allNestedClass = entityInfo.getAllNestedClass();
Set<Class<?>> allNestedClass = entityInfo.getAllNestedOrObjectClass();
if (CollectionUtils.isNotEmpty(allNestedClass)) {
allNestedClass.forEach(nestedClass -> {
Map<String, Method> nestedInvokeMethodsMap = initInvokeMethodsMap(nestedClass);
@ -76,7 +83,7 @@ public class BaseCache {
.forEach(entityMethod -> {
String methodName = entityMethod.getName();
if (methodName.startsWith(BaseEsConstants.GET_FUNC_PREFIX) || methodName.startsWith(BaseEsConstants.IS_FUNC_PREFIX)
|| methodName.startsWith(BaseEsConstants.SET_FUNC_PREFIX)) {
|| methodName.startsWith(BaseEsConstants.SET_FUNC_PREFIX)) {
invokeMethodsMap.put(methodName, entityMethod);
}
});
@ -125,4 +132,48 @@ public class BaseCache {
.map(b -> b.get(BaseEsConstants.SET_FUNC_PREFIX + FieldUtils.firstToUpperCase(methodName)))
.orElseThrow(() -> ExceptionUtils.eee("no such method:", entityClass, methodName));
}
/**
* 执行缓存中对应entity和methodName的setter方法
*
* @param entityClass 实体
* @param methodName 方法名
* @param obj 对象
* @param value
*/
public static void setterInvoke(Class<?> entityClass, String methodName, Object obj, Object value) {
try {
setterMethod(entityClass, methodName).invoke(obj, value);
} catch (Exception e) {
throw ExceptionUtils.eee("setterMethod exception", e);
}
}
/**
* 执行缓存中对应entity和methodName的getter方法
*
* @param entityClass 实体
* @param methodName 方法名
* @param obj 对象
* @return 执行方法
*/
public static Object getterInvoke(Class<?> entityClass, String methodName, Object obj) {
try {
return getterMethod(entityClass, methodName).invoke(obj);
} catch (Exception e) {
throw ExceptionUtils.eee("getterInvoke exception", e);
}
}
/**
* 获取id
*
* @param entityClass 实体
* @param obj 对象
* @return 执行方法
*/
public static Object getId(Class<?> entityClass, Object obj) {
String idFieldName = EntityInfoHelper.getEntityInfo(entityClass).getKeyProperty();
return getterInvoke(entityClass, idFieldName, obj);
}
}

View File

@ -0,0 +1,132 @@
package org.dromara.easyes.core.cache;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonIncludeProperties;
import com.fasterxml.jackson.databind.util.ClassUtil;
import org.dromara.easyes.common.constants.BaseEsConstants;
import org.dromara.easyes.common.utils.jackson.JacksonCustomConfig;
import org.dromara.easyes.core.biz.EntityFieldInfo;
import org.dromara.easyes.core.biz.EntityInfo;
import org.dromara.easyes.core.toolkit.FieldUtils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* jackson缓存
*
* @author jaime
* @version 1.0
* @since 2025/2/24
*/
public class JacksonCache {
public static void init(Map<Class<?>, EntityInfo> entityInfoMap) {
if (entityInfoMap.isEmpty()) {
return;
}
entityInfoMap.forEach((clz,e) -> {
// 当前类
if (!JacksonCustomConfig.jacksonConfigMap.containsKey(clz)) {
JacksonCustomConfig config = init(clz, e.getMappingColumnMap(), e.getClassDateFormatMap().get(clz), e.getFieldList());
JacksonCustomConfig.jacksonConfigMap.put(clz, config);
}
// nested嵌套类
e.getNestedOrObjectClassMappingColumnMap().forEach((nestedClz, nestedMappingColumnMap) -> {
if (JacksonCustomConfig.jacksonConfigMap.containsKey(clz)) {
return;
}
JacksonCustomConfig c = init(nestedClz, nestedMappingColumnMap,
e.getClassDateFormatMap().get(nestedClz),
e.getNestedOrObjectFieldListMap().get(nestedClz)
);
JacksonCustomConfig.jacksonConfigMap.put(nestedClz, c);
});
});
}
private static JacksonCustomConfig init(
Class<?> clz,
Map<String, String> mappingColumnMap,
Map<String, String> formatMap,
List<EntityFieldInfo> fieldList
) {
JacksonCustomConfig config = new JacksonCustomConfig();
config.clz = clz;
if (mappingColumnMap != null && !mappingColumnMap.isEmpty()) {
config.javaJsonFieldNameMap.putAll(mappingColumnMap);
config.allJsonField = JsonIncludeProperties.Value.from(new JsonIncludeProperties() {
@Override
public String[] value() {
return config.javaJsonFieldNameMap.values().toArray(new String[0]);
}
@Override
public Class<? extends Annotation> annotationType() {
return JsonIncludeProperties.class;
}
});
}
// java字段名 - 格式化
if (formatMap != null && !formatMap.isEmpty()) {
formatMap.forEach((javaFieldName, format) -> {
String getterName = getterMethod(clz, javaFieldName);
if (getterName != null) {
config.formatMap.put(getterName, JsonFormat.Value.forPattern(format));
}
String setterName = setterMethod(clz, javaFieldName);
if (setterName != null) {
config.formatMap.put(setterName, JsonFormat.Value.forPattern(format));
}
});
}
fieldList.forEach(f -> {
String getterName = getterMethod(clz, f.getColumn());
if (getterName == null) {
return;
}
switch (f.getFieldStrategy()) {
case NOT_NULL:
JsonInclude.Value v = JsonInclude.Value.construct(JsonInclude.Include.NON_NULL, null);
config.includeMap.put(getterName, v);
config.includeMap.put(f.getColumn(), v);
break;
case NOT_EMPTY:
JsonInclude.Value j = JsonInclude.Value.construct(JsonInclude.Include.NON_EMPTY, null);
config.includeMap.put(getterName, j);
config.includeMap.put(f.getColumn(), j);
break;
default:
break;
}
});
return config;
}
private static <V> String getterMethod(Class<V> clz, String fieldName) {
String getterName1 = BaseEsConstants.GET_FUNC_PREFIX + FieldUtils.firstToUpperCase(fieldName);
String getterName2 = BaseEsConstants.GET_FUNC_PREFIX + FieldUtils.firstToUpperCase(fieldName);
return Arrays.stream(ClassUtil.getClassMethods(clz))
.filter(m -> m.getName().equals(getterName1) || m.getName().equals(getterName2))
.findFirst()
.map(Method::getName)
.orElse(null);
}
private static <V> String setterMethod(Class<V> clz, String fieldName) {
String setterName1 = BaseEsConstants.SET_FUNC_PREFIX + FieldUtils.firstToUpperCase(fieldName);
return Arrays.stream(ClassUtil.getClassMethods(clz))
.filter(m -> m.getName().equals(setterName1))
.findFirst()
.map(Method::getName)
.orElse(null);
}
}

View File

@ -1,8 +1,7 @@
package org.dromara.easyes.core.conditions.function;
import co.elastic.clients.elasticsearch._types.query_dsl.Operator;
import org.dromara.easyes.core.toolkit.FieldUtils;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.index.query.Operator;
import java.io.Serializable;
import java.time.ZoneId;
@ -592,7 +591,7 @@ public interface Compare<Children, R> extends Serializable {
* @return wrapper
*/
default Children multiMatchQuery(boolean condition, Object val, R... columns) {
return multiMatchQuery(condition, val, Operator.OR, DEFAULT_MIN_SHOULD_MATCH, DEFAULT_BOOST, columns);
return multiMatchQuery(condition, val, Operator.Or, DEFAULT_MIN_SHOULD_MATCH, DEFAULT_BOOST, columns);
}
/**
@ -604,7 +603,7 @@ public interface Compare<Children, R> extends Serializable {
* @return wrapper
*/
default Children multiMatchQuery(Object val, Float boost, R... columns) {
return multiMatchQuery(true, val, Operator.OR, DEFAULT_MIN_SHOULD_MATCH, boost, columns);
return multiMatchQuery(true, val, Operator.Or, DEFAULT_MIN_SHOULD_MATCH, boost, columns);
}
/**
@ -616,7 +615,7 @@ public interface Compare<Children, R> extends Serializable {
* @return wrapper
*/
default Children multiMatchQuery(Object val, int minimumShouldMatch, R... columns) {
return multiMatchQuery(true, val, Operator.OR, minimumShouldMatch, DEFAULT_BOOST, columns);
return multiMatchQuery(true, val, Operator.Or, minimumShouldMatch, DEFAULT_BOOST, columns);
}
/**
@ -654,7 +653,7 @@ public interface Compare<Children, R> extends Serializable {
* @return wrapper
*/
default Children multiMatchQuery(Object val, int minimumShouldMatch, Float boost, R... columns) {
return multiMatchQuery(true, val, Operator.OR, minimumShouldMatch, boost, columns);
return multiMatchQuery(true, val, Operator.Or, minimumShouldMatch, boost, columns);
}
/**
@ -704,7 +703,7 @@ public interface Compare<Children, R> extends Serializable {
* @return wrapper
*/
default Children multiMatchQuery(boolean condition, Object val, String... columns) {
return multiMatchQuery(condition, val, Operator.OR, DEFAULT_MIN_SHOULD_MATCH, DEFAULT_BOOST, columns);
return multiMatchQuery(condition, val, Operator.Or, DEFAULT_MIN_SHOULD_MATCH, DEFAULT_BOOST, columns);
}
/**
@ -716,7 +715,7 @@ public interface Compare<Children, R> extends Serializable {
* @return wrapper
*/
default Children multiMatchQuery(Object val, Float boost, String... columns) {
return multiMatchQuery(true, val, Operator.OR, DEFAULT_MIN_SHOULD_MATCH, boost, columns);
return multiMatchQuery(true, val, Operator.Or, DEFAULT_MIN_SHOULD_MATCH, boost, columns);
}
/**
@ -728,7 +727,7 @@ public interface Compare<Children, R> extends Serializable {
* @return wrapper
*/
default Children multiMatchQuery(Object val, int minimumShouldMatch, String... columns) {
return multiMatchQuery(true, val, Operator.OR, minimumShouldMatch, DEFAULT_BOOST, columns);
return multiMatchQuery(true, val, Operator.Or, minimumShouldMatch, DEFAULT_BOOST, columns);
}
/**
@ -766,7 +765,7 @@ public interface Compare<Children, R> extends Serializable {
* @return wrapper
*/
default Children multiMatchQuery(Object val, int minimumShouldMatch, Float boost, String... columns) {
return multiMatchQuery(true, val, Operator.OR, minimumShouldMatch, boost, columns);
return multiMatchQuery(true, val, Operator.Or, minimumShouldMatch, boost, columns);
}
/**

View File

@ -1,15 +1,11 @@
package org.dromara.easyes.core.conditions.function;
import co.elastic.clients.elasticsearch._types.*;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.util.NamedValue;
import org.dromara.easyes.core.biz.OrderByParam;
import org.dromara.easyes.core.toolkit.FieldUtils;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.dromara.easyes.core.toolkit.GeoUtils;
import java.io.Serializable;
import java.util.*;
@ -221,7 +217,7 @@ public interface Func<Children, R> extends Serializable {
* @return wrapper
*/
default Children orderByDistanceAsc(R column, double lat, double lon) {
return orderByDistanceAsc(true, FieldUtils.getFieldName(column), DistanceUnit.KILOMETERS, GeoDistance.PLANE, new GeoPoint(lat, lon));
return orderByDistanceAsc(true, FieldUtils.getFieldName(column), DistanceUnit.Meters, GeoDistanceType.Plane, GeoUtils.create(lat, lon));
}
/**
@ -234,7 +230,7 @@ public interface Func<Children, R> extends Serializable {
* @return wrapper`
*/
default Children orderByDistanceAsc(R column, DistanceUnit unit, double lat, double lon) {
return orderByDistanceAsc(true, FieldUtils.getFieldName(column), unit, GeoDistance.PLANE, new GeoPoint(lat, lon));
return orderByDistanceAsc(true, FieldUtils.getFieldName(column), unit, GeoDistanceType.Plane, GeoUtils.create(lat, lon));
}
/**
@ -246,8 +242,8 @@ public interface Func<Children, R> extends Serializable {
* @param lon 经度
* @return wrapper`
*/
default Children orderByDistanceAsc(R column, GeoDistance geoDistance, double lat, double lon) {
return orderByDistanceAsc(true, FieldUtils.getFieldName(column), DistanceUnit.KILOMETERS, geoDistance, new GeoPoint(lat, lon));
default Children orderByDistanceAsc(R column, GeoDistanceType geoDistance, double lat, double lon) {
return orderByDistanceAsc(true, FieldUtils.getFieldName(column), DistanceUnit.Meters, geoDistance, GeoUtils.create(lat, lon));
}
/**
@ -260,8 +256,8 @@ public interface Func<Children, R> extends Serializable {
* @param lon 经度
* @return wrapper
*/
default Children orderByDistanceAsc(R column, DistanceUnit unit, GeoDistance geoDistance, double lat, double lon) {
return orderByDistanceAsc(true, FieldUtils.getFieldName(column), unit, geoDistance, new GeoPoint(lat, lon));
default Children orderByDistanceAsc(R column, DistanceUnit unit, GeoDistanceType geoDistance, double lat, double lon) {
return orderByDistanceAsc(true, FieldUtils.getFieldName(column), unit, geoDistance, GeoUtils.create(lat, lon));
}
/**
@ -271,8 +267,8 @@ public interface Func<Children, R> extends Serializable {
* @param geoPoints 多边形坐标点数组
* @return wrapper
*/
default Children orderByDistanceAsc(R column, GeoPoint... geoPoints) {
return orderByDistanceAsc(true, FieldUtils.getFieldName(column), DistanceUnit.KILOMETERS, GeoDistance.PLANE, geoPoints);
default Children orderByDistanceAsc(R column, GeoLocation... geoPoints) {
return orderByDistanceAsc(true, FieldUtils.getFieldName(column), DistanceUnit.Meters, GeoDistanceType.Plane, geoPoints);
}
/**
@ -283,8 +279,8 @@ public interface Func<Children, R> extends Serializable {
* @param geoPoints 多边形坐标点数组
* @return wrapper
*/
default Children orderByDistanceAsc(R column, DistanceUnit unit, GeoPoint... geoPoints) {
return orderByDistanceAsc(true, FieldUtils.getFieldName(column), unit, GeoDistance.PLANE, geoPoints);
default Children orderByDistanceAsc(R column, DistanceUnit unit, GeoLocation... geoPoints) {
return orderByDistanceAsc(true, FieldUtils.getFieldName(column), unit, GeoDistanceType.Plane, geoPoints);
}
/**
@ -295,8 +291,8 @@ public interface Func<Children, R> extends Serializable {
* @param geoPoints 多边形坐标点数组
* @return wrapper
*/
default Children orderByDistanceAsc(R column, GeoDistance geoDistance, GeoPoint... geoPoints) {
return orderByDistanceAsc(true, FieldUtils.getFieldName(column), DistanceUnit.KILOMETERS, geoDistance, geoPoints);
default Children orderByDistanceAsc(R column, GeoDistanceType geoDistance, GeoLocation... geoPoints) {
return orderByDistanceAsc(true, FieldUtils.getFieldName(column), DistanceUnit.Meters, geoDistance, geoPoints);
}
/**
@ -308,7 +304,7 @@ public interface Func<Children, R> extends Serializable {
* @param geoPoints 多边形坐标点数组
* @return wrapper
*/
default Children orderByDistanceAsc(R column, DistanceUnit unit, GeoDistance geoDistance, GeoPoint... geoPoints) {
default Children orderByDistanceAsc(R column, DistanceUnit unit, GeoDistanceType geoDistance, GeoLocation... geoPoints) {
return orderByDistanceAsc(true, FieldUtils.getFieldName(column), unit, geoDistance, geoPoints);
}
@ -321,7 +317,7 @@ public interface Func<Children, R> extends Serializable {
* @return wrapper
*/
default Children orderByDistanceAsc(String column, double lat, double lon) {
return orderByDistanceAsc(true, column, DistanceUnit.KILOMETERS, GeoDistance.PLANE, new GeoPoint(lat, lon));
return orderByDistanceAsc(true, column, DistanceUnit.Meters, GeoDistanceType.Plane, GeoUtils.create(lat, lon));
}
/**
@ -334,7 +330,7 @@ public interface Func<Children, R> extends Serializable {
* @return wrapper
*/
default Children orderByDistanceAsc(String column, DistanceUnit unit, double lat, double lon) {
return orderByDistanceAsc(true, column, unit, GeoDistance.PLANE, new GeoPoint(lat, lon));
return orderByDistanceAsc(true, column, unit, GeoDistanceType.Plane, GeoUtils.create(lat, lon));
}
/**
@ -346,8 +342,8 @@ public interface Func<Children, R> extends Serializable {
* @param lon 经度
* @return wrapper
*/
default Children orderByDistanceAsc(String column, GeoDistance geoDistance, double lat, double lon) {
return orderByDistanceAsc(true, column, DistanceUnit.KILOMETERS, geoDistance, new GeoPoint(lat, lon));
default Children orderByDistanceAsc(String column, GeoDistanceType geoDistance, double lat, double lon) {
return orderByDistanceAsc(true, column, DistanceUnit.Meters, geoDistance, GeoUtils.create(lat, lon));
}
/**
@ -360,8 +356,8 @@ public interface Func<Children, R> extends Serializable {
* @param lon 经度
* @return wrapper
*/
default Children orderByDistanceAsc(String column, DistanceUnit unit, GeoDistance geoDistance, double lat, double lon) {
return orderByDistanceAsc(true, column, unit, geoDistance, new GeoPoint(lat, lon));
default Children orderByDistanceAsc(String column, DistanceUnit unit, GeoDistanceType geoDistance, double lat, double lon) {
return orderByDistanceAsc(true, column, unit, geoDistance, GeoUtils.create(lat, lon));
}
/**
@ -371,8 +367,8 @@ public interface Func<Children, R> extends Serializable {
* @param geoPoints 多边形坐标点数组
* @return wrapper
*/
default Children orderByDistanceAsc(String column, GeoPoint... geoPoints) {
return orderByDistanceAsc(true, column, DistanceUnit.KILOMETERS, GeoDistance.PLANE, geoPoints);
default Children orderByDistanceAsc(String column, GeoLocation... geoPoints) {
return orderByDistanceAsc(true, column, DistanceUnit.Meters, GeoDistanceType.Plane, geoPoints);
}
/**
@ -383,8 +379,8 @@ public interface Func<Children, R> extends Serializable {
* @param geoPoints 多边形坐标点数组
* @return wrapper
*/
default Children orderByDistanceAsc(String column, DistanceUnit unit, GeoPoint... geoPoints) {
return orderByDistanceAsc(true, column, unit, GeoDistance.PLANE, geoPoints);
default Children orderByDistanceAsc(String column, DistanceUnit unit, GeoLocation... geoPoints) {
return orderByDistanceAsc(true, column, unit, GeoDistanceType.Plane, geoPoints);
}
/**
@ -395,8 +391,8 @@ public interface Func<Children, R> extends Serializable {
* @param geoPoints 多边形坐标点数组
* @return wrapper
*/
default Children orderByDistanceAsc(String column, GeoDistance geoDistance, GeoPoint... geoPoints) {
return orderByDistanceAsc(true, column, DistanceUnit.KILOMETERS, geoDistance, geoPoints);
default Children orderByDistanceAsc(String column, GeoDistanceType geoDistance, GeoLocation... geoPoints) {
return orderByDistanceAsc(true, column, DistanceUnit.Meters, geoDistance, geoPoints);
}
/**
@ -408,7 +404,7 @@ public interface Func<Children, R> extends Serializable {
* @param geoPoints 多边形坐标点数组
* @return wrapper
*/
default Children orderByDistanceAsc(String column, DistanceUnit unit, GeoDistance geoDistance, GeoPoint... geoPoints) {
default Children orderByDistanceAsc(String column, DistanceUnit unit, GeoDistanceType geoDistance, GeoLocation... geoPoints) {
return orderByDistanceAsc(true, column, unit, geoDistance, geoPoints);
}
@ -418,11 +414,11 @@ public interface Func<Children, R> extends Serializable {
* @param condition 执行条件
* @param column 列名 字符串
* @param unit 距离单位 重载方法默认为km
* @param geoDistance 距离计算方式,重载方法默认为GeoDistance.PLANE
* @param geoDistance 距离计算方式,重载方法默认为GeoDistanceType.Plane
* @param geoPoints 多边形坐标点数组
* @return wrapper
*/
Children orderByDistanceAsc(boolean condition, String column, DistanceUnit unit, GeoDistance geoDistance, GeoPoint... geoPoints);
Children orderByDistanceAsc(boolean condition, String column, DistanceUnit unit, GeoDistanceType geoDistance, GeoLocation... geoPoints);
/**
* 地理位置坐标点由近及远排序
@ -433,7 +429,7 @@ public interface Func<Children, R> extends Serializable {
* @return wrapper
*/
default Children orderByDistanceDesc(R column, double lat, double lon) {
return orderByDistanceDesc(true, FieldUtils.getFieldName(column), DistanceUnit.KILOMETERS, GeoDistance.PLANE, new GeoPoint(lat, lon));
return orderByDistanceDesc(true, FieldUtils.getFieldName(column), DistanceUnit.Meters, GeoDistanceType.Plane, GeoUtils.create(lat, lon));
}
/**
@ -446,20 +442,20 @@ public interface Func<Children, R> extends Serializable {
* @return wrapper
*/
default Children orderByDistanceDesc(R column, DistanceUnit unit, double lat, double lon) {
return orderByDistanceDesc(true, FieldUtils.getFieldName(column), unit, GeoDistance.PLANE, new GeoPoint(lat, lon));
return orderByDistanceDesc(true, FieldUtils.getFieldName(column), unit, GeoDistanceType.Plane, GeoUtils.create(lat, lon));
}
/**
* 地理位置坐标点由近及远排序
*
* @param column
* @param geoDistance 距离计算方式,重载方法默认为GeoDistance.PLANE
* @param geoDistance 距离计算方式,重载方法默认为GeoDistanceType.Plane
* @param lat 纬度
* @param lon 经度
* @return wrapper
*/
default Children orderByDistanceDesc(R column, GeoDistance geoDistance, double lat, double lon) {
return orderByDistanceDesc(true, FieldUtils.getFieldName(column), DistanceUnit.KILOMETERS, geoDistance, new GeoPoint(lat, lon));
default Children orderByDistanceDesc(R column, GeoDistanceType geoDistance, double lat, double lon) {
return orderByDistanceDesc(true, FieldUtils.getFieldName(column), DistanceUnit.Meters, geoDistance, GeoUtils.create(lat, lon));
}
/**
@ -467,13 +463,13 @@ public interface Func<Children, R> extends Serializable {
*
* @param column 列名
* @param unit 距离单位
* @param geoDistance 距离计算方式,重载方法默认为GeoDistance.PLANE
* @param geoDistance 距离计算方式,重载方法默认为GeoDistanceType.Plane
* @param lat 纬度
* @param lon 经度
* @return wrapper
*/
default Children orderByDistanceDesc(R column, DistanceUnit unit, GeoDistance geoDistance, double lat, double lon) {
return orderByDistanceDesc(true, FieldUtils.getFieldName(column), unit, geoDistance, new GeoPoint(lat, lon));
default Children orderByDistanceDesc(R column, DistanceUnit unit, GeoDistanceType geoDistance, double lat, double lon) {
return orderByDistanceDesc(true, FieldUtils.getFieldName(column), unit, geoDistance, GeoUtils.create(lat, lon));
}
/**
@ -483,8 +479,8 @@ public interface Func<Children, R> extends Serializable {
* @param geoPoints 多边形坐标点数组
* @return wrapper
*/
default Children orderByDistanceDesc(R column, GeoPoint... geoPoints) {
return orderByDistanceDesc(true, FieldUtils.getFieldName(column), DistanceUnit.KILOMETERS, GeoDistance.PLANE, geoPoints);
default Children orderByDistanceDesc(R column, GeoLocation... geoPoints) {
return orderByDistanceDesc(true, FieldUtils.getFieldName(column), DistanceUnit.Meters, GeoDistanceType.Plane, geoPoints);
}
/**
@ -495,20 +491,20 @@ public interface Func<Children, R> extends Serializable {
* @param geoPoints 多边形坐标点数组
* @return wrapper
*/
default Children orderByDistanceDesc(R column, DistanceUnit unit, GeoPoint... geoPoints) {
return orderByDistanceDesc(true, FieldUtils.getFieldName(column), unit, GeoDistance.PLANE, geoPoints);
default Children orderByDistanceDesc(R column, DistanceUnit unit, GeoLocation... geoPoints) {
return orderByDistanceDesc(true, FieldUtils.getFieldName(column), unit, GeoDistanceType.Plane, geoPoints);
}
/**
* 地理位置坐标点由近及远排序
*
* @param column
* @param geoDistance 距离计算方式,重载方法默认为GeoDistance.PLANE
* @param geoDistance 距离计算方式,重载方法默认为GeoDistanceType.Plane
* @param geoPoints 多边形坐标点数组
* @return wrapper
*/
default Children orderByDistanceDesc(R column, GeoDistance geoDistance, GeoPoint... geoPoints) {
return orderByDistanceDesc(true, FieldUtils.getFieldName(column), DistanceUnit.KILOMETERS, geoDistance, geoPoints);
default Children orderByDistanceDesc(R column, GeoDistanceType geoDistance, GeoLocation... geoPoints) {
return orderByDistanceDesc(true, FieldUtils.getFieldName(column), DistanceUnit.Meters, geoDistance, geoPoints);
}
/**
@ -516,11 +512,11 @@ public interface Func<Children, R> extends Serializable {
*
* @param column
* @param unit 距离单位
* @param geoDistance 距离计算方式,重载方法默认为GeoDistance.PLANE
* @param geoDistance 距离计算方式,重载方法默认为GeoDistanceType.Plane
* @param geoPoints 多边形坐标点数组
* @return wrapper
*/
default Children orderByDistanceDesc(R column, DistanceUnit unit, GeoDistance geoDistance, GeoPoint... geoPoints) {
default Children orderByDistanceDesc(R column, DistanceUnit unit, GeoDistanceType geoDistance, GeoLocation... geoPoints) {
return orderByDistanceDesc(true, FieldUtils.getFieldName(column), unit, geoDistance, geoPoints);
}
@ -533,7 +529,7 @@ public interface Func<Children, R> extends Serializable {
* @return wrapper
*/
default Children orderByDistanceDesc(String column, double lat, double lon) {
return orderByDistanceDesc(true, column, DistanceUnit.KILOMETERS, GeoDistance.PLANE, new GeoPoint(lat, lon));
return orderByDistanceDesc(true, column, DistanceUnit.Meters, GeoDistanceType.Plane, GeoUtils.create(lat, lon));
}
/**
@ -546,20 +542,20 @@ public interface Func<Children, R> extends Serializable {
* @return wrapper
*/
default Children orderByDistanceDesc(String column, DistanceUnit unit, double lat, double lon) {
return orderByDistanceDesc(true, column, unit, GeoDistance.PLANE, new GeoPoint(lat, lon));
return orderByDistanceDesc(true, column, unit, GeoDistanceType.Plane, GeoUtils.create(lat, lon));
}
/**
* 地理位置坐标点由近及远排序
*
* @param column 列名 字符串
* @param geoDistance 距离计算方式,重载方法默认为GeoDistance.PLANE
* @param geoDistance 距离计算方式,重载方法默认为GeoDistanceType.Plane
* @param lat 纬度
* @param lon 经度
* @return wrapper
*/
default Children orderByDistanceDesc(String column, GeoDistance geoDistance, double lat, double lon) {
return orderByDistanceDesc(true, column, DistanceUnit.KILOMETERS, geoDistance, new GeoPoint(lat, lon));
default Children orderByDistanceDesc(String column, GeoDistanceType geoDistance, double lat, double lon) {
return orderByDistanceDesc(true, column, DistanceUnit.Meters, geoDistance, GeoUtils.create(lat, lon));
}
/**
@ -567,13 +563,13 @@ public interface Func<Children, R> extends Serializable {
*
* @param column 列名 字符串
* @param unit 距离单位
* @param geoDistance 距离计算方式,重载方法默认为GeoDistance.PLANE
* @param geoDistance 距离计算方式,重载方法默认为GeoDistanceType.Plane
* @param lat 纬度
* @param lon 经度
* @return wrapper
*/
default Children orderByDistanceDesc(String column, DistanceUnit unit, GeoDistance geoDistance, double lat, double lon) {
return orderByDistanceDesc(true, column, unit, geoDistance, new GeoPoint(lat, lon));
default Children orderByDistanceDesc(String column, DistanceUnit unit, GeoDistanceType geoDistance, double lat, double lon) {
return orderByDistanceDesc(true, column, unit, geoDistance, GeoUtils.create(lat, lon));
}
/**
@ -583,8 +579,8 @@ public interface Func<Children, R> extends Serializable {
* @param geoPoints 多边形坐标点数组
* @return wrapper
*/
default Children orderByDistanceDesc(String column, GeoPoint... geoPoints) {
return orderByDistanceDesc(true, column, DistanceUnit.KILOMETERS, GeoDistance.PLANE, geoPoints);
default Children orderByDistanceDesc(String column, GeoLocation... geoPoints) {
return orderByDistanceDesc(true, column, DistanceUnit.Meters, GeoDistanceType.Plane, geoPoints);
}
/**
@ -595,20 +591,20 @@ public interface Func<Children, R> extends Serializable {
* @param geoPoints 多边形坐标点数组
* @return wrapper
*/
default Children orderByDistanceDesc(String column, DistanceUnit unit, GeoPoint... geoPoints) {
return orderByDistanceDesc(true, column, unit, GeoDistance.PLANE, geoPoints);
default Children orderByDistanceDesc(String column, DistanceUnit unit, GeoLocation... geoPoints) {
return orderByDistanceDesc(true, column, unit, GeoDistanceType.Plane, geoPoints);
}
/**
* 地理位置坐标点由近及远排序
*
* @param column 列名 字符串
* @param geoDistance 距离计算方式,重载方法默认为GeoDistance.PLANE
* @param geoDistance 距离计算方式,重载方法默认为GeoDistanceType.Plane
* @param geoPoints 多边形坐标点数组
* @return wrapper
*/
default Children orderByDistanceDesc(String column, GeoDistance geoDistance, GeoPoint... geoPoints) {
return orderByDistanceDesc(true, column, DistanceUnit.KILOMETERS, geoDistance, geoPoints);
default Children orderByDistanceDesc(String column, GeoDistanceType geoDistance, GeoLocation... geoPoints) {
return orderByDistanceDesc(true, column, DistanceUnit.Meters, geoDistance, geoPoints);
}
/**
@ -616,11 +612,11 @@ public interface Func<Children, R> extends Serializable {
*
* @param column 列名 字符串
* @param unit 距离单位
* @param geoDistance 距离计算方式,重载方法默认为GeoDistance.PLANE
* @param geoDistance 距离计算方式,重载方法默认为GeoDistanceType.Plane
* @param geoPoints 多边形坐标点数组
* @return wrapper
*/
default Children orderByDistanceDesc(String column, DistanceUnit unit, GeoDistance geoDistance, GeoPoint... geoPoints) {
default Children orderByDistanceDesc(String column, DistanceUnit unit, GeoDistanceType geoDistance, GeoLocation... geoPoints) {
return orderByDistanceDesc(true, column, unit, geoDistance, geoPoints);
}
@ -630,11 +626,11 @@ public interface Func<Children, R> extends Serializable {
* @param condition 条件
* @param column 列名 字符串
* @param unit 距离单位 重载方法默认为km
* @param geoDistance 距离计算方式,重载方法默认为GeoDistance.PLANE
* @param geoDistance 距离计算方式,重载方法默认为GeoDistanceType.Plane
* @param geoPoints 多边形坐标点数组
* @return wrapper
*/
Children orderByDistanceDesc(boolean condition, String column, DistanceUnit unit, GeoDistance geoDistance, GeoPoint... geoPoints);
Children orderByDistanceDesc(boolean condition, String column, DistanceUnit unit, GeoDistanceType geoDistance, GeoLocation... geoPoints);
/**
* 字段 IN
@ -1531,7 +1527,7 @@ public interface Func<Children, R> extends Serializable {
* @param sortBuilder 原生排序器
* @return wrapper
*/
default Children sort(SortBuilder<?> sortBuilder) {
default Children sort(SortOptions sortBuilder) {
return sort(true, sortBuilder);
}
@ -1542,7 +1538,7 @@ public interface Func<Children, R> extends Serializable {
* @param sortBuilder 原生排序器
* @return wrapper
*/
default Children sort(boolean condition, SortBuilder<?> sortBuilder) {
default Children sort(boolean condition, SortOptions sortBuilder) {
return sort(condition, Collections.singletonList(sortBuilder));
}
@ -1553,7 +1549,7 @@ public interface Func<Children, R> extends Serializable {
* @param sortBuilders 原生排序器列表
* @return wrapper
*/
Children sort(boolean condition, List<SortBuilder<?>> sortBuilders);
Children sort(boolean condition, List<SortOptions> sortBuilders);
/**
* 根据得分_score排序 默认为降序 得分高得在前
@ -1561,7 +1557,7 @@ public interface Func<Children, R> extends Serializable {
* @return wrapper
*/
default Children sortByScore() {
return sortByScore(true, SortOrder.DESC);
return sortByScore(true, SortOrder.Desc);
}
/**
@ -1571,7 +1567,7 @@ public interface Func<Children, R> extends Serializable {
* @return wrapper
*/
default Children sortByScore(boolean condition) {
return sortByScore(condition, SortOrder.DESC);
return sortByScore(condition, SortOrder.Desc);
}
/**
@ -1668,23 +1664,23 @@ public interface Func<Children, R> extends Serializable {
Children limit(Integer m, Integer n);
/**
* 用户自定义SearchSourceBuilder 用于混合查询
* 用户自定义SearchRequest.Builder 用于混合查询
*
* @param searchSourceBuilder 用户自定义的SearchSourceBuilder
* @return wrapper
*/
default Children setSearchSourceBuilder(SearchSourceBuilder searchSourceBuilder) {
default Children setSearchSourceBuilder(SearchRequest.Builder searchSourceBuilder) {
return setSearchSourceBuilder(true, searchSourceBuilder);
}
/**
* 用户自定义SearchSourceBuilder 用于混合查询
* 用户自定义SearchRequest.Builder 用于混合查询
*
* @param condition 执行条件
* @param searchSourceBuilder 用户自定义的SearchSourceBuilder
* @return wrapper
*/
Children setSearchSourceBuilder(boolean condition, SearchSourceBuilder searchSourceBuilder);
Children setSearchSourceBuilder(boolean condition, SearchRequest.Builder searchSourceBuilder);
/**
* 混合查询
@ -1692,7 +1688,7 @@ public interface Func<Children, R> extends Serializable {
* @param queryBuilder 原生查询条件
* @return wrapper
*/
default Children mix(QueryBuilder queryBuilder) {
default Children mix(co.elastic.clients.elasticsearch._types.query_dsl.Query.Builder queryBuilder) {
return mix(true, queryBuilder);
}
@ -1704,7 +1700,7 @@ public interface Func<Children, R> extends Serializable {
* @param queryBuilder 原生查询条件
* @return wrapper
*/
Children mix(boolean condition, QueryBuilder queryBuilder);
Children mix(boolean condition, co.elastic.clients.elasticsearch._types.query_dsl.Query.Builder queryBuilder);
/**
@ -1713,7 +1709,7 @@ public interface Func<Children, R> extends Serializable {
* @param bucketOrder 排序规则
* @return wrapper
*/
default Children bucketOrder(BucketOrder bucketOrder) {
default Children bucketOrder(NamedValue<SortOrder> bucketOrder) {
return bucketOrder(true, bucketOrder);
}
@ -1724,7 +1720,7 @@ public interface Func<Children, R> extends Serializable {
* @param bucketOrder 桶排序规则
* @return wrapper
*/
default Children bucketOrder(boolean condition, BucketOrder bucketOrder) {
default Children bucketOrder(boolean condition, NamedValue<SortOrder> bucketOrder) {
return bucketOrder(condition, Arrays.asList(bucketOrder));
}
@ -1734,7 +1730,7 @@ public interface Func<Children, R> extends Serializable {
* @param bucketOrders 排序规则列表
* @return wrapper
*/
default Children bucketOrder(List<BucketOrder> bucketOrders) {
default Children bucketOrder(List<NamedValue<SortOrder>> bucketOrders) {
return bucketOrder(true, bucketOrders);
}
@ -1745,5 +1741,5 @@ public interface Func<Children, R> extends Serializable {
* @param bucketOrders 排序规则列表
* @return wrapper
*/
Children bucketOrder(boolean condition, List<BucketOrder> bucketOrders);
Children bucketOrder(boolean condition, List<NamedValue<SortOrder>> bucketOrders);
}

View File

@ -1,11 +1,12 @@
package org.dromara.easyes.core.conditions.function;
import co.elastic.clients.elasticsearch._types.DistanceUnit;
import co.elastic.clients.elasticsearch._types.GeoLocation;
import co.elastic.clients.elasticsearch._types.GeoShapeRelation;
import org.dromara.easyes.common.utils.CollectionUtils;
import org.dromara.easyes.common.utils.ExceptionUtils;
import org.dromara.easyes.core.toolkit.FieldUtils;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.unit.DistanceUnit;
import org.dromara.easyes.core.toolkit.GeoUtils;
import org.elasticsearch.geometry.Geometry;
import java.io.Serializable;
@ -24,11 +25,11 @@ import static org.dromara.easyes.common.constants.BaseEsConstants.DEFAULT_BOOST;
public interface Geo<Children, R> extends Serializable {
/**
* @param column
* @param topLeft 左上点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param topLeft 左上点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoBoundingBox(R column, GeoPoint topLeft, GeoPoint bottomRight) {
default Children geoBoundingBox(R column, GeoLocation topLeft, GeoLocation bottomRight) {
return geoBoundingBox(true, column, topLeft, bottomRight, DEFAULT_BOOST);
}
@ -37,11 +38,11 @@ public interface Geo<Children, R> extends Serializable {
*
* @param condition 执行条件
* @param column
* @param topLeft 左上点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param topLeft 左上点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoBoundingBox(boolean condition, R column, GeoPoint topLeft, GeoPoint bottomRight) {
default Children geoBoundingBox(boolean condition, R column, GeoLocation topLeft, GeoLocation bottomRight) {
return geoBoundingBox(condition, column, topLeft, bottomRight, DEFAULT_BOOST);
}
@ -49,12 +50,12 @@ public interface Geo<Children, R> extends Serializable {
* 矩形内范围查询
*
* @param column
* @param topLeft 左上点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param topLeft 左上点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
default Children geoBoundingBox(R column, GeoPoint topLeft, GeoPoint bottomRight, Float boost) {
default Children geoBoundingBox(R column, GeoLocation topLeft, GeoLocation bottomRight, Float boost) {
return geoBoundingBox(true, column, topLeft, bottomRight, boost);
}
@ -62,8 +63,8 @@ public interface Geo<Children, R> extends Serializable {
* 矩形内范围查询
*
* @param column 列名 字符串
* @param topLeft 左上点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param topLeft 左上点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoBoundingBox(R column, String topLeft, String bottomRight) {
@ -75,8 +76,8 @@ public interface Geo<Children, R> extends Serializable {
*
* @param condition 执行条件
* @param column
* @param topLeft 左上点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param topLeft 左上点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoBoundingBox(boolean condition, R column, String topLeft, String bottomRight) {
@ -87,8 +88,8 @@ public interface Geo<Children, R> extends Serializable {
* 矩形内范围查询
*
* @param column
* @param topLeft 左上点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param topLeft 左上点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
@ -100,11 +101,11 @@ public interface Geo<Children, R> extends Serializable {
* 矩形内范围查询
*
* @param column 列名 字符串
* @param topLeft 左上点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param topLeft 左上点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoBoundingBox(String column, GeoPoint topLeft, GeoPoint bottomRight) {
default Children geoBoundingBox(String column, GeoLocation topLeft, GeoLocation bottomRight) {
return geoBoundingBox(true, column, topLeft, bottomRight, DEFAULT_BOOST);
}
@ -113,11 +114,11 @@ public interface Geo<Children, R> extends Serializable {
*
* @param condition 执行条件
* @param column 列名 字符串
* @param topLeft 左上点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param topLeft 左上点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoBoundingBox(boolean condition, String column, GeoPoint topLeft, GeoPoint bottomRight) {
default Children geoBoundingBox(boolean condition, String column, GeoLocation topLeft, GeoLocation bottomRight) {
return geoBoundingBox(condition, column, topLeft, bottomRight, DEFAULT_BOOST);
}
@ -125,12 +126,12 @@ public interface Geo<Children, R> extends Serializable {
* 矩形内范围查询
*
* @param column 列名 字符串
* @param topLeft 左上点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param topLeft 左上点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
default Children geoBoundingBox(String column, GeoPoint topLeft, GeoPoint bottomRight, Float boost) {
default Children geoBoundingBox(String column, GeoLocation topLeft, GeoLocation bottomRight, Float boost) {
return geoBoundingBox(true, column, topLeft, bottomRight, boost);
}
@ -138,8 +139,8 @@ public interface Geo<Children, R> extends Serializable {
* 矩形内范围查询
*
* @param column 列名 字符串
* @param topLeft 左上点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param topLeft 左上点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoBoundingBox(String column, String topLeft, String bottomRight) {
@ -151,8 +152,8 @@ public interface Geo<Children, R> extends Serializable {
*
* @param condition 执行条件
* @param column 列名 字符串
* @param topLeft 左上点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param topLeft 左上点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoBoundingBox(boolean condition, String column, String topLeft, String bottomRight) {
@ -163,8 +164,8 @@ public interface Geo<Children, R> extends Serializable {
* 矩形内范围查询
*
* @param column 列名 字符串
* @param topLeft 左上点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param topLeft 左上点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
@ -177,12 +178,12 @@ public interface Geo<Children, R> extends Serializable {
*
* @param condition 执行条件
* @param column
* @param topLeft 左上点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param topLeft 左上点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
default Children geoBoundingBox(boolean condition, R column, GeoPoint topLeft, GeoPoint bottomRight, Float boost) {
default Children geoBoundingBox(boolean condition, R column, GeoLocation topLeft, GeoLocation bottomRight, Float boost) {
return geoBoundingBox(condition, FieldUtils.getFieldName(column), topLeft, bottomRight, boost);
}
@ -191,20 +192,20 @@ public interface Geo<Children, R> extends Serializable {
*
* @param condition 执行条件
* @param column 列名 字符串
* @param topLeft 左上点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param topLeft 左上点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
Children geoBoundingBox(boolean condition, String column, GeoPoint topLeft, GeoPoint bottomRight, Float boost);
Children geoBoundingBox(boolean condition, String column, GeoLocation topLeft, GeoLocation bottomRight, Float boost);
/**
* 矩形内范围查询
*
* @param condition 执行条件
* @param column 列名 字符串
* @param topLeft 左上点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoPoint/字符串/哈希/wkt均支持
* @param topLeft 左上点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param bottomRight 右下点坐标 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
@ -215,11 +216,11 @@ public interface Geo<Children, R> extends Serializable {
*
* @param column
* @param distance 距离
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoDistance(R column, Double distance, GeoPoint centralGeoPoint) {
return geoDistance(true, column, distance, DistanceUnit.KILOMETERS, centralGeoPoint, DEFAULT_BOOST);
default Children geoDistance(R column, Double distance, GeoLocation centralGeoLocation) {
return geoDistance(true, column, distance, DistanceUnit.Meters, centralGeoLocation, DEFAULT_BOOST);
}
/**
@ -228,11 +229,11 @@ public interface Geo<Children, R> extends Serializable {
* @param column
* @param distance 距离
* @param distanceUnit 距离单位
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoDistance(R column, Double distance, DistanceUnit distanceUnit, GeoPoint centralGeoPoint) {
return geoDistance(true, column, distance, distanceUnit, centralGeoPoint, DEFAULT_BOOST);
default Children geoDistance(R column, Double distance, DistanceUnit distanceUnit, GeoLocation centralGeoLocation) {
return geoDistance(true, column, distance, distanceUnit, centralGeoLocation, DEFAULT_BOOST);
}
/**
@ -241,12 +242,12 @@ public interface Geo<Children, R> extends Serializable {
* @param column
* @param distance 距离
* @param distanceUnit 距离单位
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
default Children geoDistance(R column, Double distance, DistanceUnit distanceUnit, GeoPoint centralGeoPoint, Float boost) {
return geoDistance(true, column, distance, distanceUnit, centralGeoPoint, boost);
default Children geoDistance(R column, Double distance, DistanceUnit distanceUnit, GeoLocation centralGeoLocation, Float boost) {
return geoDistance(true, column, distance, distanceUnit, centralGeoLocation, boost);
}
/**
@ -255,11 +256,11 @@ public interface Geo<Children, R> extends Serializable {
* @param column
* @param distance 距离
* @param distanceUnit 距离单位
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoDistance(R column, Double distance, DistanceUnit distanceUnit, String centralGeoPoint) {
return geoDistance(true, column, distance, distanceUnit, centralGeoPoint, DEFAULT_BOOST);
default Children geoDistance(R column, Double distance, DistanceUnit distanceUnit, String centralGeoLocation) {
return geoDistance(true, column, distance, distanceUnit, centralGeoLocation, DEFAULT_BOOST);
}
/**
@ -269,11 +270,11 @@ public interface Geo<Children, R> extends Serializable {
* @param column
* @param distance 距离
* @param distanceUnit 距离单位
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoDistance(boolean condition, R column, Double distance, DistanceUnit distanceUnit, String centralGeoPoint) {
return geoDistance(condition, column, distance, distanceUnit, centralGeoPoint, DEFAULT_BOOST);
default Children geoDistance(boolean condition, R column, Double distance, DistanceUnit distanceUnit, String centralGeoLocation) {
return geoDistance(condition, column, distance, distanceUnit, centralGeoLocation, DEFAULT_BOOST);
}
/**
@ -282,12 +283,12 @@ public interface Geo<Children, R> extends Serializable {
* @param column
* @param distance 距离
* @param distanceUnit 距离单位
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
default Children geoDistance(R column, Double distance, DistanceUnit distanceUnit, String centralGeoPoint, Float boost) {
return geoDistance(true, column, distance, distanceUnit, centralGeoPoint, boost);
default Children geoDistance(R column, Double distance, DistanceUnit distanceUnit, String centralGeoLocation, Float boost) {
return geoDistance(true, column, distance, distanceUnit, centralGeoLocation, boost);
}
/**
@ -297,12 +298,12 @@ public interface Geo<Children, R> extends Serializable {
* @param column
* @param distance 距离
* @param distanceUnit 距离单位
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
default Children geoDistance(boolean condition, R column, Double distance, DistanceUnit distanceUnit, String centralGeoPoint, Float boost) {
return geoDistance(condition, FieldUtils.getFieldName(column), distance, distanceUnit, centralGeoPoint, boost);
default Children geoDistance(boolean condition, R column, Double distance, DistanceUnit distanceUnit, String centralGeoLocation, Float boost) {
return geoDistance(condition, FieldUtils.getFieldName(column), distance, distanceUnit, centralGeoLocation, boost);
}
/**
@ -310,11 +311,11 @@ public interface Geo<Children, R> extends Serializable {
*
* @param column 列名 字符串
* @param distance 距离
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoDistance(String column, Double distance, GeoPoint centralGeoPoint) {
return geoDistance(true, column, distance, DistanceUnit.KILOMETERS, centralGeoPoint, DEFAULT_BOOST);
default Children geoDistance(String column, Double distance, GeoLocation centralGeoLocation) {
return geoDistance(true, column, distance, DistanceUnit.Meters, centralGeoLocation, DEFAULT_BOOST);
}
/**
@ -323,11 +324,11 @@ public interface Geo<Children, R> extends Serializable {
* @param column 列名 字符串
* @param distance 距离
* @param distanceUnit 距离单位
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoDistance(String column, Double distance, DistanceUnit distanceUnit, GeoPoint centralGeoPoint) {
return geoDistance(true, column, distance, distanceUnit, centralGeoPoint, DEFAULT_BOOST);
default Children geoDistance(String column, Double distance, DistanceUnit distanceUnit, GeoLocation centralGeoLocation) {
return geoDistance(true, column, distance, distanceUnit, centralGeoLocation, DEFAULT_BOOST);
}
/**
@ -336,12 +337,12 @@ public interface Geo<Children, R> extends Serializable {
* @param column 列名 字符串
* @param distance 距离
* @param distanceUnit 距离单位
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
default Children geoDistance(String column, Double distance, DistanceUnit distanceUnit, GeoPoint centralGeoPoint, Float boost) {
return geoDistance(true, column, distance, distanceUnit, centralGeoPoint, boost);
default Children geoDistance(String column, Double distance, DistanceUnit distanceUnit, GeoLocation centralGeoLocation, Float boost) {
return geoDistance(true, column, distance, distanceUnit, centralGeoLocation, boost);
}
/**
@ -350,11 +351,11 @@ public interface Geo<Children, R> extends Serializable {
* @param column 列名 字符串
* @param distance 距离
* @param distanceUnit 距离单位
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoDistance(String column, Double distance, DistanceUnit distanceUnit, String centralGeoPoint) {
return geoDistance(true, column, distance, distanceUnit, centralGeoPoint, DEFAULT_BOOST);
default Children geoDistance(String column, Double distance, DistanceUnit distanceUnit, String centralGeoLocation) {
return geoDistance(true, column, distance, distanceUnit, centralGeoLocation, DEFAULT_BOOST);
}
/**
@ -364,11 +365,11 @@ public interface Geo<Children, R> extends Serializable {
* @param column 列名 字符串
* @param distance 距离
* @param distanceUnit 距离单位
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoDistance(boolean condition, String column, Double distance, DistanceUnit distanceUnit, String centralGeoPoint) {
return geoDistance(condition, column, distance, distanceUnit, centralGeoPoint, DEFAULT_BOOST);
default Children geoDistance(boolean condition, String column, Double distance, DistanceUnit distanceUnit, String centralGeoLocation) {
return geoDistance(condition, column, distance, distanceUnit, centralGeoLocation, DEFAULT_BOOST);
}
/**
@ -377,12 +378,12 @@ public interface Geo<Children, R> extends Serializable {
* @param column 列名 字符串
* @param distance 距离
* @param distanceUnit 距离单位
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
default Children geoDistance(String column, Double distance, DistanceUnit distanceUnit, String centralGeoPoint, Float boost) {
return geoDistance(true, column, distance, distanceUnit, centralGeoPoint, boost);
default Children geoDistance(String column, Double distance, DistanceUnit distanceUnit, String centralGeoLocation, Float boost) {
return geoDistance(true, column, distance, distanceUnit, centralGeoLocation, boost);
}
/**
@ -392,11 +393,11 @@ public interface Geo<Children, R> extends Serializable {
* @param column 列名 字符串
* @param distance 距离
* @param distanceUnit 距离单位
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
Children geoDistance(boolean condition, String column, Double distance, DistanceUnit distanceUnit, String centralGeoPoint, Float boost);
Children geoDistance(boolean condition, String column, Double distance, DistanceUnit distanceUnit, String centralGeoLocation, Float boost);
/**
* 距离范围查询 以给定圆心和半径范围查询 距离类型为双精度
@ -405,12 +406,12 @@ public interface Geo<Children, R> extends Serializable {
* @param column
* @param distance 距离
* @param distanceUnit 距离单位
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
default Children geoDistance(boolean condition, R column, Double distance, DistanceUnit distanceUnit, GeoPoint centralGeoPoint, Float boost) {
return geoDistance(condition, FieldUtils.getFieldName(column), distance, distanceUnit, centralGeoPoint, boost);
default Children geoDistance(boolean condition, R column, Double distance, DistanceUnit distanceUnit, GeoLocation centralGeoLocation, Float boost) {
return geoDistance(condition, FieldUtils.getFieldName(column), distance, distanceUnit, centralGeoLocation, boost);
}
/**
@ -420,22 +421,22 @@ public interface Geo<Children, R> extends Serializable {
* @param column 列名 字符串
* @param distance 距离
* @param distanceUnit 距离单位
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
Children geoDistance(boolean condition, String column, Double distance, DistanceUnit distanceUnit, GeoPoint centralGeoPoint, Float boost);
Children geoDistance(boolean condition, String column, Double distance, DistanceUnit distanceUnit, GeoLocation centralGeoLocation, Float boost);
/**
* 距离范围查询 以给定圆心和半径范围查询 距离类型为字符串
*
* @param column
* @param distance 距离
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoDistance(R column, String distance, GeoPoint centralGeoPoint) {
return geoDistance(true, column, distance, centralGeoPoint, DEFAULT_BOOST);
default Children geoDistance(R column, String distance, GeoLocation centralGeoLocation) {
return geoDistance(true, column, distance, centralGeoLocation, DEFAULT_BOOST);
}
/**
@ -444,11 +445,11 @@ public interface Geo<Children, R> extends Serializable {
* @param condition 执行条件
* @param column
* @param distance 距离
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoDistance(boolean condition, R column, String distance, GeoPoint centralGeoPoint) {
return geoDistance(condition, column, distance, centralGeoPoint, DEFAULT_BOOST);
default Children geoDistance(boolean condition, R column, String distance, GeoLocation centralGeoLocation) {
return geoDistance(condition, column, distance, centralGeoLocation, DEFAULT_BOOST);
}
/**
@ -456,12 +457,12 @@ public interface Geo<Children, R> extends Serializable {
*
* @param column
* @param distance 距离
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
default Children geoDistance(R column, String distance, GeoPoint centralGeoPoint, Float boost) {
return geoDistance(true, column, distance, centralGeoPoint, boost);
default Children geoDistance(R column, String distance, GeoLocation centralGeoLocation, Float boost) {
return geoDistance(true, column, distance, centralGeoLocation, boost);
}
/**
@ -469,11 +470,11 @@ public interface Geo<Children, R> extends Serializable {
*
* @param column
* @param distance 距离
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoDistance(R column, String distance, String centralGeoPoint) {
return geoDistance(true, column, distance, centralGeoPoint, DEFAULT_BOOST);
default Children geoDistance(R column, String distance, String centralGeoLocation) {
return geoDistance(true, column, distance, centralGeoLocation, DEFAULT_BOOST);
}
/**
@ -482,11 +483,11 @@ public interface Geo<Children, R> extends Serializable {
* @param condition 执行条件
* @param column
* @param distance 距离
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoDistance(boolean condition, R column, String distance, String centralGeoPoint) {
return geoDistance(condition, column, distance, centralGeoPoint, DEFAULT_BOOST);
default Children geoDistance(boolean condition, R column, String distance, String centralGeoLocation) {
return geoDistance(condition, column, distance, centralGeoLocation, DEFAULT_BOOST);
}
/**
@ -494,12 +495,12 @@ public interface Geo<Children, R> extends Serializable {
*
* @param column
* @param distance 距离
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
default Children geoDistance(R column, String distance, String centralGeoPoint, Float boost) {
return geoDistance(true, column, distance, centralGeoPoint, boost);
default Children geoDistance(R column, String distance, String centralGeoLocation, Float boost) {
return geoDistance(true, column, distance, centralGeoLocation, boost);
}
/**
@ -508,12 +509,12 @@ public interface Geo<Children, R> extends Serializable {
* @param condition 执行条件
* @param column
* @param distance 距离
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
default Children geoDistance(boolean condition, R column, String distance, String centralGeoPoint, Float boost) {
return geoDistance(condition, FieldUtils.getFieldName(column), distance, centralGeoPoint, boost);
default Children geoDistance(boolean condition, R column, String distance, String centralGeoLocation, Float boost) {
return geoDistance(condition, FieldUtils.getFieldName(column), distance, centralGeoLocation, boost);
}
/**
@ -521,11 +522,11 @@ public interface Geo<Children, R> extends Serializable {
*
* @param column 列名 字符串
* @param distance 距离
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoDistance(String column, String distance, GeoPoint centralGeoPoint) {
return geoDistance(true, column, distance, centralGeoPoint, DEFAULT_BOOST);
default Children geoDistance(String column, String distance, GeoLocation centralGeoLocation) {
return geoDistance(true, column, distance, centralGeoLocation, DEFAULT_BOOST);
}
/**
@ -534,11 +535,11 @@ public interface Geo<Children, R> extends Serializable {
* @param condition 执行条件
* @param column 列名 字符串
* @param distance 距离
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoDistance(boolean condition, String column, String distance, GeoPoint centralGeoPoint) {
return geoDistance(condition, column, distance, centralGeoPoint, DEFAULT_BOOST);
default Children geoDistance(boolean condition, String column, String distance, GeoLocation centralGeoLocation) {
return geoDistance(condition, column, distance, centralGeoLocation, DEFAULT_BOOST);
}
/**
@ -546,12 +547,12 @@ public interface Geo<Children, R> extends Serializable {
*
* @param column 列名 字符串
* @param distance 距离
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
default Children geoDistance(String column, String distance, GeoPoint centralGeoPoint, Float boost) {
return geoDistance(true, column, distance, centralGeoPoint, boost);
default Children geoDistance(String column, String distance, GeoLocation centralGeoLocation, Float boost) {
return geoDistance(true, column, distance, centralGeoLocation, boost);
}
/**
@ -559,11 +560,11 @@ public interface Geo<Children, R> extends Serializable {
*
* @param column 列名 字符串
* @param distance 距离
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoDistance(String column, String distance, String centralGeoPoint) {
return geoDistance(true, column, distance, centralGeoPoint, DEFAULT_BOOST);
default Children geoDistance(String column, String distance, String centralGeoLocation) {
return geoDistance(true, column, distance, centralGeoLocation, DEFAULT_BOOST);
}
/**
@ -572,11 +573,11 @@ public interface Geo<Children, R> extends Serializable {
* @param condition 执行条件
* @param column 列名 字符串
* @param distance 距离
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @return wrapper
*/
default Children geoDistance(boolean condition, String column, String distance, String centralGeoPoint) {
return geoDistance(condition, column, distance, centralGeoPoint, DEFAULT_BOOST);
default Children geoDistance(boolean condition, String column, String distance, String centralGeoLocation) {
return geoDistance(condition, column, distance, centralGeoLocation, DEFAULT_BOOST);
}
/**
@ -584,12 +585,12 @@ public interface Geo<Children, R> extends Serializable {
*
* @param column 列名 字符串
* @param distance 距离
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
default Children geoDistance(String column, String distance, String centralGeoPoint, Float boost) {
return geoDistance(true, column, distance, centralGeoPoint, boost);
default Children geoDistance(String column, String distance, String centralGeoLocation, Float boost) {
return geoDistance(true, column, distance, centralGeoLocation, boost);
}
/**
@ -598,11 +599,11 @@ public interface Geo<Children, R> extends Serializable {
* @param condition 执行条件
* @param column 列名 字符串
* @param distance 距离
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
Children geoDistance(boolean condition, String column, String distance, String centralGeoPoint, Float boost);
Children geoDistance(boolean condition, String column, String distance, String centralGeoLocation, Float boost);
/**
* 距离范围查询 以给定圆心和半径范围查询 距离类型为字符串
@ -610,12 +611,12 @@ public interface Geo<Children, R> extends Serializable {
* @param condition 执行条件
* @param column
* @param distance 距离
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值
* @return wrapper
*/
default Children geoDistance(boolean condition, R column, String distance, GeoPoint centralGeoPoint, Float boost) {
return geoDistance(condition, FieldUtils.getFieldName(column), distance, centralGeoPoint, boost);
default Children geoDistance(boolean condition, R column, String distance, GeoLocation centralGeoLocation, Float boost) {
return geoDistance(condition, FieldUtils.getFieldName(column), distance, centralGeoLocation, boost);
}
/**
@ -624,11 +625,11 @@ public interface Geo<Children, R> extends Serializable {
* @param condition 执行条件 执行条件
* @param column 列名 字符串
* @param distance 距离
* @param centralGeoPoint 中心点 GeoPoint/字符串/哈希/wkt均支持
* @param centralGeoLocation 中心点 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值 权重
* @return wrapper wrapper
*/
Children geoDistance(boolean condition, String column, String distance, GeoPoint centralGeoPoint, Float boost);
Children geoDistance(boolean condition, String column, String distance, GeoLocation centralGeoLocation, Float boost);
/**
* 不规则多边形范围查询
@ -637,7 +638,7 @@ public interface Geo<Children, R> extends Serializable {
* @param geoPoints 多边形顶点列表
* @return wrapper
*/
default Children geoPolygon(R column, List<GeoPoint> geoPoints) {
default Children geoPolygon(R column, List<GeoLocation> geoPoints) {
return geoPolygon(true, column, geoPoints, DEFAULT_BOOST);
}
@ -649,7 +650,7 @@ public interface Geo<Children, R> extends Serializable {
* @param geoPoints 多边形顶点列表
* @return wrapper
*/
default Children geoPolygon(boolean condition, R column, List<GeoPoint> geoPoints) {
default Children geoPolygon(boolean condition, R column, List<GeoLocation> geoPoints) {
return geoPolygon(condition, column, geoPoints, DEFAULT_BOOST);
}
@ -661,7 +662,7 @@ public interface Geo<Children, R> extends Serializable {
* @param boost 权重值
* @return wrapper
*/
default Children geoPolygon(R column, List<GeoPoint> geoPoints, Float boost) {
default Children geoPolygon(R column, List<GeoLocation> geoPoints, Float boost) {
return geoPolygon(true, column, geoPoints, boost);
}
@ -707,7 +708,7 @@ public interface Geo<Children, R> extends Serializable {
* @param geoPoints 多边形顶点列表
* @return wrapper
*/
default Children geoPolygon(String column, List<GeoPoint> geoPoints) {
default Children geoPolygon(String column, List<GeoLocation> geoPoints) {
return geoPolygon(true, column, geoPoints, DEFAULT_BOOST);
}
@ -719,7 +720,7 @@ public interface Geo<Children, R> extends Serializable {
* @param geoPoints 多边形顶点列表
* @return wrapper
*/
default Children geoPolygon(boolean condition, String column, List<GeoPoint> geoPoints) {
default Children geoPolygon(boolean condition, String column, List<GeoLocation> geoPoints) {
return geoPolygon(condition, column, geoPoints, DEFAULT_BOOST);
}
@ -731,7 +732,7 @@ public interface Geo<Children, R> extends Serializable {
* @param boost 权重值
* @return wrapper
*/
default Children geoPolygon(String column, List<GeoPoint> geoPoints, Float boost) {
default Children geoPolygon(String column, List<GeoLocation> geoPoints, Float boost) {
return geoPolygon(true, column, geoPoints, boost);
}
@ -755,9 +756,9 @@ public interface Geo<Children, R> extends Serializable {
* @return wrapper
*/
default Children geoPolygonStr(boolean condition, String column, List<String> strPoints) {
List<GeoPoint> geoPoints = Optional.ofNullable(strPoints).orElseGet(ArrayList::new)
List<GeoLocation> geoPoints = Optional.ofNullable(strPoints).orElseGet(ArrayList::new)
.stream()
.map(GeoPoint::new)
.map(GeoUtils::create)
.collect(Collectors.toList());
return geoPolygon(condition, column, geoPoints, DEFAULT_BOOST);
}
@ -774,7 +775,7 @@ public interface Geo<Children, R> extends Serializable {
if (CollectionUtils.isEmpty(strPoints)) {
throw ExceptionUtils.eee("polygon point list must not be empty");
}
List<GeoPoint> geoPoints = strPoints.stream().map(GeoPoint::new).collect(Collectors.toList());
List<GeoLocation> geoPoints = strPoints.stream().map(GeoUtils::create).collect(Collectors.toList());
return geoPolygon(true, column, geoPoints, boost);
}
@ -787,7 +788,7 @@ public interface Geo<Children, R> extends Serializable {
* @param boost 权重值
* @return wrapper
*/
default Children geoPolygon(boolean condition, R column, List<GeoPoint> geoPoints, Float boost) {
default Children geoPolygon(boolean condition, R column, List<GeoLocation> geoPoints, Float boost) {
return geoPolygon(condition, FieldUtils.getFieldName(column), geoPoints, boost);
}
@ -796,12 +797,11 @@ public interface Geo<Children, R> extends Serializable {
*
* @param condition 执行条件 执行条件
* @param column 列名 字符串
* @param geoPoints 多边形顶点列表 多边形顶点列表 GeoPoint/字符串/哈希/wkt均支持
* @param geoPoints 多边形顶点列表 多边形顶点列表 GeoLocation/字符串/哈希/wkt均支持
* @param boost 权重值 权重值
* @return wrapper wrapper
*/
Children geoPolygon(boolean condition, String column, List<GeoPoint> geoPoints, Float boost);
Children geoPolygon(boolean condition, String column, List<GeoLocation> geoPoints, Float boost);
/**
* 图形GeoShape查询 已知被索引的图形id
@ -906,7 +906,7 @@ public interface Geo<Children, R> extends Serializable {
* @return wrapper
*/
default Children geoShape(R column, Geometry geometry) {
return geoShape(true, column, geometry, ShapeRelation.WITHIN, DEFAULT_BOOST);
return geoShape(true, column, geometry, GeoShapeRelation.Within, DEFAULT_BOOST);
}
/**
@ -914,10 +914,10 @@ public interface Geo<Children, R> extends Serializable {
*
* @param column 列名 字符串
* @param geometry 图形
* @param shapeRelation 图形关系(可参考ShapeRelation枚举)
* @param shapeRelation 图形关系(可参考GeoShapeRelation枚举)
* @return wrapper
*/
default Children geoShape(R column, Geometry geometry, ShapeRelation shapeRelation) {
default Children geoShape(R column, Geometry geometry, GeoShapeRelation shapeRelation) {
return geoShape(true, column, geometry, shapeRelation, DEFAULT_BOOST);
}
@ -927,10 +927,10 @@ public interface Geo<Children, R> extends Serializable {
* @param condition 执行条件
* @param column 列名 字符串
* @param geometry 图形
* @param shapeRelation 图形关系(可参考ShapeRelation枚举)
* @param shapeRelation 图形关系(可参考GeoShapeRelation枚举)
* @return wrapper
*/
default Children geoShape(boolean condition, R column, Geometry geometry, ShapeRelation shapeRelation) {
default Children geoShape(boolean condition, R column, Geometry geometry, GeoShapeRelation shapeRelation) {
return geoShape(condition, column, geometry, shapeRelation, DEFAULT_BOOST);
}
@ -939,11 +939,11 @@ public interface Geo<Children, R> extends Serializable {
*
* @param column 列名 字符串
* @param geometry 图形
* @param shapeRelation 图形关系(可参考ShapeRelation枚举)
* @param shapeRelation 图形关系(可参考GeoShapeRelation枚举)
* @param boost 权重值
* @return wrapper
*/
default Children geoShape(R column, Geometry geometry, ShapeRelation shapeRelation, Float boost) {
default Children geoShape(R column, Geometry geometry, GeoShapeRelation shapeRelation, Float boost) {
return geoShape(true, column, geometry, shapeRelation, boost);
}
@ -955,7 +955,7 @@ public interface Geo<Children, R> extends Serializable {
* @return wrapper
*/
default Children geoShape(String column, Geometry geometry) {
return geoShape(true, column, geometry, ShapeRelation.WITHIN, DEFAULT_BOOST);
return geoShape(true, column, geometry, GeoShapeRelation.Within, DEFAULT_BOOST);
}
/**
@ -963,10 +963,10 @@ public interface Geo<Children, R> extends Serializable {
*
* @param column 列名 字符串
* @param geometry 图形
* @param shapeRelation 图形关系(可参考ShapeRelation枚举)
* @param shapeRelation 图形关系(可参考GeoShapeRelation枚举)
* @return wrapper
*/
default Children geoShape(String column, Geometry geometry, ShapeRelation shapeRelation) {
default Children geoShape(String column, Geometry geometry, GeoShapeRelation shapeRelation) {
return geoShape(true, column, geometry, shapeRelation, DEFAULT_BOOST);
}
@ -976,10 +976,10 @@ public interface Geo<Children, R> extends Serializable {
* @param condition 执行条件
* @param column 列名 字符串
* @param geometry 图形
* @param shapeRelation 图形关系(可参考ShapeRelation枚举)
* @param shapeRelation 图形关系(可参考GeoShapeRelation枚举)
* @return wrapper
*/
default Children geoShape(boolean condition, String column, Geometry geometry, ShapeRelation shapeRelation) {
default Children geoShape(boolean condition, String column, Geometry geometry, GeoShapeRelation shapeRelation) {
return geoShape(condition, column, geometry, shapeRelation, DEFAULT_BOOST);
}
@ -988,11 +988,11 @@ public interface Geo<Children, R> extends Serializable {
*
* @param column 列名 字符串
* @param geometry 图形
* @param shapeRelation 图形关系(可参考ShapeRelation枚举)
* @param shapeRelation 图形关系(可参考GeoShapeRelation枚举)
* @param boost 权重值
* @return wrapper
*/
default Children geoShape(String column, Geometry geometry, ShapeRelation shapeRelation, Float boost) {
default Children geoShape(String column, Geometry geometry, GeoShapeRelation shapeRelation, Float boost) {
return geoShape(true, column, geometry, shapeRelation, boost);
}
@ -1002,11 +1002,11 @@ public interface Geo<Children, R> extends Serializable {
* @param condition 执行条件
* @param column 列名 字符串
* @param geometry 图形
* @param shapeRelation 图形关系(可参考ShapeRelation枚举)
* @param shapeRelation 图形关系(可参考GeoShapeRelation枚举)
* @param boost 权重值
* @return wrapper
*/
default Children geoShape(boolean condition, R column, Geometry geometry, ShapeRelation shapeRelation, Float boost) {
default Children geoShape(boolean condition, R column, Geometry geometry, GeoShapeRelation shapeRelation, Float boost) {
return geoShape(condition, FieldUtils.getFieldName(column), geometry, shapeRelation, boost);
}
@ -1016,10 +1016,11 @@ public interface Geo<Children, R> extends Serializable {
* @param condition 执行条件 执行条件
* @param column 列名 字符串
* @param geometry 图形
* @param shapeRelation 图形关系(可参考ShapeRelation枚举)
* @param shapeRelation 图形关系(可参考GeoShapeRelation枚举)
* @param boost 权重值 权重值
* @return wrapper wrapper
*/
Children geoShape(boolean condition, String column, Geometry geometry, ShapeRelation shapeRelation, Float boost);
Children geoShape(boolean condition, String column, Geometry geometry, GeoShapeRelation shapeRelation, Float boost);
}

View File

@ -1,11 +1,11 @@
package org.dromara.easyes.core.conditions.function;
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
import co.elastic.clients.elasticsearch.indices.IndexSettings;
import org.dromara.easyes.annotation.rely.FieldType;
import org.dromara.easyes.core.toolkit.FieldUtils;
import org.elasticsearch.common.settings.Settings;
import java.io.Serializable;
import java.util.Map;
/**
* 索引相关
@ -27,7 +27,7 @@ public interface Index<Children, R> extends Serializable {
* @param maxResultWindow 最大返回数
* @return wrapper
*/
Children maxResultWindow(Integer maxResultWindow);
Children maxResultWindow(Long maxResultWindow);
/**
* 设置索引的分片数和副本数
@ -44,7 +44,7 @@ public interface Index<Children, R> extends Serializable {
* @param settings settings
* @return wrapper
*/
Children settings(Settings settings);
Children settings(IndexSettings.Builder settings);
/**
* 用户自行指定mapping
@ -52,7 +52,7 @@ public interface Index<Children, R> extends Serializable {
* @param mapping mapping信息
* @return wrapper
*/
Children mapping(Map<String, Object> mapping);
Children mapping(TypeMapping.Builder mapping);
/**
* 设置mapping信息
@ -85,7 +85,7 @@ public interface Index<Children, R> extends Serializable {
* @param boost 权重
* @return wrapper
*/
default Children mapping(R column, FieldType fieldType, Float boost) {
default Children mapping(R column, FieldType fieldType, Double boost) {
return mapping(column, fieldType, null, null, null, null, boost);
}
@ -98,7 +98,7 @@ public interface Index<Children, R> extends Serializable {
* @param boost 权重
* @return wrapper
*/
default Children mapping(R column, FieldType fieldType, Boolean fieldData, Float boost) {
default Children mapping(R column, FieldType fieldType, Boolean fieldData, Double boost) {
return mapping(column, fieldType, null, null, null, fieldData, boost);
}
@ -151,7 +151,7 @@ public interface Index<Children, R> extends Serializable {
* @param boost 权重
* @return wrapper
*/
default Children mapping(R column, FieldType fieldType, String analyzer, String searchAnalyzer, Float boost) {
default Children mapping(R column, FieldType fieldType, String analyzer, String searchAnalyzer, Double boost) {
return mapping(column, fieldType, analyzer, searchAnalyzer, null, null, boost);
}
@ -167,7 +167,7 @@ public interface Index<Children, R> extends Serializable {
* @param boost 权重值
* @return wrapper
*/
default Children mapping(R column, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat, Boolean fieldData, Float boost) {
default Children mapping(R column, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat, Boolean fieldData, Double boost) {
return mapping(FieldUtils.getFieldName(column), fieldType, analyzer, searchAnalyzer, dateFormat, fieldData, boost);
}
@ -202,7 +202,7 @@ public interface Index<Children, R> extends Serializable {
* @param boost 权重
* @return wrapper
*/
default Children mapping(String column, FieldType fieldType, Float boost) {
default Children mapping(String column, FieldType fieldType, Double boost) {
return mapping(column, fieldType, null, null, null, boost);
}
@ -256,7 +256,7 @@ public interface Index<Children, R> extends Serializable {
* @param boost 权重
* @return wrapper
*/
default Children mapping(String column, FieldType fieldType, String analyzer, String searchAnalyzer, Boolean fieldData, Float boost) {
default Children mapping(String column, FieldType fieldType, String analyzer, String searchAnalyzer, Boolean fieldData, Double boost) {
return mapping(column, fieldType, analyzer, searchAnalyzer, null, fieldData, boost);
}
@ -273,7 +273,7 @@ public interface Index<Children, R> extends Serializable {
* @param boost 字段权重值
* @return wrapper
*/
Children mapping(String column, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat, Boolean fieldData, Float boost);
Children mapping(String column, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat, Boolean fieldData, Double boost);
/**
* 设置创建别名信息

View File

@ -1,6 +1,6 @@
package org.dromara.easyes.core.conditions.function;
import org.apache.lucene.search.join.ScoreMode;
import co.elastic.clients.elasticsearch._types.query_dsl.ChildScoreMode;
import java.io.Serializable;
import java.util.function.Consumer;
@ -142,7 +142,7 @@ public interface Nested<Param, Children> extends Serializable {
* @param scoreMode 得分模式
* @return wrapper
*/
default Children nested(String path, Consumer<Param> consumer, ScoreMode scoreMode) {
default Children nested(String path, Consumer<Param> consumer, ChildScoreMode scoreMode) {
return nested(true, path, consumer, scoreMode);
}
@ -155,7 +155,7 @@ public interface Nested<Param, Children> extends Serializable {
* @return wrapper
*/
default Children nested(boolean condition, String path, Consumer<Param> consumer) {
return nested(condition, path, consumer, ScoreMode.None);
return nested(condition, path, consumer, ChildScoreMode.None);
}
/**
@ -167,7 +167,7 @@ public interface Nested<Param, Children> extends Serializable {
* @param scoreMode 得分模式
* @return wrapper
*/
Children nested(boolean condition, String path, Consumer<Param> consumer, ScoreMode scoreMode);
Children nested(boolean condition, String path, Consumer<Param> consumer, ChildScoreMode scoreMode);
/**
@ -189,7 +189,7 @@ public interface Nested<Param, Children> extends Serializable {
* @param scoreMode 得分模式
* @return wrapper
*/
default Children hasChild(String type, Consumer<Param> consumer, ScoreMode scoreMode) {
default Children hasChild(String type, Consumer<Param> consumer, ChildScoreMode scoreMode) {
return hasChild(true, type, consumer, scoreMode);
}
@ -202,7 +202,7 @@ public interface Nested<Param, Children> extends Serializable {
* @return wrapper
*/
default Children hasChild(boolean condition, String type, Consumer<Param> consumer) {
return hasChild(condition, type, consumer, ScoreMode.None);
return hasChild(condition, type, consumer, ChildScoreMode.None);
}
/**
@ -214,7 +214,7 @@ public interface Nested<Param, Children> extends Serializable {
* @param scoreMode 得分模式
* @return wrapper
*/
Children hasChild(boolean condition, String type, Consumer<Param> consumer, ScoreMode scoreMode);
Children hasChild(boolean condition, String type, Consumer<Param> consumer, ChildScoreMode scoreMode);
/**
* 父子类型-根据子查父匹配 返回子文档 无需指定父,由框架根据@Join注解自行推断其父

View File

@ -85,7 +85,7 @@ public interface Query<Children, T, R> extends Serializable {
* @param score 最小得分
* @return wrapper
*/
Children minScore(Float score);
Children minScore(Double score);
/**
* 开启计算得分 默认值为关闭状态

View File

@ -1,6 +1,7 @@
package org.dromara.easyes.core.conditions.select;
import co.elastic.clients.elasticsearch._types.FieldValue;
import org.dromara.easyes.core.biz.EsPageInfo;
import org.dromara.easyes.core.biz.SAPageInfo;
import org.dromara.easyes.core.kernel.EsChainWrapper;
@ -71,7 +72,7 @@ public interface EsChainQuery<T> extends EsChainWrapper<T> {
return getBaseEsMapper().pageQuery(getWrapper(), pageNum, pageSize);
}
default SAPageInfo<T> searchAfterPage(List<Object> searchAfter, Integer pageSize) {
default SAPageInfo<T> searchAfterPage(List<FieldValue> searchAfter, Integer pageSize) {
return getBaseEsMapper().searchAfterPage(getWrapper(), searchAfter, pageSize);
}
}

View File

@ -1,5 +1,6 @@
package org.dromara.easyes.core.index;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import org.dromara.easyes.common.enums.ProcessIndexStrategyEnum;
import org.dromara.easyes.common.strategy.AutoProcessIndexStrategy;
import org.dromara.easyes.common.utils.LogUtils;
@ -8,7 +9,6 @@ import org.dromara.easyes.core.biz.EntityInfo;
import org.dromara.easyes.core.biz.EsIndexInfo;
import org.dromara.easyes.core.toolkit.EntityInfoHelper;
import org.dromara.easyes.core.toolkit.IndexUtils;
import org.elasticsearch.client.RestHighLevelClient;
/**
* 自动非平滑托管索引实现类, 重建索引时原索引数据会被删除
@ -23,12 +23,12 @@ public class AutoProcessIndexNotSmoothlyStrategy implements AutoProcessIndexStra
}
@Override
public void processIndexAsync(Class<?> entityClass, RestHighLevelClient client) {
public void processIndexAsync(Class<?> entityClass, ElasticsearchClient client) {
LogUtils.info("===> Not smoothly process index mode activated");
IndexUtils.supplyAsync(this::process, entityClass, client);
}
private boolean process(Class<?> entityClass, RestHighLevelClient client) {
private boolean process(Class<?> entityClass, ElasticsearchClient client) {
EntityInfo entityInfo = EntityInfoHelper.getEntityInfo(entityClass);
// 是否存在索引
boolean existsIndex = IndexUtils.existsIndexWithRetry(entityInfo, client);
@ -43,7 +43,7 @@ public class AutoProcessIndexNotSmoothlyStrategy implements AutoProcessIndexStra
}
}
private boolean doUpdateIndex(EntityInfo entityInfo, Class<?> clazz, RestHighLevelClient client) {
private boolean doUpdateIndex(EntityInfo entityInfo, Class<?> clazz, ElasticsearchClient client) {
// 获取索引信息
EsIndexInfo esIndexInfo = IndexUtils.getIndexInfo(client, entityInfo.getRetrySuccessIndexName());
@ -65,7 +65,7 @@ public class AutoProcessIndexNotSmoothlyStrategy implements AutoProcessIndexStra
return IndexUtils.createIndex(client, entityInfo, createIndexParam);
}
private boolean doCreateIndex(EntityInfo entityInfo, Class<?> clazz, RestHighLevelClient client) {
private boolean doCreateIndex(EntityInfo entityInfo, Class<?> clazz, ElasticsearchClient client) {
// 初始化创建索引参数
CreateIndexParam createIndexParam = IndexUtils.getCreateIndexParam(entityInfo, clazz);

View File

@ -1,5 +1,6 @@
package org.dromara.easyes.core.index;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import org.dromara.easyes.common.enums.ProcessIndexStrategyEnum;
import org.dromara.easyes.common.strategy.AutoProcessIndexStrategy;
import org.dromara.easyes.common.utils.LogUtils;
@ -8,7 +9,6 @@ import org.dromara.easyes.core.biz.EntityInfo;
import org.dromara.easyes.core.biz.EsIndexInfo;
import org.dromara.easyes.core.toolkit.EntityInfoHelper;
import org.dromara.easyes.core.toolkit.IndexUtils;
import org.elasticsearch.client.RestHighLevelClient;
import static org.dromara.easyes.common.constants.BaseEsConstants.S1_SUFFIX;
import static org.dromara.easyes.common.constants.BaseEsConstants.SO_SUFFIX;
@ -26,12 +26,12 @@ public class AutoProcessIndexSmoothlyStrategy implements AutoProcessIndexStrateg
}
@Override
public void processIndexAsync(Class<?> entityClass, RestHighLevelClient client) {
public void processIndexAsync(Class<?> entityClass, ElasticsearchClient client) {
LogUtils.info("===> Smoothly process index mode activated");
IndexUtils.supplyAsync(this::process, entityClass, client);
}
private synchronized boolean process(Class<?> entityClass, RestHighLevelClient client) {
private synchronized boolean process(Class<?> entityClass, ElasticsearchClient client) {
EntityInfo entityInfo = EntityInfoHelper.getEntityInfo(entityClass);
// 索引是否已存在
@ -48,7 +48,7 @@ public class AutoProcessIndexSmoothlyStrategy implements AutoProcessIndexStrateg
}
private boolean doUpdateIndex(EntityInfo entityInfo, Class<?> clazz, RestHighLevelClient client) {
private boolean doUpdateIndex(EntityInfo entityInfo, Class<?> clazz, ElasticsearchClient client) {
// 获取索引信息
EsIndexInfo esIndexInfo = IndexUtils.getIndexInfo(client, entityInfo.getIndexName());
@ -114,11 +114,11 @@ public class AutoProcessIndexSmoothlyStrategy implements AutoProcessIndexStrateg
}
}
private boolean doDataMigration(String oldIndexName, String releaseIndexName, Integer maxResultWindow, RestHighLevelClient client) {
private boolean doDataMigration(String oldIndexName, String releaseIndexName, Long maxResultWindow, ElasticsearchClient client) {
return IndexUtils.reindex(client, oldIndexName, releaseIndexName, maxResultWindow);
}
private boolean doCreateIndex(EntityInfo entityInfo, Class<?> clazz, RestHighLevelClient client) {
private boolean doCreateIndex(EntityInfo entityInfo, Class<?> clazz, ElasticsearchClient client) {
// 初始化创建索引参数
CreateIndexParam createIndexParam = IndexUtils.getCreateIndexParam(entityInfo, clazz);
// 执行创建

View File

@ -1,22 +1,17 @@
package org.dromara.easyes.core.kernel;
import org.apache.lucene.search.join.ScoreMode;
import co.elastic.clients.elasticsearch._types.*;
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
import co.elastic.clients.elasticsearch._types.query_dsl.ChildScoreMode;
import co.elastic.clients.elasticsearch._types.query_dsl.Operator;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.indices.IndexSettings;
import co.elastic.clients.util.NamedValue;
import org.dromara.easyes.annotation.rely.FieldType;
import org.dromara.easyes.core.biz.EntityFieldInfo;
import org.dromara.easyes.core.biz.OrderByParam;
import org.dromara.easyes.core.conditions.function.*;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.geometry.Geometry;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import java.time.ZoneId;
import java.util.Collection;
@ -223,7 +218,7 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
}
@Override
public Children sort(boolean condition, List<SortBuilder<?>> sortBuilders) {
public Children sort(boolean condition, List<SortOptions> sortBuilders) {
getWrapper().sort(condition, sortBuilders);
return typedThis;
}
@ -300,7 +295,7 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
}
@Override
public Children sort(boolean condition, SortBuilder<?> sortBuilder) {
public Children sort(boolean condition, SortOptions sortBuilder) {
getWrapper().sort(condition, sortBuilder);
return typedThis;
}
@ -312,25 +307,25 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
}
@Override
public Children geoBoundingBox(boolean condition, R column, GeoPoint topLeft, GeoPoint bottomRight, Float boost) {
public Children geoBoundingBox(boolean condition, R column, GeoLocation topLeft, GeoLocation bottomRight, Float boost) {
getWrapper().geoBoundingBox(condition, column, topLeft, bottomRight, boost);
return typedThis;
}
@Override
public Children geoDistance(boolean condition, R column, Double distance, DistanceUnit distanceUnit, GeoPoint centralGeoPoint, Float boost) {
getWrapper().geoDistance(condition, column, distance, distanceUnit, centralGeoPoint, boost);
public Children geoDistance(boolean condition, R column, Double distance, DistanceUnit distanceUnit, GeoLocation centralGeoLocation, Float boost) {
getWrapper().geoDistance(condition, column, distance, distanceUnit, centralGeoLocation, boost);
return typedThis;
}
@Override
public Children geoDistance(boolean condition, R column, String distance, GeoPoint centralGeoPoint, Float boost) {
getWrapper().geoDistance(condition, column, distance, centralGeoPoint, boost);
public Children geoDistance(boolean condition, R column, String distance, GeoLocation centralGeoLocation, Float boost) {
getWrapper().geoDistance(condition, column, distance, centralGeoLocation, boost);
return typedThis;
}
@Override
public Children geoPolygon(boolean condition, R column, List<GeoPoint> geoPoints, Float boost) {
public Children geoPolygon(boolean condition, R column, List<GeoLocation> geoPoints, Float boost) {
getWrapper().geoPolygon(condition, column, geoPoints, boost);
return typedThis;
}
@ -342,7 +337,7 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
}
@Override
public Children geoShape(boolean condition, R column, Geometry geometry, ShapeRelation shapeRelation, Float boost) {
public Children geoShape(boolean condition, R column, Geometry geometry, GeoShapeRelation shapeRelation, Float boost) {
getWrapper().geoShape(condition, column, geometry, shapeRelation, boost);
return typedThis;
}
@ -493,7 +488,7 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
}
@Override
public Children geoBoundingBox(boolean condition, String column, GeoPoint topLeft, GeoPoint bottomRight, Float boost) {
public Children geoBoundingBox(boolean condition, String column, GeoLocation topLeft, GeoLocation bottomRight, Float boost) {
getWrapper().geoBoundingBox(condition, column, topLeft, bottomRight, boost);
return typedThis;
}
@ -505,31 +500,31 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
}
@Override
public Children geoDistance(boolean condition, String column, Double distance, DistanceUnit distanceUnit, GeoPoint centralGeoPoint, Float boost) {
getWrapper().geoDistance(condition, column, distance, distanceUnit, centralGeoPoint, boost);
public Children geoDistance(boolean condition, String column, Double distance, DistanceUnit distanceUnit, GeoLocation centralGeoLocation, Float boost) {
getWrapper().geoDistance(condition, column, distance, distanceUnit, centralGeoLocation, boost);
return typedThis;
}
@Override
public Children geoDistance(boolean condition, String column, Double distance, DistanceUnit distanceUnit, String centralGeoPoint, Float boost) {
getWrapper().geoDistance(condition, column, distance, distanceUnit, centralGeoPoint, boost);
public Children geoDistance(boolean condition, String column, Double distance, DistanceUnit distanceUnit, String centralGeoLocation, Float boost) {
getWrapper().geoDistance(condition, column, distance, distanceUnit, centralGeoLocation, boost);
return typedThis;
}
@Override
public Children geoDistance(boolean condition, String column, String distance, GeoPoint centralGeoPoint, Float boost) {
getWrapper().geoDistance(condition, column, distance, centralGeoPoint, boost);
public Children geoDistance(boolean condition, String column, String distance, GeoLocation centralGeoLocation, Float boost) {
getWrapper().geoDistance(condition, column, distance, centralGeoLocation, boost);
return typedThis;
}
@Override
public Children geoDistance(boolean condition, String column, String distance, String centralGeoPoint, Float boost) {
getWrapper().geoDistance(condition, column, distance, centralGeoPoint, boost);
public Children geoDistance(boolean condition, String column, String distance, String centralGeoLocation, Float boost) {
getWrapper().geoDistance(condition, column, distance, centralGeoLocation, boost);
return typedThis;
}
@Override
public Children geoPolygon(boolean condition, String column, List<GeoPoint> geoPoints, Float boost) {
public Children geoPolygon(boolean condition, String column, List<GeoLocation> geoPoints, Float boost) {
getWrapper().geoPolygon(condition, column, geoPoints, boost);
return typedThis;
}
@ -541,13 +536,13 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
}
@Override
public Children geoShape(boolean condition, String column, Geometry geometry, ShapeRelation shapeRelation, Float boost) {
public Children geoShape(boolean condition, String column, Geometry geometry, GeoShapeRelation shapeRelation, Float boost) {
getWrapper().geoShape(condition, column, geometry, shapeRelation, boost);
return typedThis;
}
@Override
public Children hasChild(boolean condition, String type, Consumer<Param> consumer, ScoreMode scoreMode) {
public Children hasChild(boolean condition, String type, Consumer<Param> consumer, ChildScoreMode scoreMode) {
getWrapper().hasChild(condition, type, consumer, scoreMode);
return typedThis;
}
@ -572,13 +567,13 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
@Override
public Children orderByDistanceAsc(boolean condition, String column, DistanceUnit unit, GeoDistance geoDistance, GeoPoint... geoPoints) {
public Children orderByDistanceAsc(boolean condition, String column, DistanceUnit unit, GeoDistanceType geoDistance, GeoLocation... geoPoints) {
getWrapper().orderByDistanceAsc(condition, column, unit, geoDistance, geoPoints);
return typedThis;
}
@Override
public Children orderByDistanceDesc(boolean condition, String column, DistanceUnit unit, GeoDistance geoDistance, GeoPoint... geoPoints) {
public Children orderByDistanceDesc(boolean condition, String column, DistanceUnit unit, GeoDistanceType geoDistance, GeoLocation... geoPoints) {
getWrapper().orderByDistanceDesc(condition, column, unit, geoDistance, geoPoints);
return typedThis;
}
@ -632,7 +627,7 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
}
@Override
public Children nested(boolean condition, String path, Consumer<Param> consumer, ScoreMode scoreMode) {
public Children nested(boolean condition, String path, Consumer<Param> consumer, ChildScoreMode scoreMode) {
getWrapper().nested(condition, path, consumer, scoreMode);
return typedThis;
}
@ -662,20 +657,20 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
}
@Override
public Children setSearchSourceBuilder(boolean condition, SearchSourceBuilder searchSourceBuilder) {
public Children setSearchSourceBuilder(boolean condition, SearchRequest.Builder searchSourceBuilder) {
getWrapper().setSearchSourceBuilder(condition, searchSourceBuilder);
return typedThis;
}
@Override
public Children mix(boolean condition, QueryBuilder queryBuilder) {
public Children mix(boolean condition, co.elastic.clients.elasticsearch._types.query_dsl.Query.Builder queryBuilder) {
getWrapper().mix(condition, queryBuilder);
return typedThis;
}
@Override
public Children bucketOrder(boolean condition, List<BucketOrder> bucketOrders) {
public Children bucketOrder(boolean condition, List<NamedValue<SortOrder>> bucketOrders) {
getWrapper().bucketOrder(condition, bucketOrders);
return typedThis;
}
@ -705,7 +700,7 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
}
@Override
public Children minScore(Float score) {
public Children minScore(Double score) {
getWrapper().minScore(score);
return typedThis;
}
@ -747,7 +742,7 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
}
@Override
public Children maxResultWindow(Integer maxResultWindow) {
public Children maxResultWindow(Long maxResultWindow) {
getWrapper().maxResultWindow(maxResultWindow);
return typedThis;
}
@ -759,19 +754,19 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
}
@Override
public Children settings(Settings settings) {
public Children settings(IndexSettings.Builder settings) {
getWrapper().settings(settings);
return typedThis;
}
@Override
public Children mapping(Map<String, Object> mapping) {
public Children mapping(TypeMapping.Builder mapping) {
getWrapper().mapping(mapping);
return typedThis;
}
@Override
public Children mapping(String column, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat, Boolean fieldData, Float boost) {
public Children mapping(String column, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat, Boolean fieldData, Double boost) {
getWrapper().mapping(column, fieldType, analyzer, searchAnalyzer, dateFormat, fieldData, boost);
return typedThis;
}

View File

@ -1,6 +1,12 @@
package org.dromara.easyes.core.kernel;
import org.apache.lucene.search.join.ScoreMode;
import co.elastic.clients.elasticsearch._types.*;
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
import co.elastic.clients.elasticsearch._types.query_dsl.ChildScoreMode;
import co.elastic.clients.elasticsearch._types.query_dsl.Operator;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.indices.IndexSettings;
import co.elastic.clients.util.NamedValue;
import org.dromara.easyes.annotation.rely.FieldType;
import org.dromara.easyes.common.enums.AggregationTypeEnum;
import org.dromara.easyes.common.enums.EsQueryTypeEnum;
@ -9,18 +15,8 @@ import org.dromara.easyes.common.utils.*;
import org.dromara.easyes.core.biz.*;
import org.dromara.easyes.core.conditions.function.*;
import org.dromara.easyes.core.toolkit.EntityInfoHelper;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.DistanceUnit;
import org.dromara.easyes.core.toolkit.GeoUtils;
import org.elasticsearch.geometry.Geometry;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import java.time.ZoneId;
import java.util.*;
@ -179,7 +175,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
}
@Override
public Children nested(boolean condition, String path, Consumer<Children> consumer, ScoreMode scoreMode) {
public Children nested(boolean condition, String path, Consumer<Children> consumer, ChildScoreMode scoreMode) {
return addNested(condition, path, scoreMode, consumer);
}
@ -189,7 +185,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
}
@Override
public Children hasChild(boolean condition, String type, Consumer<Children> consumer, ScoreMode scoreMode) {
public Children hasChild(boolean condition, String type, Consumer<Children> consumer, ChildScoreMode scoreMode) {
return addJoin(condition, HAS_CHILD, type, scoreMode, consumer);
}
@ -308,13 +304,13 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
if (condition) {
Assert.notBlank(topLeft, "TopLeft must not be null in geoBoundingBox query");
Assert.notBlank(bottomRight, "BottomRight must not be null in geoBoundingBox query");
return geoBoundingBox(true, column, new GeoPoint(topLeft), new GeoPoint(bottomRight), boost);
return geoBoundingBox(true, column, GeoUtils.create(topLeft), GeoUtils.create(bottomRight), boost);
}
return typedThis;
}
@Override
public Children geoBoundingBox(boolean condition, String column, GeoPoint topLeft, GeoPoint bottomRight, Float boost) {
public Children geoBoundingBox(boolean condition, String column, GeoLocation topLeft, GeoLocation bottomRight, Float boost) {
if (condition) {
Assert.notNull(topLeft, "TopLeft point must not be null in geoBoundingBox query");
Assert.notNull(bottomRight, "BottomRight point must not be null in geoBoundingBox query");
@ -323,46 +319,46 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
}
@Override
public Children geoDistance(boolean condition, String column, Double distance, DistanceUnit distanceUnit, GeoPoint centralGeoPoint, Float boost) {
public Children geoDistance(boolean condition, String column, Double distance, DistanceUnit distanceUnit, GeoLocation centralGeoLocation, Float boost) {
if (condition) {
Assert.notNull(distance, "Distance must not be null in geoDistance query");
Assert.notNull(distanceUnit, "Distance unit must not be null in geoDistance query");
Assert.notNull(centralGeoPoint, "CentralGeoPoint must not be null in geoDistance query");
Assert.notNull(centralGeoLocation, "CentralGeoLocation must not be null in geoDistance query");
}
return addParam(condition, GEO_DISTANCE, column, distance, distanceUnit, centralGeoPoint, boost);
return addParam(condition, GEO_DISTANCE, column, distance, distanceUnit, centralGeoLocation, boost);
}
@Override
public Children geoDistance(boolean condition, String column, Double distance, DistanceUnit distanceUnit, String centralGeoPoint, Float boost) {
public Children geoDistance(boolean condition, String column, Double distance, DistanceUnit distanceUnit, String centralGeoLocation, Float boost) {
if (condition) {
Assert.notBlank(centralGeoPoint, "centralGeoPoint must not be null in geoDistance query");
return geoDistance(true, column, distance, distanceUnit, new GeoPoint(centralGeoPoint), boost);
Assert.notBlank(centralGeoLocation, "centralGeoLocation must not be null in geoDistance query");
return geoDistance(true, column, distance, distanceUnit, GeoUtils.create(centralGeoLocation), boost);
}
return typedThis;
}
@Override
public Children geoDistance(boolean condition, String column, String distance, GeoPoint centralGeoPoint, Float boost) {
public Children geoDistance(boolean condition, String column, String distance, GeoLocation centralGeoLocation, Float boost) {
if (condition) {
Assert.notBlank(distance, "Distance must not be null in geoDistance query");
Assert.notNull(centralGeoPoint, "CentralGeoPoint must not be null in geoDistance query");
Assert.notNull(centralGeoLocation, "CentralGeoLocation must not be null in geoDistance query");
}
return addParam(condition, GEO_DISTANCE, column, distance, null, centralGeoPoint, boost);
return addParam(condition, GEO_DISTANCE, column, distance, null, centralGeoLocation, boost);
}
@Override
public Children geoDistance(boolean condition, String column, String distance, String centralGeoPoint, Float boost) {
public Children geoDistance(boolean condition, String column, String distance, String centralGeoLocation, Float boost) {
if (condition) {
Assert.notBlank(centralGeoPoint, "centralGeoPoint must not be null in geoDistance query");
return geoDistance(true, column, distance, new GeoPoint(centralGeoPoint), boost);
Assert.notBlank(centralGeoLocation, "centralGeoLocation must not be null in geoDistance query");
return geoDistance(true, column, distance, GeoUtils.create(centralGeoLocation), boost);
}
return typedThis;
}
@Override
public Children geoPolygon(boolean condition, String column, List<GeoPoint> geoPoints, Float boost) {
public Children geoPolygon(boolean condition, String column, List<GeoLocation> geoPoints, Float boost) {
if (condition) {
Assert.notEmpty(geoPoints, "GeoPoints must not be null in geoPolygon query");
Assert.notEmpty(geoPoints, "GeoLocations must not be null in geoPolygon query");
}
return addParam(condition, GEO_POLYGON, column, geoPoints, boost);
}
@ -376,10 +372,10 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
}
@Override
public Children geoShape(boolean condition, String column, Geometry geometry, ShapeRelation shapeRelation, Float boost) {
public Children geoShape(boolean condition, String column, Geometry geometry, GeoShapeRelation shapeRelation, Float boost) {
if (condition) {
Assert.notNull(geometry, "Geometry must not be null in geoShape query");
Assert.notNull(geometry, "ShapeRelation must not be null in geoShape query");
Assert.notNull(geometry, "GeoShapeRelation must not be null in geoShape query");
}
return addParam(condition, GEO_SHAPE, column, geometry, shapeRelation, null, boost);
}
@ -395,7 +391,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
.forEach(column -> {
BaseSortParam baseSortParam = BaseSortParam.builder()
.sortField(column)
.sortOrder(isAsc ? SortOrder.ASC : SortOrder.DESC)
.sortOrder(isAsc ? SortOrder.Asc : SortOrder.Desc)
.orderTypeEnum(OrderTypeEnum.FIELD)
.build();
baseSortParams.add(baseSortParam);
@ -413,14 +409,14 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
}
@Override
public Children orderByDistanceAsc(boolean condition, String column, DistanceUnit unit, GeoDistance geoDistance, GeoPoint... geoPoints) {
public Children orderByDistanceAsc(boolean condition, String column, DistanceUnit unit, GeoDistanceType geoDistance, GeoLocation... geoPoints) {
if (ArrayUtils.isNotEmpty(geoPoints)) {
if (condition) {
BaseSortParam baseSortParam = BaseSortParam.builder()
.sortField(column)
.sortOrder(SortOrder.ASC)
.sortOrder(SortOrder.Asc)
.orderTypeEnum(OrderTypeEnum.GEO)
.geoPoints(geoPoints)
.geoPoints(Arrays.asList(geoPoints))
.unit(unit)
.geoDistance(geoDistance)
.build();
@ -431,14 +427,14 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
}
@Override
public Children orderByDistanceDesc(boolean condition, String column, DistanceUnit unit, GeoDistance geoDistance, GeoPoint... geoPoints) {
public Children orderByDistanceDesc(boolean condition, String column, DistanceUnit unit, GeoDistanceType geoDistance, GeoLocation... geoPoints) {
if (ArrayUtils.isNotEmpty(geoPoints)) {
if (condition) {
BaseSortParam baseSortParam = BaseSortParam.builder()
.sortField(column)
.sortOrder(SortOrder.DESC)
.sortOrder(SortOrder.Desc)
.orderTypeEnum(OrderTypeEnum.GEO)
.geoPoints(geoPoints)
.geoPoints(Arrays.asList(geoPoints))
.unit(unit)
.geoDistance(geoDistance)
.build();
@ -449,7 +445,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
}
@Override
public Children sort(boolean condition, List<SortBuilder<?>> sortBuilders) {
public Children sort(boolean condition, List<SortOptions> sortBuilders) {
if (CollectionUtils.isEmpty(sortBuilders)) {
return typedThis;
}
@ -597,20 +593,20 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
}
@Override
public Children setSearchSourceBuilder(boolean condition, SearchSourceBuilder searchSourceBuilder) {
public Children setSearchSourceBuilder(boolean condition, SearchRequest.Builder searchSourceBuilder) {
if (condition) {
this.searchSourceBuilder = searchSourceBuilder;
this.searchBuilder = searchSourceBuilder;
}
return typedThis;
}
@Override
public Children mix(boolean condition, QueryBuilder queryBuilder) {
public Children mix(boolean condition, co.elastic.clients.elasticsearch._types.query_dsl.Query.Builder queryBuilder) {
return addParam(condition, queryBuilder);
}
@Override
public Children bucketOrder(boolean condition, List<BucketOrder> bucketOrders) {
public Children bucketOrder(boolean condition, List<NamedValue<SortOrder>> bucketOrders) {
if (condition) {
this.bucketOrders = bucketOrders;
}
@ -637,7 +633,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
}
@Override
public Children minScore(Float score) {
public Children minScore(Double score) {
minScore = score;
return typedThis;
}
@ -676,7 +672,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
}
@Override
public Children maxResultWindow(Integer maxResultWindow) {
public Children maxResultWindow(Long maxResultWindow) {
Optional.ofNullable(maxResultWindow).ifPresent(max -> this.maxResultWindow = maxResultWindow);
return typedThis;
}
@ -693,19 +689,19 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
}
@Override
public Children settings(Settings settings) {
public Children settings(IndexSettings.Builder settings) {
this.settings = settings;
return typedThis;
}
@Override
public Children mapping(Map<String, Object> mapping) {
public Children mapping(TypeMapping.Builder mapping) {
this.mapping = mapping;
return typedThis;
}
@Override
public Children mapping(String column, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat, Boolean fieldData, Float boost) {
public Children mapping(String column, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat, Boolean fieldData, Double boost) {
addEsIndexParam(column, fieldType, analyzer, searchAnalyzer, dateFormat, fieldData, boost);
return typedThis;
}
@ -833,7 +829,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
* @param queryBuilder 原生查询参数
* @return wrapper
*/
private Children addParam(boolean condition, QueryBuilder queryBuilder) {
private Children addParam(boolean condition, co.elastic.clients.elasticsearch._types.query_dsl.Query.Builder queryBuilder) {
if (condition) {
Param param = new Param();
param.setQueryBuilder(queryBuilder);
@ -976,7 +972,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
* @param consumer 消费者
* @return wrapper
*/
private Children addNested(boolean condition, String path, ScoreMode scoreMode, Consumer<Children> consumer) {
private Children addNested(boolean condition, String path, ChildScoreMode scoreMode, Consumer<Children> consumer) {
if (condition) {
Param param = new Param();
param.setColumn(path);
@ -1019,7 +1015,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
* @param fieldData 是否将text类型字段添加fieldData,fieldData为true时,则text字段也支持聚合
* @param boost 权重
*/
private void addEsIndexParam(String fieldName, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat, Boolean fieldData, Float boost) {
private void addEsIndexParam(String fieldName, FieldType fieldType, String analyzer, String searchAnalyzer, String dateFormat, Boolean fieldData, Double boost) {
EsIndexParam esIndexParam = new EsIndexParam();
esIndexParam.setFieldName(fieldName);
esIndexParam.setFieldType(fieldType.getType());

View File

@ -1,19 +1,24 @@
package org.dromara.easyes.core.kernel;
import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch.core.ScrollRequest;
import co.elastic.clients.elasticsearch.core.ScrollResponse;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.indices.GetIndexResponse;
import co.elastic.clients.transport.TransportOptions;
import org.dromara.easyes.common.enums.MethodEnum;
import org.dromara.easyes.core.biz.EsPageInfo;
import org.dromara.easyes.core.biz.SAPageInfo;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.dromara.easyes.core.toolkit.EntityInfoHelper;
import java.io.IOException;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import static org.dromara.easyes.common.constants.BaseEsConstants.DSL_ENDPOINT;
/**
* 核心 所有支持方法接口
* <p>
@ -120,7 +125,9 @@ public interface BaseEsMapper<T> {
* @param dsl dsl语句
* @return 执行结果 jsonString
*/
String executeDSL(String dsl);
default String executeDSL(String dsl) {
return executeDSL(dsl, EntityInfoHelper.getEntityInfo(getEntityClass()).getIndexName());
}
/**
* 执行静态dsl语句 可指定作用的索引
@ -129,7 +136,19 @@ public interface BaseEsMapper<T> {
* @param indexName 作用的索引名
* @return 执行结果 jsonString
*/
String executeDSL(String dsl, String indexName);
default String executeDSL(String dsl, String indexName) {
return executeDSL(MethodEnum.GET.name(), indexName + DSL_ENDPOINT, dsl);
}
/**
* 执行静态dsl语句 可指定作用的索引
*
* @param method 方法名
* @param endpoint 端点
* @param dsl dsl语句
* @return 执行结果 jsonString
*/
String executeDSL(String method, String endpoint, String dsl);
/**
* 混合查询
@ -137,15 +156,15 @@ public interface BaseEsMapper<T> {
* @param wrapper 条件
* @return es标准结果
*/
SearchResponse search(Wrapper<T> wrapper);
SearchResponse<T> search(Wrapper<T> wrapper);
/**
* 获取SearchSourceBuilder,可用于本框架生成基础查询条件,不支持的高阶语法用户可通过SearchSourceBuilder 进一步封装
* 获取SearchSourceBuilder,可用于本框架生成基础查询条件,不支持的高阶语法用户可通过SearchRequest.Builder 进一步封装
*
* @param wrapper 条件
* @return 查询参数
*/
SearchSourceBuilder getSearchSourceBuilder(Wrapper<T> wrapper);
SearchRequest.Builder getSearchSourceBuilder(Wrapper<T> wrapper);
/**
* es原生查询
@ -155,7 +174,7 @@ public interface BaseEsMapper<T> {
* @return es原生返回结果
* @throws IOException IO异常
*/
SearchResponse search(SearchRequest searchRequest, RequestOptions requestOptions) throws IOException;
SearchResponse<T> search(SearchRequest searchRequest, TransportOptions requestOptions) throws IOException;
/**
* es原生滚动查询
@ -165,7 +184,7 @@ public interface BaseEsMapper<T> {
* @return es原生返回结果
* @throws IOException IO异常
*/
SearchResponse scroll(SearchScrollRequest searchScrollRequest, RequestOptions requestOptions) throws IOException;
ScrollResponse<T> scroll(ScrollRequest searchScrollRequest, TransportOptions requestOptions) throws IOException;
/**
* 获取通过本框架生成的查询参数,可用于检验本框架生成的查询参数是否正确
@ -193,7 +212,7 @@ public interface BaseEsMapper<T> {
* @param pageSize 每页条数
* @return 指定的返回类型
*/
SAPageInfo<T> searchAfterPage(Wrapper<T> wrapper, List<Object> searchAfter, Integer pageSize);
SAPageInfo<T> searchAfterPage(Wrapper<T> wrapper, List<FieldValue> searchAfter, Integer pageSize);
/**
* 获取总数(智能推断:若wrapper中指定了去重字段则去重,若未指定则不去重 推荐使用)
@ -586,10 +605,10 @@ public interface BaseEsMapper<T> {
Boolean setCurrentActiveIndex(String indexName);
/**
* 设置当前Mapper默认的RequestOptions,不设置则使用默认配置,务必谨慎操作,设置后全局生效,永驻jvm,除非项目重启
* 设置当前Mapper默认的TransportOptions,不设置则使用默认配置,务必谨慎操作,设置后全局生效,永驻jvm,除非项目重启
*
* @param requestOptions 请求配置
* @return 是否成功
*/
Boolean setRequestOptions(RequestOptions requestOptions);
Boolean setRequestOptions(TransportOptions requestOptions);
}

View File

@ -1,15 +1,15 @@
package org.dromara.easyes.core.kernel;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.indices.IndexSettings;
import co.elastic.clients.util.NamedValue;
import lombok.SneakyThrows;
import org.dromara.easyes.core.biz.*;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* Lambda表达式的祖宗类 存放孙子们所需的公用字段及参数
@ -40,7 +40,7 @@ public abstract class Wrapper<T> implements Cloneable {
/**
* 排除_score 小于 min_score 中指定的最小值的文档
*/
protected Float minScore;
protected Double minScore;
/**
* 自定义排序时( 脚本里面使用 _score)是否计算分数
*/
@ -78,11 +78,10 @@ public abstract class Wrapper<T> implements Cloneable {
* 聚合查询参数列表
*/
protected List<AggregationParam> aggregationParamList;
/**
* 聚合桶排序规则列表
* 最大返回数
*/
List<BucketOrder> bucketOrders;
protected Long maxResultWindow;
/**
* 排序参数列表
@ -106,26 +105,26 @@ public abstract class Wrapper<T> implements Cloneable {
* 副本数
*/
protected Integer replicasNum;
/**
* 最大返回数
*/
protected Integer maxResultWindow;
/**
* 用户手动指定的索引mapping信息,优先级最高
*/
protected Map<String, Object> mapping;
protected TypeMapping.Builder mapping;
/**
* 用户手动指定的索引settings,优先级最高
*/
protected Settings settings;
protected IndexSettings.Builder settings;
/**
* 用户自定义的searchSourceBuilder 用于混合查询
*/
protected SearchRequest.Builder searchBuilder;
/**
* 索引相关参数列表
*/
protected List<EsIndexParam> esIndexParamList;
/**
* 用户自定义的searchSourceBuilder 用于混合查询
* 聚合桶排序规则列表
*/
protected SearchSourceBuilder searchSourceBuilder;
List<NamedValue<SortOrder>> bucketOrders;
/**
* 浅拷贝当前条件构造器

View File

@ -1,8 +1,15 @@
package org.dromara.easyes.core.kernel;
import co.elastic.clients.elasticsearch._types.*;
import co.elastic.clients.elasticsearch._types.aggregations.Aggregation;
import co.elastic.clients.elasticsearch._types.query_dsl.*;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.search.Highlight;
import co.elastic.clients.elasticsearch.core.search.HighlightField;
import co.elastic.clients.json.JsonData;
import co.elastic.clients.util.NamedValue;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
import org.apache.lucene.search.join.ScoreMode;
import org.dromara.easyes.common.enums.AggregationTypeEnum;
import org.dromara.easyes.common.enums.EsQueryTypeEnum;
import org.dromara.easyes.common.utils.*;
@ -11,25 +18,7 @@ import org.dromara.easyes.core.cache.GlobalConfigCache;
import org.dromara.easyes.core.toolkit.EntityInfoHelper;
import org.dromara.easyes.core.toolkit.FieldUtils;
import org.dromara.easyes.core.toolkit.TreeBuilder;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.geometry.Geometry;
import org.elasticsearch.index.query.*;
import org.elasticsearch.join.query.HasChildQueryBuilder;
import org.elasticsearch.join.query.HasParentQueryBuilder;
import org.elasticsearch.join.query.ParentIdQueryBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.collapse.CollapseBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import java.time.ZoneId;
import java.util.*;
@ -54,15 +43,15 @@ public class WrapperProcessor {
* @param entityClass 实体类
* @return ES查询参数
*/
public static SearchSourceBuilder buildSearchSourceBuilder(Wrapper<?> wrapper, Class<?> entityClass) {
public static SearchRequest.Builder buildSearchSourceBuilder(Wrapper<?> wrapper, Class<?> entityClass) {
// 初始化boolQueryBuilder 参数
BoolQueryBuilder boolQueryBuilder = initBoolQueryBuilder(wrapper.paramQueue, entityClass);
BoolQuery.Builder boolQueryBuilder = initBoolQueryBuilder(wrapper.paramQueue, entityClass);
// 初始化searchSourceBuilder 参数
SearchSourceBuilder searchSourceBuilder = initSearchSourceBuilder(wrapper, entityClass);
SearchRequest.Builder searchSourceBuilder = initSearchSourceBuilder(wrapper, entityClass);
// 设置boolQuery参数
searchSourceBuilder.query(boolQueryBuilder);
searchSourceBuilder.query(x -> x.bool(boolQueryBuilder.build()));
return searchSourceBuilder;
}
@ -74,12 +63,12 @@ public class WrapperProcessor {
* @param entityClass 实体类
* @return BoolQueryBuilder
*/
public static BoolQueryBuilder initBoolQueryBuilder(List<Param> paramList, Class<?> entityClass) {
public static BoolQuery.Builder initBoolQueryBuilder(List<Param> paramList, Class<?> entityClass) {
// 建立参数森林无根树
List<Param> rootList = paramList.stream().filter(i -> Objects.isNull(i.getParentId())).collect(Collectors.toList());
TreeBuilder treeBuilder = new TreeBuilder(rootList, paramList);
List<Param> tree = (List<Param>) treeBuilder.build();
BoolQueryBuilder rootBool = QueryBuilders.boolQuery();
BoolQuery.Builder rootBool = QueryBuilders.bool();
// 对森林的每个根节点递归封装 这里看似简单实则很绕很烧脑 整个框架的核心 主要依托树的递归 深度优先遍历 森林 还原lambda条件构造语句
return getBool(tree, rootBool, EntityInfoHelper.getEntityInfo(entityClass), null);
@ -92,11 +81,10 @@ public class WrapperProcessor {
* @param param 查询参数
*/
@SneakyThrows
private static void initBool(BoolQueryBuilder bool, Param param, EntityInfo entityInfo,
private static void initBool(BoolQuery.Builder bool, Param param, EntityInfo entityInfo,
Map<String, String> mappingColumnMap, Map<String, String> fieldTypeMap) {
List<Param> children = (List<Param>) param.getChildren();
QueryBuilder queryBuilder;
RangeQueryBuilder rangeBuilder;
Query query;
String realField;
switch (param.getQueryTypeEnum()) {
case OR:
@ -105,160 +93,219 @@ public class WrapperProcessor {
// 渣男行为,*完就不认人了,因为拼接类型在AbstractWrapper中已处理过了 直接跳过
break;
case MIX:
setBool(bool, param.getQueryBuilder(), param.getPrevQueryType());
setBool(bool, param.getQueryBuilder().build(), param.getPrevQueryType());
break;
case TERM:
realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap);
queryBuilder = QueryBuilders.termQuery(realField, param.getVal()).boost(param.getBoost());
setBool(bool, queryBuilder, param.getPrevQueryType());
query = Query.of(q -> q.term(p ->
p.field(realField).value(fieldValue(param.getVal())).boost(param.getBoost())));
setBool(bool, query, param.getPrevQueryType());
break;
case MATCH:
realField = getRealField(param.getColumn(), mappingColumnMap);
queryBuilder = QueryBuilders.matchQuery(realField, param.getVal()).boost(param.getBoost());
setBool(bool, queryBuilder, param.getPrevQueryType());
query = Query.of(q -> q.match(p ->
p.field(realField).query(fieldValue(param.getVal())).boost(param.getBoost())));
setBool(bool, query, param.getPrevQueryType());
break;
case MATCH_PHRASE:
realField = getRealField(param.getColumn(), mappingColumnMap);
queryBuilder = QueryBuilders.matchPhraseQuery(realField, param.getVal()).boost(param.getBoost());
setBool(bool, queryBuilder, param.getPrevQueryType());
query = Query.of(q -> q.matchPhrase(p ->
p.field(realField).query((String) param.getVal()).boost(param.getBoost())));
setBool(bool, query, param.getPrevQueryType());
break;
case MATCH_PHRASE_PREFIX:
realField = getRealField(param.getColumn(), mappingColumnMap);
queryBuilder = QueryBuilders.matchPhrasePrefixQuery(realField, param.getVal()).boost(param.getBoost()).maxExpansions((int) param.getExt1());
setBool(bool, queryBuilder, param.getPrevQueryType());
query = Query.of(q -> q.matchPhrasePrefix(p ->
p.field(realField).query((String) param.getVal()).boost(param.getBoost()).maxExpansions((int) param.getExt1())));
setBool(bool, query, param.getPrevQueryType());
break;
case MULTI_MATCH:
String[] realFields = getRealFields(param.getColumns(), mappingColumnMap);
queryBuilder = QueryBuilders.multiMatchQuery(param.getVal(), realFields).operator((Operator) param.getExt1()).minimumShouldMatch(param.getExt2() + PERCENT_SIGN);
setBool(bool, queryBuilder, param.getPrevQueryType());
List<String> realFields = getRealFields(param.getColumns(), mappingColumnMap);
query = Query.of(q -> q.multiMatch(p -> p.query((String) param.getVal()).fields(realFields)
.operator((Operator) param.getExt1()).minimumShouldMatch(param.getExt2() + PERCENT_SIGN)));
setBool(bool, query, param.getPrevQueryType());
break;
case MATCH_ALL:
queryBuilder = QueryBuilders.matchAllQuery().boost(param.getBoost());
setBool(bool, queryBuilder, param.getPrevQueryType());
query = Query.of(q -> q.matchAll(p -> p.boost(param.getBoost())));
setBool(bool, query, param.getPrevQueryType());
break;
case QUERY_STRING:
queryBuilder = QueryBuilders.queryStringQuery(param.getColumn()).boost(param.getBoost());
setBool(bool, queryBuilder, param.getPrevQueryType());
query = Query.of(q -> q.queryString(p -> p.query(param.getColumn()).boost(param.getBoost())));
setBool(bool, query, param.getPrevQueryType());
break;
case PREFIX:
realField = getRealField(param.getColumn(), mappingColumnMap);
queryBuilder = QueryBuilders.prefixQuery(realField, (String) param.getVal()).boost(param.getBoost());
setBool(bool, queryBuilder, param.getPrevQueryType());
query = Query.of(q -> q.prefix(p -> p.field(realField).value((String) param.getVal()).boost(param.getBoost())));
setBool(bool, query, param.getPrevQueryType());
break;
case GT:
realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap);
rangeBuilder = QueryBuilders.rangeQuery(realField).gt(param.getVal()).boost(param.getBoost());
Optional.ofNullable(param.getExt1()).ifPresent(ext1 -> rangeBuilder.timeZone(((ZoneId) ext1).getId()));
Optional.ofNullable(param.getExt2()).ifPresent(ext2 -> rangeBuilder.format(ext2.toString()));
setBool(bool, rangeBuilder, param.getPrevQueryType());
query = Query.of(q -> q.range(p ->
p.untyped(v -> {
v.field(realField).gt(JsonData.of(param.getVal())).boost(param.getBoost());
Optional.ofNullable(param.getExt1()).ifPresent(ext1 -> v.timeZone(((ZoneId) ext1).getId()));
Optional.ofNullable(param.getExt2()).ifPresent(ext2 -> v.format(ext2.toString()));
return v;
})
));
setBool(bool, query, param.getPrevQueryType());
break;
case GE:
realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap);
rangeBuilder = QueryBuilders.rangeQuery(realField).gte(param.getVal()).boost(param.getBoost());
Optional.ofNullable(param.getExt1()).ifPresent(ext1 -> rangeBuilder.timeZone(((ZoneId) ext1).getId()));
Optional.ofNullable(param.getExt2()).ifPresent(ext2 -> rangeBuilder.format(ext2.toString()));
setBool(bool, rangeBuilder, param.getPrevQueryType());
query = Query.of(q -> q.range(p ->
p.untyped(v -> {
v.field(realField).gte(JsonData.of(param.getVal())).boost(param.getBoost());
Optional.ofNullable(param.getExt1()).ifPresent(ext1 -> v.timeZone(((ZoneId) ext1).getId()));
Optional.ofNullable(param.getExt2()).ifPresent(ext2 -> v.format(ext2.toString()));
return v;
})
));
setBool(bool, query, param.getPrevQueryType());
break;
case LT:
realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap);
rangeBuilder = QueryBuilders.rangeQuery(realField).lt(param.getVal()).boost(param.getBoost());
Optional.ofNullable(param.getExt1()).ifPresent(ext1 -> rangeBuilder.timeZone(((ZoneId) ext1).getId()));
Optional.ofNullable(param.getExt2()).ifPresent(ext2 -> rangeBuilder.format(ext2.toString()));
setBool(bool, rangeBuilder, param.getPrevQueryType());
query = Query.of(q -> q.range(p ->
p.untyped(v -> {
v.field(realField).lt(JsonData.of(param.getVal())).boost(param.getBoost());
Optional.ofNullable(param.getExt1()).ifPresent(ext1 -> v.timeZone(((ZoneId) ext1).getId()));
Optional.ofNullable(param.getExt2()).ifPresent(ext2 -> v.format(ext2.toString()));
return v;
})
));
setBool(bool, query, param.getPrevQueryType());
break;
case LE:
realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap);
rangeBuilder = QueryBuilders.rangeQuery(realField).lte(param.getVal()).boost(param.getBoost());
Optional.ofNullable(param.getExt1()).ifPresent(ext1 -> rangeBuilder.timeZone(((ZoneId) ext1).getId()));
Optional.ofNullable(param.getExt2()).ifPresent(ext2 -> rangeBuilder.format(ext2.toString()));
setBool(bool, rangeBuilder, param.getPrevQueryType());
query = Query.of(q -> q.range(p ->
p.untyped(v -> {
v.field(realField).lte(JsonData.of(param.getVal())).boost(param.getBoost());
Optional.ofNullable(param.getExt1()).ifPresent(ext1 -> v.timeZone(((ZoneId) ext1).getId()));
Optional.ofNullable(param.getExt2()).ifPresent(ext2 -> v.format(ext2.toString()));
return v;
})
));
setBool(bool, query, param.getPrevQueryType());
break;
case BETWEEN:
realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap);
rangeBuilder = QueryBuilders.rangeQuery(realField).gte(param.getExt1()).lte(param.getExt2()).boost(param.getBoost());
Optional.ofNullable(param.getExt3()).ifPresent(ext3 -> rangeBuilder.timeZone(((ZoneId) ext3).getId()));
Optional.ofNullable(param.getExt4()).ifPresent(ext4 -> rangeBuilder.format(ext4.toString()));
setBool(bool, rangeBuilder, param.getPrevQueryType());
query = Query.of(q -> q.range(p ->
p.untyped(v -> {
v.field(realField).gte(JsonData.of(param.getExt1())).lte(JsonData.of(param.getExt2())).boost(param.getBoost());
Optional.ofNullable(param.getExt1()).ifPresent(ext1 -> v.timeZone(((ZoneId) ext1).getId()));
Optional.ofNullable(param.getExt2()).ifPresent(ext2 -> v.format(ext2.toString()));
return v;
})
));
setBool(bool, query, param.getPrevQueryType());
break;
case WILDCARD:
realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap);
queryBuilder = QueryBuilders.wildcardQuery(realField, param.getVal().toString());
setBool(bool, queryBuilder, param.getPrevQueryType());
query = Query.of(q -> q.wildcard(p -> p.field(realField).value((String) param.getVal()).boost(param.getBoost())));
setBool(bool, query, param.getPrevQueryType());
break;
case TERMS:
realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap);
queryBuilder = QueryBuilders.termsQuery(realField, (Collection<?>) param.getVal());
setBool(bool, queryBuilder, param.getPrevQueryType());
List<FieldValue> fieldValueList = ((Collection<?>) param.getVal()).stream()
.map(WrapperProcessor::fieldValue).collect(Collectors.toList());
query = Query.of(q -> q.terms(p -> p.field(realField).terms(t -> t.value(fieldValueList))));
setBool(bool, query, param.getPrevQueryType());
break;
case EXISTS:
realField = getRealField(param.getColumn(), mappingColumnMap);
queryBuilder = QueryBuilders.existsQuery(realField).boost(param.getBoost());
setBool(bool, queryBuilder, param.getPrevQueryType());
query = Query.of(q -> q.exists(p -> p.field(realField).boost(param.getBoost())));
setBool(bool, query, param.getPrevQueryType());
break;
case GEO_BOUNDING_BOX:
realField = getRealField(param.getColumn(), mappingColumnMap);
queryBuilder = QueryBuilders.geoBoundingBoxQuery(realField).setCorners((GeoPoint) param.getExt1(), (GeoPoint) param.getExt2()).boost(param.getBoost());
setBool(bool, queryBuilder, param.getPrevQueryType());
query = Query.of(q -> q.geoBoundingBox(p -> p.field(realField)
.boundingBox(x -> x.tlbr(y -> y
.topLeft((GeoLocation) param.getExt1())
.bottomRight((GeoLocation) param.getExt2())
))
.boost(param.getBoost())));
setBool(bool, query, param.getPrevQueryType());
break;
case GEO_DISTANCE:
realField = getRealField(param.getColumn(), mappingColumnMap);
GeoDistanceQueryBuilder geoDistanceBuilder = QueryBuilders.geoDistanceQuery(realField).point((GeoPoint) param.getExt2()).boost(param.getBoost());
MyOptional.ofNullable(param.getExt1()).ifPresent(ext1 -> geoDistanceBuilder.distance((double) param.getVal(), (DistanceUnit) ext1), () -> geoDistanceBuilder.distance((String) param.getVal()));
queryBuilder = geoDistanceBuilder;
setBool(bool, queryBuilder, param.getPrevQueryType());
query = Query.of(q -> q.geoDistance(p -> {
p.field(realField).location(x -> x.latlon((LatLonGeoLocation) param.getExt2())).boost(param.getBoost());
String unit = param.getExt1() == null ? DistanceUnit.Meters.jsonValue() : ((DistanceUnit) param.getExt1()).jsonValue();
String val = (String) param.getVal();
String distance = val.endsWith(unit) ? val : val + unit;
p.distance(distance);
return p;
}));
setBool(bool, query, param.getPrevQueryType());
break;
case GEO_POLYGON:
realField = getRealField(param.getColumn(), mappingColumnMap);
queryBuilder = QueryBuilders.geoPolygonQuery(realField, (List<GeoPoint>) param.getVal());
setBool(bool, queryBuilder, param.getPrevQueryType());
query = Query.of(q -> q.geoPolygon(p -> p.field(realField).polygon(x ->
x.points((List<GeoLocation>) param.getExt2()))));
setBool(bool, query, param.getPrevQueryType());
break;
case GEO_SHAPE_ID:
realField = getRealField(param.getColumn(), mappingColumnMap);
queryBuilder = QueryBuilders.geoShapeQuery(realField, param.getVal().toString()).boost(param.getBoost());
setBool(bool, queryBuilder, param.getPrevQueryType());
query = Query.of(q -> q.geoShape(p -> p.field(realField).shape(x ->
x.indexedShape(y -> y.id((String) param.getVal())))));
setBool(bool, query, param.getPrevQueryType());
break;
case GEO_SHAPE:
realField = getRealField(param.getColumn(), mappingColumnMap);
queryBuilder = QueryBuilders.geoShapeQuery(realField, (Geometry) param.getVal()).relation((ShapeRelation) param.getExt1()).boost(param.getBoost());
setBool(bool, queryBuilder, param.getPrevQueryType());
query = Query.of(q -> q.geoShape(p -> p.field(realField).shape(x ->
x.shape(JsonData.of((Geometry)param.getVal())).relation((GeoShapeRelation) param.getExt1())
).boost(param.getBoost())
));
setBool(bool, query, param.getPrevQueryType());
break;
case PARENT_ID:
realField = getRealField(param.getColumn(), mappingColumnMap);
queryBuilder = new ParentIdQueryBuilder(realField, param.getVal().toString());
setBool(bool, queryBuilder, param.getPrevQueryType());
query = Query.of(q -> q.parentId(p -> p.type(realField).id((String) param.getVal())));
setBool(bool, query, param.getPrevQueryType());
break;
// 下面几种特殊嵌套类型 需要对孩子节点递归处理
case NESTED_AND:
case NESTED_FILTER:
case NESTED_NOT:
case NESTED_OR:
queryBuilder = getBool(children, QueryBuilders.boolQuery(), entityInfo, null);
setBool(bool, queryBuilder, param.getPrevQueryType());
query = Query.of(t -> t.bool(b -> getBool(children, b, entityInfo, null)));
setBool(bool, query, param.getPrevQueryType());
break;
case NESTED:
realField = getRealField(param.getColumn(), mappingColumnMap);
String[] split = param.getColumn().split(SIGN);
String path = split[split.length - 1];
queryBuilder = getBool(children, QueryBuilders.boolQuery(), entityInfo, path);
NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery(realField, queryBuilder, (ScoreMode) param.getVal());
query = Query.of(b -> b.bool( x -> getBool(children, x, entityInfo, path)));
NestedQuery.Builder nestedQueryBuilder = QueryBuilders.nested().path(realField).query(query).scoreMode((ChildScoreMode) param.getVal());
// 设置嵌套类型高亮查询参数
setNestedHighlight(path, param.getColumn(), nestedQueryBuilder, entityInfo);
// 设置bool查询参数
setBool(bool, nestedQueryBuilder, param.getPrevQueryType());
setBool(bool, Query.of(x -> x.nested(nestedQueryBuilder.build())), param.getPrevQueryType());
break;
case HAS_PARENT:
// 如果用户没指定type框架可根据entityInfo上下文自行推断出其父type
String column = Optional.ofNullable(param.getColumn()).orElse(entityInfo.getParentJoinAlias());
realField = getRealField(column, mappingColumnMap);
queryBuilder = getBool(children, QueryBuilders.boolQuery(), entityInfo, param.getColumn());
HasParentQueryBuilder hasParentQueryBuilder = new HasParentQueryBuilder(realField, queryBuilder, (boolean) param.getVal());
setBool(bool, hasParentQueryBuilder, param.getPrevQueryType());
query = Query.of(t -> t.bool(b -> getBool(children, b, entityInfo, param.getColumn())));
HasParentQuery.Builder hasParentQueryBuilder = new HasParentQuery.Builder()
.ignoreUnmapped(false)
.parentType(realField)
.query(query)
.score((boolean) param.getVal());
setBool(bool, Query.of(x -> x.hasParent(hasParentQueryBuilder.build())), param.getPrevQueryType());
break;
case HAS_CHILD:
realField = getRealField(param.getColumn(), mappingColumnMap);
queryBuilder = getBool(children, QueryBuilders.boolQuery(), entityInfo, param.getColumn());
HasChildQueryBuilder hasChildQueryBuilder = new HasChildQueryBuilder(realField, queryBuilder, (ScoreMode) param.getVal());
setBool(bool, hasChildQueryBuilder, param.getPrevQueryType());
query = Query.of(t -> t.bool(b -> getBool(children, b, entityInfo, param.getColumn())));
HasChildQuery.Builder hasChildQueryBuilder = new HasChildQuery.Builder()
.minChildren(1)
.maxChildren(Integer.MAX_VALUE)
.ignoreUnmapped(false)
.type(realField)
.query(query)
.minChildren(1)
.scoreMode((ChildScoreMode) param.getVal())
;
setBool(bool, Query.of(x -> x.hasChild(hasChildQueryBuilder.build())), param.getPrevQueryType());
break;
default:
// just ignore,almost never happen
@ -266,6 +313,26 @@ public class WrapperProcessor {
}
}
/**
* 获取FieldValue
*
* @param val 原字段值
* @return FieldValue
*/
public static FieldValue fieldValue(Object val) {
return switch (val) {
case null -> FieldValue.NULL;
case FieldValue fieldValue -> fieldValue;
case Long l -> FieldValue.of((long) val);
case Integer i -> FieldValue.of((int) val);
case Double v -> FieldValue.of((double) val);
case Boolean b -> FieldValue.of((boolean) val);
case String s -> FieldValue.of(s);
default -> FieldValue.of(val);
};
}
/**
* 设置嵌套类型高亮查询参数
*
@ -274,16 +341,16 @@ public class WrapperProcessor {
* @param nestedQueryBuilder 嵌套查询条件构造器
* @param entityInfo 实体信息缓存
*/
private static void setNestedHighlight(String path, String column, NestedQueryBuilder nestedQueryBuilder, EntityInfo entityInfo) {
private static void setNestedHighlight(String path, String column, NestedQuery.Builder nestedQueryBuilder, EntityInfo entityInfo) {
// 嵌套类型的高亮查询语句构造
Class<?> pathClass = entityInfo.getPathClassMap().get(path);
Optional.ofNullable(pathClass)
.flatMap(i -> Optional.ofNullable(entityInfo.getNestedHighLightParamsMap().get(i)))
.flatMap(i -> Optional.ofNullable(entityInfo.getNestedOrObjectHighLightParamsMap().get(i)))
.ifPresent(i -> {
// 嵌套类型高亮字段名需要完整的path 例如users.faqs 所以此处用param.column而非path
HighlightBuilder highlightBuilder = initHighlightBuilder(i, column);
Highlight.Builder highlightBuilder = initHighlightBuilder(i, column);
Optional.ofNullable(highlightBuilder)
.ifPresent(p -> nestedQueryBuilder.innerHit(new InnerHitBuilder().setHighlightBuilder(p)));
.ifPresent(p -> nestedQueryBuilder.innerHits(x -> x.highlight(p.build())));
});
}
@ -294,7 +361,7 @@ public class WrapperProcessor {
* @param queryBuilder 非根节点BoolQueryBuilder
* @param parentType 查询类型
*/
private static void setBool(BoolQueryBuilder bool, QueryBuilder queryBuilder, EsQueryTypeEnum parentType) {
private static void setBool(BoolQuery.Builder bool, Query queryBuilder, EsQueryTypeEnum parentType) {
if (NESTED_AND.equals(parentType)) {
bool.must(queryBuilder);
} else if (NESTED_OR.equals(parentType)) {
@ -318,7 +385,7 @@ public class WrapperProcessor {
* @param path 路径
* @return 子节点bool合集, 统一封装至入参builder中
*/
private static BoolQueryBuilder getBool(List<Param> paramList, BoolQueryBuilder builder, EntityInfo entityInfo, String path) {
private static BoolQuery.Builder getBool(List<Param> paramList, BoolQuery.Builder builder, EntityInfo entityInfo, String path) {
if (CollectionUtils.isEmpty(paramList)) {
return builder;
}
@ -329,9 +396,9 @@ public class WrapperProcessor {
if (StringUtils.isNotBlank(path)) {
// 嵌套类型
Class<?> clazz = entityInfo.getPathClassMap().get(path);
mappingColumnMap = Optional.ofNullable(entityInfo.getNestedClassMappingColumnMap().get(clazz))
mappingColumnMap = Optional.ofNullable(entityInfo.getNestedOrObjectClassMappingColumnMap().get(clazz))
.orElse(Collections.emptyMap());
fieldTypeMap = Optional.ofNullable(entityInfo.getNestedClassFieldTypeMap().get(clazz))
fieldTypeMap = Optional.ofNullable(entityInfo.getNestedOrObjectClassFieldTypeMap().get(clazz))
.orElse(Collections.emptyMap());
} else {
mappingColumnMap = entityInfo.getMappingColumnMap();
@ -350,42 +417,78 @@ public class WrapperProcessor {
* @param wrapper 条件
* @return SearchSourceBuilder
*/
private static SearchSourceBuilder initSearchSourceBuilder(Wrapper<?> wrapper, Class<?> entityClass) {
private static SearchRequest.Builder initSearchSourceBuilder(Wrapper<?> wrapper, Class<?> entityClass) {
EntityInfo entityInfo = EntityInfoHelper.getEntityInfo(entityClass);
// 获取自定义字段map
Map<String, String> mappingColumnMap = entityInfo.getMappingColumnMap();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchRequest.Builder builder = new SearchRequest.Builder();
builder.index(getIndexName(entityClass, wrapper.indexNames));
builder.routing(wrapper.routing);
builder.preference(wrapper.preference);
// 设置高亮
setHighLight(entityInfo.getHighlightParams(), searchSourceBuilder);
setHighLight(entityInfo.getHighlightParams(), builder);
// 设置用户指定的各种排序规则
setSort(wrapper, mappingColumnMap, searchSourceBuilder);
setSort(wrapper, mappingColumnMap, builder);
// 设置查询或不查询字段
setFetchSource(wrapper, mappingColumnMap, searchSourceBuilder);
setFetchSource(wrapper, mappingColumnMap, builder);
// 设置排除_score 小于 min_score 中指定的最小值的文档
Optional.ofNullable(wrapper.minScore).ifPresent(searchSourceBuilder::minScore);
Optional.ofNullable(wrapper.minScore).ifPresent(builder::minScore);
// 设置自定义排序时( 脚本里面使用 _score) 是否计算分数
Optional.ofNullable(wrapper.trackScores).ifPresent(searchSourceBuilder::trackScores);
Optional.ofNullable(wrapper.trackScores).ifPresent(builder::trackScores);
// 设置聚合参数
setAggregations(wrapper, mappingColumnMap, searchSourceBuilder);
setAggregations(wrapper, mappingColumnMap, builder);
// 设置查询起止参数
Optional.ofNullable(wrapper.from).ifPresent(searchSourceBuilder::from);
MyOptional.ofNullable(wrapper.size).ifPresent(searchSourceBuilder::size,
entityInfo.getMaxResultWindow() != null ? entityInfo.getMaxResultWindow() : DEFAULT_SIZE);
Optional.ofNullable(wrapper.from).ifPresent(builder::from);
MyOptional.ofNullable(wrapper.size).ifPresent(builder::size,
entityInfo.getMaxResultWindow() != null ? entityInfo.getMaxResultWindow().intValue() : DEFAULT_SIZE);
// 根据全局配置决定是否开启全部查询
if (GlobalConfigCache.getGlobalConfig().getDbConfig().isEnableTrackTotalHits()) {
searchSourceBuilder.trackTotalHits(Boolean.TRUE);
builder.trackTotalHits(x -> x.enabled(true));
}
return searchSourceBuilder;
return builder;
}
/**
* 获取兜底索引名称
*
* @return 索引名称
*/
public static <T> String getIndexName(Class<T> entityClass, String indexName) {
// 优先按wrapper中指定的索引名,若未指定则取当前全局激活的索引名
if (StringUtils.isBlank(indexName)) {
return EntityInfoHelper.getEntityInfo(entityClass).getIndexName();
}
return indexName;
}
/**
* 获取兜底索引名称数组
*
* @param indexNames 原始索引名称数组
* @return 目标索引名称数组
*/
public static <T> List<String> getIndexName(Class<T> entityClass, String[] indexNames) {
// 碰到傻狍子用户锤子索引都没指定, 给个兜底
if (ArrayUtils.isEmpty(indexNames)) {
return Collections.singletonList(EntityInfoHelper.getEntityInfo(entityClass).getIndexName());
}
// 指定了个空字符串之类的,需要给兜底
return Arrays.stream(indexNames)
.map(indexName -> getIndexName(entityClass, indexName))
.distinct()
.collect(Collectors.toList());
}
/**
@ -413,15 +516,15 @@ public class WrapperProcessor {
* @param mappingColumnMap 字段映射map
* @param searchSourceBuilder 查询参数建造者
*/
private static void setFetchSource(Wrapper<?> wrapper, Map<String, String> mappingColumnMap, SearchSourceBuilder searchSourceBuilder) {
private static void setFetchSource(Wrapper<?> wrapper, Map<String, String> mappingColumnMap, SearchRequest.Builder searchSourceBuilder) {
if (ArrayUtils.isEmpty(wrapper.include) && ArrayUtils.isEmpty(wrapper.exclude)) {
return;
}
// 获取实际字段
String[] includes = FieldUtils.getRealFields(wrapper.include, mappingColumnMap);
String[] excludes = FieldUtils.getRealFields(wrapper.exclude, mappingColumnMap);
searchSourceBuilder.fetchSource(includes, excludes);
List<String> includes = FieldUtils.getRealFields(wrapper.include, mappingColumnMap);
List<String> excludes = FieldUtils.getRealFields(wrapper.exclude, mappingColumnMap);
searchSourceBuilder.source(x -> x.filter(y -> y.includes(includes).excludes(excludes)));
}
@ -431,37 +534,36 @@ public class WrapperProcessor {
* @param highLightParams 高亮参数列表
* @param searchSourceBuilder 查询参数建造者
*/
private static void setHighLight(List<HighLightParam> highLightParams, SearchSourceBuilder searchSourceBuilder) {
private static void setHighLight(List<HighLightParam> highLightParams, SearchRequest.Builder searchSourceBuilder) {
if (CollectionUtils.isEmpty(highLightParams)) {
return;
}
// 初始化高亮参数
HighlightBuilder highlightBuilder = initHighlightBuilder(highLightParams, null);
Optional.ofNullable(highlightBuilder).ifPresent(searchSourceBuilder::highlighter);
Highlight.Builder highlightBuilder = initHighlightBuilder(highLightParams, null);
Optional.ofNullable(highlightBuilder).map(Highlight.Builder::build).ifPresent(searchSourceBuilder::highlight);
}
private static HighlightBuilder initHighlightBuilder(List<HighLightParam> highLightParams, String path) {
private static Highlight.Builder initHighlightBuilder(List<HighLightParam> highLightParams, String path) {
if (CollectionUtils.isEmpty(highLightParams)) {
return null;
}
// 封装高亮参数
HighlightBuilder highlightBuilder = new HighlightBuilder();
Highlight.Builder highlightBuilder = new Highlight.Builder();
highLightParams.forEach(highLightParam -> {
if (StringUtils.isNotBlank(highLightParam.getHighLightField())) {
// 嵌套类型 须追加其完整path前缀
String highlightField = Optional.ofNullable(path).map(i -> i + STR_SIGN + highLightParam.getHighLightField())
.orElse(highLightParam.getHighLightField());
HighlightBuilder.Field field = new HighlightBuilder.Field(highlightField)
HighlightField field = HighlightField.of(x -> x
.preTags(highLightParam.getPreTag())
.postTags(highLightParam.getPostTag());
field.highlighterType(highLightParam.getHighLightType().getValue());
if (Boolean.FALSE.equals(highLightParam.getRequireFieldMatch())) {
field.requireFieldMatch(highLightParam.getRequireFieldMatch());
}
highlightBuilder.field(field);
.postTags(highLightParam.getPostTag())
.type(highLightParam.getHighLightType().getValue())
.requireFieldMatch(highLightParam.getRequireFieldMatch())
);
highlightBuilder.fields(highlightField, field);
highlightBuilder.fragmentSize(highLightParam.getFragmentSize());
Optional.ofNullable(highLightParam.getNumberOfFragments()).ifPresent(highlightBuilder::numOfFragments);
Optional.ofNullable(highLightParam.getNumberOfFragments()).ifPresent(highlightBuilder::numberOfFragments);
}
});
return highlightBuilder;
@ -475,14 +577,14 @@ public class WrapperProcessor {
* @param mappingColumnMap 字段映射map
* @param searchSourceBuilder 查询参数建造者
*/
private static void setSort(Wrapper<?> wrapper, Map<String, String> mappingColumnMap, SearchSourceBuilder searchSourceBuilder) {
private static void setSort(Wrapper<?> wrapper, Map<String, String> mappingColumnMap, SearchRequest.Builder searchSourceBuilder) {
// 批量设置排序字段
if (CollectionUtils.isNotEmpty(wrapper.baseSortParams)) {
wrapper.baseSortParams.forEach(baseSortParam -> {
// 获取es中的实际字段 有可能已经被用户自定义或者驼峰转成下划线
String realField = Objects.isNull(baseSortParam.getSortField()) ?
null : getRealField(baseSortParam.getSortField(), mappingColumnMap);
SortBuilder<?> sortBuilder = getSortBuilder(realField, baseSortParam);
SortOptions sortBuilder = getSortBuilder(realField, baseSortParam);
Optional.ofNullable(sortBuilder).ifPresent(searchSourceBuilder::sort);
});
}
@ -491,16 +593,16 @@ public class WrapperProcessor {
if (CollectionUtils.isNotEmpty(wrapper.orderByParams)) {
wrapper.orderByParams.forEach(orderByParam -> {
// 设置排序字段
FieldSortBuilder fieldSortBuilder = new FieldSortBuilder(orderByParam.getOrder());
FieldSort.Builder fieldSortBuilder = new FieldSort.Builder().field(orderByParam.getOrder());
// 设置排序规则
if (SortOrder.ASC.toString().equalsIgnoreCase(orderByParam.getSort())) {
fieldSortBuilder.order(SortOrder.ASC);
if (SortOrder.Asc.toString().equalsIgnoreCase(orderByParam.getSort())) {
fieldSortBuilder.order(SortOrder.Asc);
}
if (SortOrder.DESC.toString().equalsIgnoreCase(orderByParam.getSort())) {
fieldSortBuilder.order(SortOrder.DESC);
if (SortOrder.Desc.toString().equalsIgnoreCase(orderByParam.getSort())) {
fieldSortBuilder.order(SortOrder.Desc);
}
searchSourceBuilder.sort(fieldSortBuilder);
searchSourceBuilder.sort(x -> x.field(fieldSortBuilder.build()));
});
}
}
@ -513,17 +615,20 @@ public class WrapperProcessor {
* @param baseSortParam 排序参数
* @return 排序器
*/
private static SortBuilder<?> getSortBuilder(String realField, BaseSortParam baseSortParam) {
private static SortOptions getSortBuilder(String realField, BaseSortParam baseSortParam) {
switch (baseSortParam.getOrderTypeEnum()) {
case FIELD:
return SortBuilders.fieldSort(realField).order(baseSortParam.getSortOrder());
return SortOptions.of(x -> x.field(y -> y.field(realField).order(baseSortParam.getSortOrder())));
case SCORE:
return SortBuilders.scoreSort().order(baseSortParam.getSortOrder());
return SortOptions.of(x -> x.score(y -> y.order(baseSortParam.getSortOrder())));
case GEO:
return SortBuilders.geoDistanceSort(realField, baseSortParam.getGeoPoints())
return SortOptions.of(x -> x.geoDistance(y -> y
.field(realField)
.location(baseSortParam.getGeoPoints())
.order(baseSortParam.getSortOrder())
.geoDistance(baseSortParam.getGeoDistance())
.unit(baseSortParam.getUnit());
.distanceType(baseSortParam.getGeoDistance())
.unit(baseSortParam.getUnit())
));
case CUSTOMIZE:
return baseSortParam.getSortBuilder();
default:
@ -540,13 +645,13 @@ public class WrapperProcessor {
* @param searchSourceBuilder 查询参数建造者
*/
private static void setAggregations(Wrapper<?> wrapper, Map<String, String> mappingColumnMap,
SearchSourceBuilder searchSourceBuilder) {
SearchRequest.Builder searchSourceBuilder) {
// 设置折叠(去重)字段
Optional.ofNullable(wrapper.distinctField)
.ifPresent(distinctField -> {
String realField = getRealField(distinctField, mappingColumnMap);
searchSourceBuilder.collapse(new CollapseBuilder(realField));
searchSourceBuilder.aggregation(AggregationBuilders.cardinality(REPEAT_NUM_KEY).field(realField));
searchSourceBuilder.collapse(x -> x.field(realField));
searchSourceBuilder.aggregations(REPEAT_NUM_KEY, x -> x.cardinality(y -> y.field(realField)));
});
// 其它聚合
@ -556,30 +661,38 @@ public class WrapperProcessor {
}
// 构建聚合树
AggregationBuilder root = null;
AggregationBuilder cursor = null;
String rootName = null;
Aggregation.Builder.ContainerBuilder root = null;
Aggregation.Builder.ContainerBuilder cursor = null;
for (AggregationParam aggParam : aggregationParamList) {
String realField = getRealField(aggParam.getField(), mappingColumnMap);
AggregationBuilder builder = getRealAggregationBuilder(aggParam.getAggregationType(), aggParam.getName(), realField, wrapper.size, wrapper.bucketOrders);
Aggregation.Builder.ContainerBuilder builder = getRealAggregationBuilder(aggParam.getAggregationType()
, aggParam.getName(), realField, wrapper.size, wrapper.bucketOrders);
if (aggParam.isEnablePipeline()) {
// 管道聚合, 构造聚合树
if (root == null) {
root = builder;
rootName = aggParam.getName();
cursor = root;
} else {
cursor.subAggregation(builder);
Aggregation agg = builder.build();
cursor.aggregations(aggParam.getName(), agg);
// 解决maxminavg和sum聚合函数不支持sub-aggregations的问题
if (builder instanceof TermsAggregationBuilder) {
if (agg._kind().equals(Aggregation.Kind.Terms)) {
cursor = builder;
}
}
} else {
// 非管道聚合
searchSourceBuilder.aggregation(builder);
if (builder != null) {
searchSourceBuilder.aggregations(aggParam.getName(), builder.build());
}
}
}
Optional.ofNullable(root).ifPresent(searchSourceBuilder::aggregation);
if (root != null) {
searchSourceBuilder.aggregations(rootName, root.build());
}
if (!GlobalConfigCache.getGlobalConfig().getDbConfig().isEnableAggHits()) {
// 配置关闭了聚合返回结果集Hits, 可提升查询效率
@ -596,32 +709,33 @@ public class WrapperProcessor {
* @param size 聚合桶大小
* @return 聚合建造者
*/
private static AggregationBuilder getRealAggregationBuilder(AggregationTypeEnum aggType, String name, String realField, Integer size, List<BucketOrder> bucketOrders) {
AggregationBuilder aggregationBuilder;
private static Aggregation.Builder.ContainerBuilder getRealAggregationBuilder(
AggregationTypeEnum aggType,
String name,
String realField,
Integer size,
List<NamedValue<SortOrder>> bucketOrders
) {
// 解决同一个字段聚合多次如min(starNum), max(starNum) 字段名重复问题
name += aggType.getValue();
String finalName = name + aggType.getValue();
switch (aggType) {
case AVG:
aggregationBuilder = AggregationBuilders.avg(name).field(realField);
break;
return new Aggregation.Builder().avg(x -> x.field(realField));
case MIN:
aggregationBuilder = AggregationBuilders.min(name).field(realField);
break;
return new Aggregation.Builder().min(x -> x.field(finalName));
case MAX:
aggregationBuilder = AggregationBuilders.max(name).field(realField);
break;
return new Aggregation.Builder().max(x -> x.field(realField));
case SUM:
aggregationBuilder = AggregationBuilders.sum(name).field(realField);
break;
return new Aggregation.Builder().sum(x -> x.field(realField));
case TERMS:
TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms(name).field(realField);
Optional.ofNullable(size).ifPresent(termsAggregationBuilder::size);
Optional.ofNullable(bucketOrders).ifPresent(termsAggregationBuilder::order);
aggregationBuilder = termsAggregationBuilder;
break;
return new Aggregation.Builder().terms(x -> {
x.field(realField);
Optional.ofNullable(size).ifPresent(x::size);
Optional.ofNullable(bucketOrders).ifPresent(x::order);
return x;
});
default:
throw new UnsupportedOperationException("不支持的聚合类型,参见AggregationTypeEnum");
}
return aggregationBuilder;
}
}

View File

@ -1,9 +1,7 @@
package org.dromara.easyes.core.toolkit;
import com.alibaba.fastjson.parser.deserializer.ExtraProcessor;
import com.alibaba.fastjson.serializer.NameFilter;
import co.elastic.clients.elasticsearch.indices.IndexSettings;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
import com.alibaba.fastjson.serializer.ValueFilter;
import lombok.SneakyThrows;
import org.dromara.easyes.annotation.*;
@ -13,15 +11,12 @@ import org.dromara.easyes.common.utils.*;
import org.dromara.easyes.core.biz.EntityFieldInfo;
import org.dromara.easyes.core.biz.EntityInfo;
import org.dromara.easyes.core.biz.HighLightParam;
import org.dromara.easyes.core.cache.BaseCache;
import org.dromara.easyes.core.cache.GlobalConfigCache;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@ -43,8 +38,7 @@ public class EntityInfoHelper {
/**
* 储存反射类表信息
*/
private static final Map<Class<?>, EntityInfo> ENTITY_INFO_CACHE = new ConcurrentHashMap<>();
public static final Map<Class<?>, EntityInfo> ENTITY_INFO_CACHE = new ConcurrentHashMap<>();
/**
* 获取实体映射表信息
@ -119,12 +113,13 @@ public class EntityInfoHelper {
boolean camelCase = globalConfig.getDbConfig().isMapUnderscoreToCamelCase();
String joinFieldName = camelToUnderline(JoinField.class.getSimpleName(), camelCase);
entityInfo.setJoinFieldName(joinFieldName);
String joinAlias = StringUtils.isBlank(join.rootAlias()) ? clazz.getSimpleName() : join.rootAlias();
String joinAlias = StringUtils.isBlank(join.rootAlias()) ? clazz.getSimpleName().toLowerCase() : join.rootAlias();
String underlineJoinAlias = camelToUnderline(joinAlias, camelCase);
entityInfo.setJoinAlias(underlineJoinAlias);
entityInfo.setEagerGlobalOrdinals(join.eagerGlobalOrdinals());
Map<String, Object> relationMap = entityInfo.getRelationMap();
Map<String, List<String>> relationMap = entityInfo.getRelationMap();
Map<Class<?>, List<Class<?>>> relationClassMap = entityInfo.getRelationClassMap();
Arrays.stream(join.nodes())
.forEach(child -> {
String parentAlias = StringUtils.isBlank(child.parentAlias()) ? child.parentClass().getSimpleName().toLowerCase() : child.parentAlias();
@ -133,8 +128,8 @@ public class EntityInfoHelper {
Arrays.stream(child.childClasses()).map(Class::getSimpleName).map(i -> camelToUnderline(i.toLowerCase(), camelCase)).distinct().collect(Collectors.toList()) :
Arrays.stream(child.childAliases()).map(i -> camelToUnderline(i, camelCase)).collect(Collectors.toList());
// 大于1以数组形式置入,只有1个元素,则以object置入 否则会导致平滑模式下,从es中查询到的索引mapping与根据注解构造出的mapping结构有差异,被误判索引发生变动
Object relation = childAliases.size() > ONE ? childAliases : childAliases.get(ZERO);
relationMap.put(underlineParentAlias, relation);
relationMap.put(underlineParentAlias, childAliases);
relationClassMap.put(child.parentClass(), Arrays.asList(child.childClasses()));
// 在join-父加载时预加载join-子信息
AtomicInteger index = new AtomicInteger(ZERO);
@ -198,43 +193,6 @@ public class EntityInfoHelper {
// 字段列表
entityInfo.setFieldList(fieldList);
// 添加fastjson 前置过滤器
addSimplePropertyPreFilter(entityInfo, clazz);
// 添加fastjson ExtraProcessor
addExtraProcessor(entityInfo);
}
/**
* 添加fastjson前置过滤器
*
* @param entityInfo 实体信息
* @param clazz 实体类
*/
private static void addSimplePropertyPreFilter(EntityInfo entityInfo, Class<?> clazz) {
// 字段是否序列化过滤 针对notExists字段及高亮字段等
List<SerializeFilter> preFilters = new ArrayList<>();
SimplePropertyPreFilter entityClassPreFilter =
FastJsonUtils.getSimplePropertyPreFilter(clazz, entityInfo.getNotSerializeField());
Optional.ofNullable(entityClassPreFilter).ifPresent(preFilters::add);
// 日期等特殊字段过滤器
List<SerializeFilter> valueFilters = getValueFilter(entityInfo, clazz);
preFilters.addAll(valueFilters);
// 嵌套类的字段序列化过滤器
entityInfo.getNestedNotSerializeField()
.forEach((k, v) -> Optional.ofNullable(FastJsonUtils.getSimplePropertyPreFilter(k, v))
.ifPresent(preFilters::add));
// 添加fastjson NameFilter 针对驼峰以及下划线转换
addNameFilter(entityInfo, preFilters);
entityInfo.getClassSimplePropertyPreFilterMap().putIfAbsent(clazz, preFilters);
// 置空闲置容器,节省少量内存
entityInfo.getNotSerializeField().clear();
entityInfo.getNestedNotSerializeField().clear();
}
/**
@ -252,7 +210,7 @@ public class EntityInfoHelper {
return serializeFilters;
}
Map<Class<?>, Map<String, String>> nestedClassColumnMappingMap = entityInfo.getNestedClassColumnMappingMap();
Map<Class<?>, Map<String, String>> nestedClassColumnMappingMap = entityInfo.getNestedOrObjectClassColumnMappingMap();
SerializeFilter serializeFilter = (ValueFilter) (object, name, value) -> {
Map<String, String> nestedColumnMappingMap = nestedClassColumnMappingMap.get(object.getClass());
if (nestedColumnMappingMap != null) {
@ -269,108 +227,6 @@ public class EntityInfoHelper {
return serializeFilters;
}
/**
* 预添加fastjson解析object时对非实体类字段的处理(比如自定义字段名,下划线等)
*
* @param entityInfo 实体信息
*/
private static void addExtraProcessor(EntityInfo entityInfo) {
Map<String, String> columnMappingMap = entityInfo.getColumnMappingMap();
Map<Class<?>, Map<String, String>> nestedClassColumnMappingMap = entityInfo.getNestedClassColumnMappingMap();
ExtraProcessor extraProcessor = (object, key, value) -> {
Map<String, String> nestedColumnMappingMap = nestedClassColumnMappingMap.get(object.getClass());
if (nestedColumnMappingMap != null) {
// 嵌套类
invokeExtraProcessor(nestedColumnMappingMap, object, key, value, object.getClass());
} else {
// 主类
invokeExtraProcessor(columnMappingMap, object, key, value, object.getClass());
}
};
entityInfo.setExtraProcessor(extraProcessor);
}
/**
* fastjson字段转换 (由es中查询结果映射至对象)
*
* @param columnMappingMap 字段映射
* @param object 对象
* @param key 字段名
* @param value 字段值
* @param clazz 实体类
*/
private static void invokeExtraProcessor(Map<String, String> columnMappingMap, Object object, String key, Object value, Class<?> clazz) {
Optional.ofNullable(columnMappingMap.get(key))
.flatMap(realMethodName -> Optional.ofNullable(BaseCache.setterMethod(clazz, realMethodName)))
.ifPresent(method -> {
try {
method.invoke(object, value);
} catch (IllegalArgumentException illegalArgumentException) {
illegalArgumentException.printStackTrace();
// 日期类型失败按默认format格式重试 几乎不会走到这里,除非用户针对日期字段设置了别名
reInvokeDate(object, value, method);
} catch (Throwable e) {
e.printStackTrace();
}
});
}
/**
* 日期类型重新反射
*
* @param object 对象
* @param value
* @param method 方法名
*/
private static void reInvokeDate(Object object, Object value, Method method) {
if (value instanceof String) {
String paramTypeName = method.getParameterTypes()[0].getSimpleName();
Object parsed = null;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT);
if (LocalDateTime.class.getSimpleName().equals(paramTypeName)) {
parsed = LocalDateTime.parse(value.toString(), formatter);
} else if (LocalDate.class.getSimpleName().equals(paramTypeName)) {
parsed = LocalDate.parse(value.toString(), formatter);
} else if (Date.class.getSimpleName().equals(paramTypeName)) {
parsed = Date.from(LocalDateTime.parse(value.toString(), formatter).atZone(ZoneId.systemDefault()).toInstant());
}
try {
method.invoke(object, parsed);
} catch (Throwable e) {
e.printStackTrace();
}
}
}
/**
* 添加fastjson字段过滤器
*
* @param entityInfo 实体信息
*/
private static void addNameFilter(EntityInfo entityInfo, List<SerializeFilter> preFilters) {
Map<String, String> mappingColumnMap = entityInfo.getMappingColumnMap();
Map<Class<?>, Map<String, String>> nestedClassMappingColumnMap = entityInfo.getNestedClassMappingColumnMap();
if (!mappingColumnMap.isEmpty()) {
NameFilter nameFilter = (object, name, value) -> {
Map<String, String> nestedMappingColumnMap = nestedClassMappingColumnMap.get(object.getClass());
if (Objects.nonNull(nestedMappingColumnMap)) {
String nestedMappingColumn = nestedMappingColumnMap.get(name);
if (Objects.equals(nestedMappingColumn, name)) {
return name;
} else {
return nestedMappingColumn;
}
}
String mappingColumn = mappingColumnMap.get(name);
if (Objects.equals(mappingColumn, name)) {
return name;
}
return mappingColumn;
};
preFilters.add(nameFilter);
}
}
/**
* 字段属性初始化
*
@ -378,7 +234,6 @@ public class EntityInfoHelper {
* @param fieldList 字段列表
* @param field 字段
* @param entityInfo 实体信息
* @return
*/
private static boolean initIndexFieldWithAnnotation(GlobalConfig.DbConfig dbConfig, List<EntityFieldInfo> fieldList,
Field field, EntityInfo entityInfo, Class<?> clazz) {
@ -472,13 +327,13 @@ public class EntityInfoHelper {
}
// 复制字段
if (ArrayUtils.isNotEmpty(indexField.copyTo())){
if (ArrayUtils.isNotEmpty(indexField.copyTo())) {
List<String> collect;
if (dbConfig.isMapUnderscoreToCamelCase()){
if (dbConfig.isMapUnderscoreToCamelCase()) {
collect = Arrays.stream(indexField.copyTo())
.map(StringUtils::camelToUnderline)
.collect(Collectors.toList());
}else {
} else {
collect = Arrays.stream(indexField.copyTo())
.collect(Collectors.toList());
}
@ -501,10 +356,10 @@ public class EntityInfoHelper {
fieldList.add(entityFieldInfo);
// 嵌套类处理
if (DefaultNestedClass.class != indexField.nestedClass()) {
if (DefaultNestedOrObjectClass.class != indexField.nestedOrObjectClass()) {
// 嵌套类
entityInfo.getPathClassMap().putIfAbsent(field.getName(), indexField.nestedClass());
processNested(indexField.nestedClass(), dbConfig, entityInfo);
entityInfo.getPathClassMap().putIfAbsent(field.getName(), indexField.nestedOrObjectClass());
processNestedOrObject(indexField.nestedOrObjectClass(), dbConfig, entityInfo);
}
} else {
@ -519,10 +374,10 @@ public class EntityInfoHelper {
* @param entityInfo 实体信息
* @param field 字段
* @param mappingColumnMap 实体字段与es字段映射关系
* @param nestedClass 嵌套类
* @param nestedOrObjectClass 嵌套类
*/
private static void initHighLightAnnotation(GlobalConfig.DbConfig dbConfig, EntityInfo entityInfo, Field field,
Map<String, String> mappingColumnMap, Class<?> nestedClass) {
Map<String, String> mappingColumnMap, Class<?> nestedOrObjectClass) {
HighLight highLight = field.getAnnotation(HighLight.class);
String mappingField = highLight.mappingField();
@ -536,14 +391,14 @@ public class EntityInfoHelper {
}
if (!skip) {
// 添加无需序列化字段至缓存
if (nestedClass == null) {
if (nestedOrObjectClass == null) {
entityInfo.getNotSerializeField().add(mappingField);
} else {
// 嵌套类型
Set<String> nestedNotSerializeFieldSet = Optional.ofNullable(entityInfo.getNestedNotSerializeField().get(nestedClass))
Set<String> nestedNotSerializeFieldSet = Optional.ofNullable(entityInfo.getNestedOrObjectNotSerializeField().get(nestedOrObjectClass))
.orElse(new HashSet<>());
nestedNotSerializeFieldSet.add(mappingField);
entityInfo.getNestedNotSerializeField().put(nestedClass, nestedNotSerializeFieldSet);
entityInfo.getNestedOrObjectNotSerializeField().put(nestedOrObjectClass, nestedNotSerializeFieldSet);
}
}
@ -553,12 +408,12 @@ public class EntityInfoHelper {
if (dbConfig.isMapUnderscoreToCamelCase()) {
realHighLightField = StringUtils.camelToUnderline(realHighLightField);
}
addHighlightParam(entityInfo, nestedClass, highLight, realHighLightField, mappingField);
addHighlightParam(entityInfo, nestedOrObjectClass, highLight, realHighLightField, mappingField);
MultiIndexField multiIndexField = field.getAnnotation(MultiIndexField.class);
if (multiIndexField != null) {
for (InnerIndexField innerIndexField : multiIndexField.otherIndexFields()) {
addHighlightParam(entityInfo, nestedClass, highLight,
addHighlightParam(entityInfo, nestedOrObjectClass, highLight,
realHighLightField + STR_SIGN + innerIndexField.suffix(), mappingField);
}
}
@ -568,20 +423,20 @@ public class EntityInfoHelper {
* 添加高亮参数
*
* @param entityInfo 实体信息
* @param nestedClass 嵌套类
* @param nestedOrObjectClass 嵌套类
* @param highLight 高亮注解
* @param realHighLightField 实际高亮字段
* @param mappingField 映射字段
*/
private static void addHighlightParam(EntityInfo entityInfo, Class<?> nestedClass, HighLight highLight,
private static void addHighlightParam(EntityInfo entityInfo, Class<?> nestedOrObjectClass, HighLight highLight,
String realHighLightField, String mappingField) {
if (nestedClass == null) {
if (nestedOrObjectClass == null) {
entityInfo.getHighlightFieldMap().putIfAbsent(realHighLightField, mappingField);
} else {
Map<String, String> nestedHighlightFieldMap = Optional.ofNullable(entityInfo.getNestedHighlightFieldMap().get(nestedClass))
Map<String, String> nestedHighlightFieldMap = Optional.ofNullable(entityInfo.getNestedOrObjectHighlightFieldMap().get(nestedOrObjectClass))
.orElse(new HashMap<>());
nestedHighlightFieldMap.putIfAbsent(realHighLightField, mappingField);
entityInfo.getNestedHighlightFieldMap().put(nestedClass, nestedHighlightFieldMap);
entityInfo.getNestedOrObjectHighlightFieldMap().put(nestedOrObjectClass, nestedHighlightFieldMap);
}
// 置入高亮查询参数缓存
@ -595,26 +450,26 @@ public class EntityInfoHelper {
if (MINUS_ONE != highLight.numberOfFragments() && highLight.numberOfFragments() > ZERO) {
highlightParam.setNumberOfFragments(highLight.numberOfFragments());
}
if (nestedClass == null) {
if (nestedOrObjectClass == null) {
entityInfo.getHighlightParams().add(highlightParam);
} else {
List<HighLightParam> nestedHighlightParams = Optional.ofNullable(entityInfo.getNestedHighLightParamsMap().get(nestedClass))
List<HighLightParam> nestedHighlightParams = Optional.ofNullable(entityInfo.getNestedOrObjectHighLightParamsMap().get(nestedOrObjectClass))
.orElse(new ArrayList<>());
nestedHighlightParams.add(highlightParam);
entityInfo.getNestedHighLightParamsMap().put(nestedClass, nestedHighlightParams);
entityInfo.getNestedOrObjectHighLightParamsMap().put(nestedOrObjectClass, nestedHighlightParams);
}
}
/**
* 处理嵌套类中的字段配置
*
* @param nestedClass 嵌套类
* @param nestedOrObjectClass 嵌套类
* @param dbConfig 全局配置
* @param entityInfo 实体信息
*/
private static void processNested(Class<?> nestedClass, GlobalConfig.DbConfig dbConfig, EntityInfo entityInfo) {
private static void processNestedOrObject(Class<?> nestedOrObjectClass, GlobalConfig.DbConfig dbConfig, EntityInfo entityInfo) {
// 将字段映射置入map 对其子节点也执行同样的操作
List<Field> allFields = getAllFields(nestedClass);
List<Field> allFields = getAllFields(nestedOrObjectClass);
Map<String, String> mappingColumnMap = new HashMap<>(allFields.size());
Map<String, String> columnMappingMap = new HashMap<>(allFields.size());
Map<String, String> fieldTypeMap = new HashMap<>();
@ -627,7 +482,7 @@ public class EntityInfoHelper {
// 初始化封装嵌套类中的HighLight注解信息
if (field.isAnnotationPresent(HighLight.class)) {
initHighLightAnnotation(dbConfig, entityInfo, field, mappingColumnMap, nestedClass);
initHighLightAnnotation(dbConfig, entityInfo, field, mappingColumnMap, nestedOrObjectClass);
}
// 处理TableField注解
@ -636,7 +491,7 @@ public class EntityInfoHelper {
.orElse(field.getAnnotation(IndexField.class));
if (Objects.isNull(indexField)) {
// 跳过无关字段
Set<String> notSerializeFields = Optional.ofNullable(entityInfo.getNestedNotSerializeField().get(nestedClass)).orElse(Collections.emptySet());
Set<String> notSerializeFields = Optional.ofNullable(entityInfo.getNestedOrObjectNotSerializeField().get(nestedOrObjectClass)).orElse(Collections.emptySet());
if (notSerializeFields.contains(field.getName())) {
return;
}
@ -649,15 +504,15 @@ public class EntityInfoHelper {
entityFieldInfo.setColumnType(field.getType().getSimpleName());
// 日期类型,如果没加注解, 设置默认的日期format
initClassDateFormatMap(fieldType, field.getName(), entityInfo, nestedClass, DEFAULT_DATE_TIME_FORMAT);
initClassDateFormatMap(fieldType, field.getName(), entityInfo, nestedOrObjectClass, DEFAULT_DATE_TIME_FORMAT);
entityFieldInfoList.add(entityFieldInfo);
} else {
if (indexField.exist()) {
// 子嵌套,递归处理
if (DefaultNestedClass.class != indexField.nestedClass()) {
entityInfo.getPathClassMap().putIfAbsent(field.getName(), indexField.nestedClass());
processNested(indexField.nestedClass(), dbConfig, entityInfo);
if (DefaultNestedOrObjectClass.class != indexField.nestedOrObjectClass()) {
entityInfo.getPathClassMap().putIfAbsent(field.getName(), indexField.nestedOrObjectClass());
processNestedOrObject(indexField.nestedOrObjectClass(), dbConfig, entityInfo);
}
// 字段名称
@ -683,7 +538,7 @@ public class EntityInfoHelper {
// 日期格式化信息初始化
String format = StringUtils.isBlank(indexField.dateFormat()) ? DEFAULT_DATE_TIME_FORMAT : indexField.dateFormat();
initClassDateFormatMap(indexField.fieldType(), field.getName(), entityInfo, nestedClass, format);
initClassDateFormatMap(indexField.fieldType(), field.getName(), entityInfo, nestedOrObjectClass, format);
// 缩放因子
if (MINUS_ONE != indexField.scalingFactor()) {
@ -712,11 +567,11 @@ public class EntityInfoHelper {
});
entityInfo.getNestedNotSerializeField().putIfAbsent(nestedClass, notSerializedFields);
entityInfo.getNestedClassColumnMappingMap().putIfAbsent(nestedClass, columnMappingMap);
entityInfo.getNestedClassMappingColumnMap().putIfAbsent(nestedClass, mappingColumnMap);
entityInfo.getNestedClassFieldTypeMap().putIfAbsent(nestedClass, fieldTypeMap);
entityInfo.getNestedFieldListMap().put(nestedClass, entityFieldInfoList);
entityInfo.getNestedOrObjectNotSerializeField().putIfAbsent(nestedOrObjectClass, notSerializedFields);
entityInfo.getNestedOrObjectClassColumnMappingMap().putIfAbsent(nestedOrObjectClass, columnMappingMap);
entityInfo.getNestedOrObjectClassMappingColumnMap().putIfAbsent(nestedOrObjectClass, mappingColumnMap);
entityInfo.getNestedOrObjectClassFieldTypeMap().putIfAbsent(nestedOrObjectClass, fieldTypeMap);
entityInfo.getNestedOrObjectFieldListMap().put(nestedOrObjectClass, entityFieldInfoList);
}
/**
@ -923,24 +778,19 @@ public class EntityInfoHelper {
@SneakyThrows
private static void initSettings(Class<?> clazz, EntityInfo entityInfo) {
Settings settings = clazz.getAnnotation(Settings.class);
Optional.ofNullable(settings).ifPresent(i -> {
entityInfo.getSettingsMap().put(REPLICAS_FIELD, i.replicasNum());
entityInfo.getSettingsMap().put(SHARDS_FIELD, i.shardsNum());
entityInfo.getSettingsMap().put(MAX_RESULT_WINDOW_FIELD, i.maxResultWindow());
if (StringUtils.isNotBlank(i.refreshInterval())) {
entityInfo.getSettingsMap().put(REFRESH_INTERVAL_FIELD, i.refreshInterval());
}
});
Class<? extends DefaultSettingsProvider> provider = settings == null ? DefaultSettingsProvider.class : settings.settingsProvider();
Object instance = provider.getConstructor(new Class[]{}).newInstance(new Object[]{});
Method method = provider.getDeclaredMethod(GET_SETTINGS_METHOD);
Object invoke = method.invoke(instance);
if (invoke instanceof Map) {
Map<String, Object> settingsMap = (Map<String, Object>) invoke;
if (CollectionUtils.isNotEmpty(settingsMap)) {
settingsMap.forEach((k, v) -> entityInfo.getSettingsMap().putIfAbsent(k, v));
}
if (settings == null) {
return;
}
IndexSettings.Builder builder = entityInfo.getIndexSettings();
builder.numberOfReplicas(settings.replicasNum() + "");
builder.numberOfShards(settings.shardsNum() + "");
builder.maxResultWindow((int)settings.maxResultWindow());
if (StringUtils.isNotBlank(settings.refreshInterval())) {
builder.refreshInterval(a -> a.time(settings.refreshInterval()));
}
ISettingsProvider provider = settings.settingsProvider().getDeclaredConstructor().newInstance();
provider.settings(builder);
}
/**

View File

@ -1,13 +1,13 @@
package org.dromara.easyes.core.toolkit;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.dromara.easyes.annotation.rely.FieldType;
import org.dromara.easyes.common.constants.BaseEsConstants;
import org.dromara.easyes.common.params.SFunction;
import org.dromara.easyes.common.property.GlobalConfig;
import org.dromara.easyes.common.utils.StringUtils;
import org.dromara.easyes.core.cache.GlobalConfigCache;
import org.dromara.easyes.common.property.GlobalConfig;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
@ -165,8 +165,8 @@ public class FieldUtils {
/**
* 获取实际字段名
*
* @param field 原字段名
* @param mappingColumnMap 字段映射关系map
* @param field 原字段名
* @param mappingColumnMap 字段映射关系map
* @return 实际字段名
*/
public static String getRealField(String field, Map<String, String> mappingColumnMap) {
@ -231,11 +231,10 @@ public class FieldUtils {
* @param mappingColumnMap 字段映射关系map
* @return 实际字段数组
*/
public static String[] getRealFields(String[] fields, Map<String, String> mappingColumnMap) {
public static List<String> getRealFields(String[] fields, Map<String, String> mappingColumnMap) {
return Arrays.stream(fields)
.map(field -> getRealField(field, mappingColumnMap))
.collect(Collectors.toList())
.toArray(new String[]{});
.collect(Collectors.toList());
}
/**
@ -246,7 +245,8 @@ public class FieldUtils {
* @return 实际字段数组
*/
public static List<String> getRealFields(List<String> fields, Map<String, String> mappingColumnMap) {
return Arrays.stream(getRealFields(fields.toArray(new String[0]), mappingColumnMap))
return fields.stream()
.map(field -> getRealField(field, mappingColumnMap))
.collect(Collectors.toList());
}

View File

@ -1,11 +1,12 @@
package org.dromara.easyes.core.toolkit;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
import lombok.SneakyThrows;
import org.dromara.easyes.common.utils.CollectionUtils;
import org.dromara.easyes.common.utils.StringUtils;
import org.dromara.easyes.common.utils.jackson.JsonUtils;
import org.dromara.easyes.core.biz.EsIndexInfo;
import org.dromara.easyes.core.config.GeneratorConfig;
import org.elasticsearch.client.RestHighLevelClient;
import java.util.*;
@ -35,23 +36,24 @@ public abstract class Generator {
* @param config 配置
*/
@SneakyThrows
public void generateEntity(GeneratorConfig config, RestHighLevelClient client) {
public void generateEntity(GeneratorConfig config, ElasticsearchClient client) {
// get index info
EsIndexInfo esIndexInfo = IndexUtils.getIndexInfo(client, config.getIndexName());
Map<String, Object> mapping = esIndexInfo.getMapping();
if (CollectionUtils.isEmpty(mapping)) {
TypeMapping.Builder mapping = esIndexInfo.getMapping();
if (mapping == null) {
return;
}
Map<String, Map> map = JsonUtils.toMap(mapping.build().toString(), String.class, Map.class);
// parse fields info
LinkedHashMap<String, LinkedHashMap<String, Object>> properties = (LinkedHashMap<String, LinkedHashMap<String, Object>>) mapping.get(PROPERTIES);
Map<String, Map<String, Object>> properties = (Map<String, Map<String, Object>>) map.get(PROPERTIES);
// execute generate
executeGenerate(properties, config, esIndexInfo, config.getIndexName());
}
@SneakyThrows
private void executeGenerate(LinkedHashMap<String, LinkedHashMap<String, Object>> properties, GeneratorConfig config, EsIndexInfo esIndexInfo, String className) {
private void executeGenerate(Map<String, Map<String, Object>> properties, GeneratorConfig config, EsIndexInfo esIndexInfo, String className) {
Map<String, String> modelMap = new HashMap<>(properties.size());
properties.forEach((k, v) -> Optional.ofNullable(v.get(TYPE)).ifPresent(esType -> {
if (SKIP_TYPE.contains(esType.toString())) {
@ -59,7 +61,7 @@ public abstract class Generator {
}
if (NESTED.equals(esType.toString())) {
// nested recursion
executeGenerate((LinkedHashMap<String, LinkedHashMap<String, Object>>) v.get(PROPERTIES), config, esIndexInfo, parseClassName(k));
executeGenerate((Map<String, Map<String, Object>>) v.get(PROPERTIES), config, esIndexInfo, parseClassName(k));
}
String javaType = getJavaType(esType.toString(), k);
modelMap.put(k, javaType);

View File

@ -0,0 +1,125 @@
package org.dromara.easyes.core.toolkit;
import co.elastic.clients.elasticsearch._types.GeoLocation;
import org.dromara.easyes.common.exception.EasyEsException;
import org.elasticsearch.geometry.Geometry;
import org.elasticsearch.geometry.Point;
import org.elasticsearch.geometry.Rectangle;
import org.elasticsearch.geometry.ShapeType;
import org.elasticsearch.geometry.utils.BitUtil;
import org.elasticsearch.geometry.utils.GeographyValidator;
import org.elasticsearch.geometry.utils.Geohash;
import org.elasticsearch.geometry.utils.WellKnownText;
import java.util.Locale;
/**
* geo工具类
*
* @author jaime
* @version 1.0
* @since 2025/2/18
*/
public class GeoUtils {
/**
* 读取geohash或lat-lon组合
*
* @param value String 必须是 geohash lat-lon组合(以逗号间隔)
* @return GeoLocation
*/
public static GeoLocation create(String value) {
return create(value, false, EffectivePoint.BOTTOM_LEFT);
}
public static GeoLocation create(String value, final boolean ignoreZValue, EffectivePoint effectivePoint) {
if (value.toLowerCase(Locale.ROOT).contains("point")) {
return createFromWKT(value, ignoreZValue);
} else if (value.contains(",")) {
return createFromCoordinates(value, ignoreZValue);
}
return parseGeoHash(value, effectivePoint);
}
public static GeoLocation createFromCoordinates(String value, final boolean ignoreZValue) {
String[] vals = value.split(",");
if (vals.length > 3) {
throw new EasyEsException(String.format("failed to parse [%s], expected 2 or 3 coordinates but found: [%s]", value, vals.length));
}
final double lat;
final double lon;
try {
lat = Double.parseDouble(vals[0].trim());
} catch (NumberFormatException ex) {
throw new EasyEsException("latitude must be a number");
}
try {
lon = Double.parseDouble(vals[1].trim());
} catch (NumberFormatException ex) {
throw new EasyEsException("longitude must be a number");
}
if (vals.length > 2 && !ignoreZValue) {
throw new EasyEsException(String.format(
"Exception parsing coordinates: found Z value [%s] but [ignore_z_value] parameter is [%s]",
Double.parseDouble(vals[2].trim()), ignoreZValue));
}
return create(lat, lon);
}
private static GeoLocation createFromWKT(String value, boolean ignoreZValue) {
Geometry geometry;
try {
geometry = WellKnownText.fromWKT(GeographyValidator.instance(ignoreZValue), false, value);
} catch (Exception e) {
throw new EasyEsException("Invalid WKT format", e);
}
if (geometry.type() != ShapeType.POINT) {
throw new EasyEsException(
"[geo_point] supports only POINT among WKT primitives, " + "but found " + geometry.type()
);
}
Point point = (Point) geometry;
return create(point.getY(), point.getX());
}
public static GeoLocation parseGeoHash(String geohash, EffectivePoint effectivePoint) {
if (effectivePoint == EffectivePoint.BOTTOM_LEFT) {
return createFromGeoHash(geohash);
} else {
Rectangle rectangle = Geohash.toBoundingBox(geohash);
return switch (effectivePoint) {
case TOP_LEFT -> create(rectangle.getMaxY(), rectangle.getMinX());
case TOP_RIGHT -> create(rectangle.getMaxY(), rectangle.getMaxX());
case BOTTOM_RIGHT -> create(rectangle.getMinY(), rectangle.getMaxX());
default -> throw new IllegalArgumentException("Unsupported effective point " + effectivePoint);
};
}
}
public static GeoLocation createFromIndexHash(long hash) {
return create(Geohash.decodeLatitude(hash), Geohash.decodeLongitude(hash));
}
public static GeoLocation createFromGeoHash(String geohash) {
return createFromIndexHash(Geohash.mortonEncode(geohash));
}
public static GeoLocation createFromGeoHash(long geohashLong) {
final int level = (int) (12 - (geohashLong & 15));
return createFromIndexHash(BitUtil.flipFlop((geohashLong >>> 4) << ((level * 5) + 2)));
}
public static GeoLocation create(double lat, double lon) {
return GeoLocation.of(b -> b.latlon(x -> x.lat(lat).lon(lon)));
}
/**
* 表示 geohash 单元格中应用作 geohash 值的点
*/
public enum EffectivePoint {
TOP_LEFT,
TOP_RIGHT,
BOTTOM_LEFT,
BOTTOM_RIGHT
}
}

View File

@ -1,18 +1,10 @@
package org.dromara.easyes.core.toolkit;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.Result;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch.core.*;
import org.dromara.easyes.common.constants.BaseEsConstants;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.xcontent.XContentType;
import java.io.IOException;
@ -36,12 +28,12 @@ public class LockUtils {
/**
* 尝试获取es分布式锁
*
* @param client RestHighLevelClient
* @param client ElasticsearchClient
* @param idValue id字段值实际未entityClass名,一个entity对应一把锁
* @param maxRetry 最大重试次数
* @return 是否获取成功
*/
public static synchronized boolean tryLock(RestHighLevelClient client, String idValue, Integer maxRetry) {
public static synchronized boolean tryLock(ElasticsearchClient client, String idValue, Integer maxRetry) {
boolean existsIndex = IndexUtils.existsIndex(client, LOCK_INDEX);
if (!existsIndex) {
IndexUtils.createEmptyIndex(client, LOCK_INDEX);
@ -66,46 +58,46 @@ public class LockUtils {
/**
* 创建锁
*
* @param client RestHighLevelClient
* @param client ElasticsearchClient
* @param idValue id字段值实际未entityClass名,一个entity对应一把锁
* @return 是否创建成功
*/
private static boolean createLock(RestHighLevelClient client, String idValue) {
IndexRequest indexRequest = new IndexRequest(LOCK_INDEX);
indexRequest.id(idValue);
indexRequest.source(BaseEsConstants.DISTRIBUTED_LOCK_TIP_JSON, XContentType.JSON);
private static boolean createLock(ElasticsearchClient client, String idValue) {
IndexRequest<?> indexRequest = IndexRequest.of(x -> x
.index(LOCK_INDEX).id(idValue).document(BaseEsConstants.DISTRIBUTED_LOCK_TIP_JSON)
);
IndexResponse response;
try {
response = client.index(indexRequest, RequestOptions.DEFAULT);
response = client.index(indexRequest);
} catch (IOException e) {
e.printStackTrace();
return Boolean.FALSE;
}
return response.status().equals(RestStatus.CREATED);
return response.result().equals(Result.Created);
}
/**
* 释放锁
*
* @param client RestHighLevelClient
* @param client ElasticsearchClient
* @param idValue id字段值实际未entityClass名,一个entity对应一把锁
* @param maxRetry 最大重试次数
* @return 是否释放成功
*/
public synchronized static boolean release(RestHighLevelClient client, String idValue, Integer maxRetry) {
DeleteRequest deleteRequest = new DeleteRequest(LOCK_INDEX);
deleteRequest.id(idValue);
public synchronized static boolean release(ElasticsearchClient client, String idValue, Integer maxRetry) {
if (maxRetry <= BaseEsConstants.ZERO) {
return Boolean.FALSE;
}
DeleteRequest deleteRequest = DeleteRequest.of(x -> x
.index(LOCK_INDEX).id(idValue)
);
DeleteResponse response;
try {
response = client.delete(deleteRequest, RequestOptions.DEFAULT);
response = client.delete(deleteRequest);
} catch (IOException e) {
return retryRelease(client, idValue, --maxRetry);
}
if (RestStatus.OK.equals(response.status())) {
if (Result.Deleted.equals(response.result())) {
return Boolean.TRUE;
} else {
return retryRelease(client, idValue, maxRetry);
@ -115,12 +107,12 @@ public class LockUtils {
/**
* 重试释放
*
* @param client RestHighLevelClient
* @param client ElasticsearchClient
* @param idValue id字段值实际未entityClass名,一个entity对应一把锁
* @param maxRetry 最大重试次数
* @return 是否重试成功
*/
private static boolean retryRelease(RestHighLevelClient client, String idValue, Integer maxRetry) {
private static boolean retryRelease(ElasticsearchClient client, String idValue, Integer maxRetry) {
try {
Thread.sleep(WAIT_SECONDS / maxRetry);
} catch (InterruptedException interruptedException) {
@ -132,24 +124,22 @@ public class LockUtils {
/**
* 获取个数
*
* @param client RestHighLevelClient
* @param client ElasticsearchClient
* @param idValue id字段值实际未entityClass名,一个entity对应一把锁
* @return 该id对应的锁的个数, 如果>0 说明已有锁,需重试获取,否则认为无锁
*/
private static Integer getCount(RestHighLevelClient client, String idValue) {
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices(LOCK_INDEX);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.termQuery(ID_FIELD, idValue));
searchRequest.source(searchSourceBuilder);
SearchResponse response;
private static Integer getCount(ElasticsearchClient client, String idValue) {
co.elastic.clients.elasticsearch.core.SearchRequest.Builder searchRequest = new SearchRequest.Builder();
searchRequest.index(LOCK_INDEX);
searchRequest.query(Query.of(x -> x.term(y -> y.field(ID_FIELD).value(idValue))));
SearchResponse<?> response;
try {
response = client.search(searchRequest, RequestOptions.DEFAULT);
response = client.search(searchRequest.build(), Object.class);
} catch (IOException e) {
e.printStackTrace();
return BaseEsConstants.ONE;
}
return (int) response.getHits().getTotalHits().value;
return (int) response.hits().total().value();
}
}

View File

@ -1,5 +1,6 @@
package org.dromara.easyes.core.toolkit;
import co.elastic.clients.elasticsearch._types.FieldValue;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.dromara.easyes.core.biz.EsPageInfo;
@ -50,8 +51,8 @@ public class PageHelper {
* @param <T> 数据类型
* @return 分页信息
*/
public static <T> SAPageInfo<T> getSAPageInfo(List<T> list, Long total, List<Object> searchAfter
, List<Object> nextSearchAfter, Integer pageSize) {
public static <T> SAPageInfo<T> getSAPageInfo(List<T> list, Long total, List<FieldValue> searchAfter
, List<FieldValue> nextSearchAfter, Integer pageSize) {
SAPageInfo<T> saPageInfo = new SAPageInfo<>();
saPageInfo.setSearchAfter(searchAfter);
saPageInfo.setNextSearchAfter(nextSearchAfter);

View File

@ -14,8 +14,8 @@
<artifactId>easy-es-extension</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<dependencies>

View File

@ -31,10 +31,11 @@
<properties>
<java.version>1.8</java.version>
<lombok.version>1.18.28</lombok.version>
<es-rest-high-level-client.version>7.17.8</es-rest-high-level-client.version>
<es.version>7.17.8</es.version>
<lombok.version>1.18.36</lombok.version>
<elasticsearch.java.version>8.17.1</elasticsearch.java.version>
<jackson.version>2.18.2</jackson.version>
<fastjson.version>1.2.83</fastjson.version>
<jakarta.json.version>2.1.3</jakarta.json.version>
<codec.version>1.13</codec.version>
<spring-boot.version>2.6.10</spring-boot.version>
<spring.version>5.3.20</spring.version>
@ -81,14 +82,33 @@
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>${es-rest-high-level-client.version}</version>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>${elasticsearch.java.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${es.version}</version>
<artifactId>elasticsearch-geo</artifactId>
<version>${elasticsearch.java.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
<version>${jakarta.json.version}</version>
</dependency>
<dependency>
@ -96,16 +116,12 @@
<artifactId>spring-boot-autoconfigure</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>org.noear</groupId>

View File

@ -10,8 +10,8 @@
<artifactId>easy-es-solon-plugin</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<dependencies>

View File

@ -1,18 +1,19 @@
package org.dromara.easyes.solon.config;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import org.dromara.easyes.common.property.EasyEsDynamicProperties;
import org.dromara.easyes.common.property.EasyEsProperties;
import org.dromara.easyes.common.strategy.AutoProcessIndexStrategy;
import org.dromara.easyes.common.utils.*;
import org.dromara.easyes.common.utils.CollectionUtils;
import org.dromara.easyes.common.utils.EsClientUtils;
import org.dromara.easyes.core.index.AutoProcessIndexNotSmoothlyStrategy;
import org.dromara.easyes.core.index.AutoProcessIndexSmoothlyStrategy;
import org.elasticsearch.client.RestHighLevelClient;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Condition;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
import java.util.*;
import java.util.Map;
/**
* es自动配置
@ -20,7 +21,7 @@ import java.util.*;
* Copyright © 2021 xpc1024 All Rights Reserved
**/
@Configuration
@Condition(onClass = RestHighLevelClient.class, onProperty = "${easy-es.enable:true} = true && ${easy-es.address:x} != x")
@Condition(onClass = ElasticsearchClient.class, onProperty = "${easy-es.enable:true} = true && ${easy-es.address:x} != x")
public class EsAutoConfiguration {
@Bean
@ -39,31 +40,30 @@ public class EsAutoConfiguration {
}
/**
* 装配RestHighLevelClient
* 装配ElasticsearchClient
*
* @return RestHighLevelClient bean
* @return ElasticsearchClient bean
*/
@Bean
@Condition(onMissingBean = RestHighLevelClient.class)
public RestHighLevelClient restHighLevelClient(EasyEsProperties easyEsProperties) {
return RestHighLevelClientUtils.restHighLevelClient(easyEsProperties);
@Condition(onMissingBean = ElasticsearchClient.class)
public ElasticsearchClient elasticClient(EasyEsProperties easyEsProperties) {
return EsClientUtils.buildClient(easyEsProperties);
}
@Bean
public RestHighLevelClientUtils restHighLevelClientUtils(
public EsClientUtils esClientUtils(
EasyEsProperties properties, EasyEsDynamicProperties dynamicProperties) {
RestHighLevelClientUtils restHighLevelClientUtils = new RestHighLevelClientUtils();
EsClientUtils esClientUtils = new EsClientUtils();
Map<String, EasyEsProperties> datasourceMap = dynamicProperties.getDatasource();
if (CollectionUtils.isEmpty(datasourceMap)) {
// 设置默认数据源,兼容不使用多数据源配置场景的老用户使用习惯
datasourceMap.put(RestHighLevelClientUtils.DEFAULT_DS, properties);
datasourceMap.put(EsClientUtils.DEFAULT_DS, properties);
}
for (String key : datasourceMap.keySet()) {
EasyEsProperties easyEsConfigProperties = datasourceMap.get(key);
RestHighLevelClientUtils.registerRestHighLevelClient(key, RestHighLevelClientUtils
.restHighLevelClient(easyEsConfigProperties));
EsClientUtils.registerClient(key, () -> EsClientUtils.buildClient(easyEsConfigProperties));
}
return restHighLevelClientUtils;
return esClientUtils;
}
@Bean

View File

@ -1,8 +1,8 @@
package org.dromara.easyes.solon.config;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import org.dromara.easyes.core.config.GeneratorConfig;
import org.dromara.easyes.core.toolkit.Generator;
import org.elasticsearch.client.RestHighLevelClient;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
@ -15,7 +15,7 @@ import org.noear.solon.annotation.Inject;
public class GeneratorConfiguration extends Generator {
@Inject
private RestHighLevelClient client;
private ElasticsearchClient client;
@Override
public Boolean generate(GeneratorConfig config) {

View File

@ -1,10 +1,10 @@
package org.dromara.easyes.solon.factory;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import org.dromara.easyes.common.enums.ProcessIndexStrategyEnum;
import org.dromara.easyes.common.property.EasyEsProperties;
import org.dromara.easyes.common.utils.ExceptionUtils;
import org.dromara.easyes.common.strategy.AutoProcessIndexStrategy;
import org.elasticsearch.client.RestHighLevelClient;
import org.dromara.easyes.common.utils.ExceptionUtils;
import org.noear.solon.Solon;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Condition;
@ -21,7 +21,7 @@ import java.util.Optional;
* Copyright © 2022 xpc1024 All Rights Reserved
**/
@Component
@Condition(onBean = RestHighLevelClient.class, onProperty = "${easy-es.enable:true} = true && ${easy-es.address:x} != x")
@Condition(onBean = ElasticsearchClient.class, onProperty = "${easy-es.enable:true} = true && ${easy-es.address:x} != x")
public class IndexStrategyFactory implements LifecycleBean {
/**

View File

@ -1,26 +1,27 @@
package org.dromara.easyes.solon.register;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import org.dromara.easyes.annotation.EsDS;
import org.dromara.easyes.annotation.Intercepts;
import org.dromara.easyes.common.enums.ProcessIndexStrategyEnum;
import org.dromara.easyes.common.property.EasyEsProperties;
import org.dromara.easyes.common.property.GlobalConfig;
import org.dromara.easyes.common.strategy.AutoProcessIndexStrategy;
import org.dromara.easyes.common.utils.EEVersionUtils;
import org.dromara.easyes.common.utils.EsClientUtils;
import org.dromara.easyes.common.utils.LogUtils;
import org.dromara.easyes.common.utils.RestHighLevelClientUtils;
import org.dromara.easyes.common.utils.TypeUtils;
import org.dromara.easyes.core.biz.EntityInfo;
import org.dromara.easyes.core.cache.BaseCache;
import org.dromara.easyes.core.cache.GlobalConfigCache;
import org.dromara.easyes.common.property.GlobalConfig;
import org.dromara.easyes.core.cache.JacksonCache;
import org.dromara.easyes.core.kernel.BaseEsMapper;
import org.dromara.easyes.core.proxy.EsMapperProxy;
import org.dromara.easyes.common.strategy.AutoProcessIndexStrategy;
import org.dromara.easyes.core.toolkit.EntityInfoHelper;
import org.dromara.easyes.extension.context.Interceptor;
import org.dromara.easyes.extension.context.InterceptorChain;
import org.dromara.easyes.extension.context.InterceptorChainHolder;
import org.dromara.easyes.solon.factory.IndexStrategyFactory;
import org.elasticsearch.client.RestHighLevelClient;
import org.noear.solon.Solon;
import org.noear.solon.core.AppContext;
import org.noear.solon.core.BeanBuilder;
@ -34,7 +35,7 @@ import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import static org.dromara.easyes.common.constants.BaseEsConstants.*;
import static org.dromara.easyes.common.utils.RestHighLevelClientUtils.DEFAULT_DS;
import static org.dromara.easyes.common.utils.EsClientUtils.DEFAULT_DS;
/**
* 注册bean
@ -135,17 +136,25 @@ public class MapperScannerRegister implements BeanBuilder<EsMapperScan> {
*/
private void beanWrapPut(Class<?> clazz) {
EasyEsProperties esConfigProperties = context.getBean(EasyEsProperties.class);
RestHighLevelClientUtils restHighLevelClientUtils = context.getBeanOrNew(RestHighLevelClientUtils.class);
EsClientUtils esClientUtils = context.getBeanOrNew(EsClientUtils.class);
EsMapperProxy<?> esMapperProxy = new EsMapperProxy<>(clazz, new ConcurrentHashMap<>());
// 获取实体类
Class<?> entityClass = TypeUtils.getInterfaceT(clazz, ZERO);
// 初始化缓存
GlobalConfigCache.setGlobalConfig(esConfigProperties.getGlobalConfig());
// 初始化entity缓存
BaseCache.initEntityCache(entityClass);
// jackson配置缓存
JacksonCache.init(EntityInfoHelper.ENTITY_INFO_CACHE);
//获取动态数据源 若未配置多数据源,则使用默认数据源
String restHighLevelClientId = Optional.ofNullable(clazz.getAnnotation(EsDS.class))
.map(EsDS::value).orElse(DEFAULT_DS);
RestHighLevelClient client = restHighLevelClientUtils.getClient(restHighLevelClientId);
BaseCache.initCache(clazz, entityClass, client);
ElasticsearchClient client = esClientUtils.getClient(restHighLevelClientId);
BaseCache.initMapperCache(clazz, entityClass, client);
// 创建代理
Object mapperProxy = Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, esMapperProxy);

View File

@ -9,8 +9,8 @@
<artifactId>easy-es-solon-test</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<dependencies>

View File

@ -111,7 +111,7 @@ public class Document {
/**
* 嵌套类型 注意,务必像下面示例一样指定类型为nested及其nested class,否则会导致框架无法正常运行
*/
@IndexField(fieldType = FieldType.NESTED, nestedClass = User.class)
@IndexField(fieldType = FieldType.NESTED, nestedOrObjectClass = User.class)
private List<User> users;
/**

View File

@ -9,7 +9,6 @@ import org.dromara.easyes.annotation.InnerIndexField;
import org.dromara.easyes.annotation.MultiIndexField;
import org.dromara.easyes.annotation.rely.Analyzer;
import org.dromara.easyes.annotation.rely.FieldType;
import org.dromara.easyes.test.entity.Faq;
import java.util.Set;
@ -44,7 +43,7 @@ public class User {
/**
* 多级嵌套
*/
@IndexField(fieldType = FieldType.NESTED, nestedClass = Faq.class)
@IndexField(fieldType = FieldType.NESTED, nestedOrObjectClass = Faq.class)
private Set<Faq> faqs;
/**
* 高亮显示的内容

View File

@ -1,5 +1,8 @@
package org.dromara.easyes.test.all;
import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch._types.GeoLocation;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import org.dromara.easyes.common.constants.BaseEsConstants;
import org.dromara.easyes.core.biz.EsPageInfo;
import org.dromara.easyes.core.biz.OrderByParam;
@ -16,8 +19,7 @@ import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.HttpAsyncResponseConsumerFactory;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.geo.GeoShapeRelation;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.geometry.Circle;
import org.elasticsearch.geometry.Point;
@ -166,7 +168,7 @@ public class AllTest {
@Order(4)
public void testUpdateBySetSearchSourceBuilder() {
LambdaEsUpdateWrapper<Document> wrapper = new LambdaEsUpdateWrapper<>();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.termQuery(FieldUtils.val(Document::getTitle) + KEYWORD_SUFFIX, "测试文档2"));
wrapper.setSearchSourceBuilder(searchSourceBuilder);
@ -533,7 +535,7 @@ public class AllTest {
@Order(6)
public void testSetSearchSourceBuilder() {
// 测试混合查询的另一种方式
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery(FieldUtils.val(Document::getCreator), "老汉"));
Optional.ofNullable(EntityInfoHelper.getEntityInfo(Document.class))
.flatMap(i -> Optional.ofNullable(i.getMaxResultWindow()))
@ -630,7 +632,7 @@ public class AllTest {
Assertions.assertEquals(10, saPageInfo.getList().size());
//获取下一页
List<Object> nextSearchAfter = saPageInfo.getNextSearchAfter();
List<FieldValue> nextSearchAfter = saPageInfo.getNextSearchAfter();
SAPageInfo<Document> next = documentMapper.searchAfterPage(lambdaEsQueryWrapper, nextSearchAfter, 10);
Assertions.assertEquals(10, next.getList().size());
}
@ -701,7 +703,7 @@ public class AllTest {
@Order(6)
public void testOrderByDistanceAsc() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
GeoPoint centerPoint = new GeoPoint(41.0, 116.0);
GeoLocation centerPoint = new GeoLocation(41.0, 116.0);
wrapper.match(Document::getCreator, "老汉")
.geoDistance(Document::getLocation, 168.8, centerPoint)
.orderByDistanceAsc(Document::getLocation, centerPoint);
@ -714,7 +716,7 @@ public class AllTest {
@Order(6)
public void testOrderByDistanceDesc() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
GeoPoint centerPoint = new GeoPoint(41.0, 116.0);
GeoLocation centerPoint = new GeoLocation(41.0, 116.0);
wrapper.match(Document::getCreator, "老汉")
.geoDistance(Document::getLocation, 168.8, centerPoint)
.orderByDistanceDesc(Document::getLocation, centerPoint);
@ -727,8 +729,8 @@ public class AllTest {
@Order(6)
public void testOrderByDistanceMulti() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
GeoPoint centerPoint = new GeoPoint(41.0, 116.0);
GeoPoint centerPoint1 = new GeoPoint(42.0, 118.0);
GeoLocation centerPoint = new GeoLocation(41.0, 116.0);
GeoLocation centerPoint1 = new GeoLocation(42.0, 118.0);
wrapper.match(Document::getCreator, "老汉")
.geoDistance(Document::getLocation, 168.8, centerPoint)
.orderByDistanceDesc(Document::getLocation, centerPoint)
@ -757,7 +759,7 @@ public class AllTest {
fieldSort(FieldUtils.getRealField(
FieldUtils.val(Document::getStarNum),
EntityInfoHelper.getEntityInfo(Document.class).getMappingColumnMap()));
fieldSortBuilder.order(SortOrder.DESC);
fieldSortBuilder.order(SortOrder.Desc);
wrapper.sort(fieldSortBuilder);
List<Document> documents = documentMapper.selectList(wrapper);
Assertions.assertEquals("22", documents.get(0).getEsId());
@ -852,8 +854,8 @@ public class AllTest {
@Order(6)
public void testGeoBoundingBox() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
GeoPoint leftTop = new GeoPoint(41.187328D, 115.498353D);
GeoPoint bottomRight = new GeoPoint(39.084509D, 117.610461D);
GeoLocation leftTop = new GeoLocation(41.187328D, 115.498353D);
GeoLocation bottomRight = new GeoLocation(39.084509D, 117.610461D);
wrapper.geoBoundingBox(Document::getLocation, leftTop, bottomRight);
List<Document> documents = documentMapper.selectList(wrapper);
Assertions.assertEquals(4, documents.size());
@ -864,12 +866,12 @@ public class AllTest {
@Order(6)
public void testGeoDistance() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
GeoPoint geoPoint = new GeoPoint(41.0, 116.0);
GeoLocation geoPoint = new GeoLocation(41.0, 116.0);
wrapper.geoDistance(Document::getLocation, 168.8, DistanceUnit.KILOMETERS, geoPoint);
GeoDistanceSortBuilder geoDistanceSortBuilder = SortBuilders.geoDistanceSort(FieldUtils.val(Document::getLocation), geoPoint)
.unit(DistanceUnit.KILOMETERS)
.geoDistance(GeoDistance.ARC)
.order(SortOrder.DESC);
.order(SortOrder.Desc);
wrapper.sort(geoDistanceSortBuilder);
List<Document> documents = documentMapper.selectList(wrapper);
@ -880,10 +882,10 @@ public class AllTest {
@Order(6)
public void testGeoPolygon() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
List<GeoPoint> geoPoints = new ArrayList<>();
GeoPoint geoPoint = new GeoPoint(40.178012, 116.577188);
GeoPoint geoPoint1 = new GeoPoint(40.169329, 116.586315);
GeoPoint geoPoint2 = new GeoPoint(40.178288, 116.591813);
List<GeoLocation> geoPoints = new ArrayList<>();
GeoLocation geoPoint = new GeoLocation(40.178012, 116.577188);
GeoLocation geoPoint1 = new GeoLocation(40.169329, 116.586315);
GeoLocation geoPoint2 = new GeoLocation(40.178288, 116.591813);
geoPoints.add(geoPoint);
geoPoints.add(geoPoint1);
geoPoints.add(geoPoint2);
@ -897,7 +899,7 @@ public class AllTest {
public void testGeoShape() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
Circle circle = new Circle(13, 14, 100);
wrapper.geoShape(Document::getGeoLocation, circle, ShapeRelation.DISJOINT);
wrapper.geoShape(Document::getGeoLocation, circle, GeoShapeRelation.DISJOINT);
List<Document> documents = documentMapper.selectList(wrapper);
Assertions.assertEquals(22, documents.size());
}
@ -926,7 +928,7 @@ public class AllTest {
String scriptCode = "cosineSimilarity(params.vector, 'vector') + 1.0";
QueryBuilder queryBuilder = QueryBuilders.scriptScoreQuery(QueryBuilders.matchAllQuery(), new Script(ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG, scriptCode, params));
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(queryBuilder);
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.setSearchSourceBuilder(searchSourceBuilder);
@ -988,7 +990,7 @@ public class AllTest {
// SQL写法
// where business_type = 1 and (state = 9 or (state = 8 and bidding_sign = 1)) or (business_type = 2 and state in (2,3))
// RestHighLevelClient写法
// ElasticsearchClient写法
List<Integer> values = Arrays.asList(2, 3);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.termQuery("business_type", 1));

View File

@ -11,8 +11,8 @@
<artifactId>easy-es-spring-test</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<junit-jupiter-engine.version>5.8.2</junit-jupiter-engine.version>
<spring-boot.version>2.6.10</spring-boot.version>
</properties>

View File

@ -1,5 +1,8 @@
package org.dromara.easyes.test.all;
import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch._types.GeoLocation;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import org.dromara.easyes.common.constants.BaseEsConstants;
import org.dromara.easyes.core.biz.EsPageInfo;
import org.dromara.easyes.core.biz.OrderByParam;
@ -16,8 +19,7 @@ import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.HttpAsyncResponseConsumerFactory;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.geo.GeoShapeRelation;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.geometry.Circle;
import org.elasticsearch.geometry.Point;
@ -166,7 +168,7 @@ public class XmlScannerAllTest {
@Order(4)
public void testUpdateBySetSearchSourceBuilder() {
LambdaEsUpdateWrapper<Document> wrapper = new LambdaEsUpdateWrapper<>();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.termQuery(FieldUtils.val(Document::getTitle) + KEYWORD_SUFFIX, "测试文档2"));
wrapper.setSearchSourceBuilder(searchSourceBuilder);
@ -533,7 +535,7 @@ public class XmlScannerAllTest {
@Order(6)
public void testSetSearchSourceBuilder() {
// 测试混合查询的另一种方式
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery(FieldUtils.val(Document::getCreator), "老汉"));
Optional.ofNullable(EntityInfoHelper.getEntityInfo(Document.class))
.flatMap(i -> Optional.ofNullable(i.getMaxResultWindow()))
@ -630,7 +632,7 @@ public class XmlScannerAllTest {
Assertions.assertEquals(10, saPageInfo.getList().size());
//获取下一页
List<Object> nextSearchAfter = saPageInfo.getNextSearchAfter();
List<FieldValue> nextSearchAfter = saPageInfo.getNextSearchAfter();
SAPageInfo<Document> next = documentMapper.searchAfterPage(lambdaEsQueryWrapper, nextSearchAfter, 10);
Assertions.assertEquals(10, next.getList().size());
}
@ -701,7 +703,7 @@ public class XmlScannerAllTest {
@Order(6)
public void testOrderByDistanceAsc() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
GeoPoint centerPoint = new GeoPoint(41.0, 116.0);
GeoLocation centerPoint = new GeoLocation(41.0, 116.0);
wrapper.match(Document::getCreator, "老汉")
.geoDistance(Document::getLocation, 168.8, centerPoint)
.orderByDistanceAsc(Document::getLocation, centerPoint);
@ -714,7 +716,7 @@ public class XmlScannerAllTest {
@Order(6)
public void testOrderByDistanceDesc() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
GeoPoint centerPoint = new GeoPoint(41.0, 116.0);
GeoLocation centerPoint = new GeoLocation(41.0, 116.0);
wrapper.match(Document::getCreator, "老汉")
.geoDistance(Document::getLocation, 168.8, centerPoint)
.orderByDistanceDesc(Document::getLocation, centerPoint);
@ -727,8 +729,8 @@ public class XmlScannerAllTest {
@Order(6)
public void testOrderByDistanceMulti() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
GeoPoint centerPoint = new GeoPoint(41.0, 116.0);
GeoPoint centerPoint1 = new GeoPoint(42.0, 118.0);
GeoLocation centerPoint = new GeoLocation(41.0, 116.0);
GeoLocation centerPoint1 = new GeoLocation(42.0, 118.0);
wrapper.match(Document::getCreator, "老汉")
.geoDistance(Document::getLocation, 168.8, centerPoint)
.orderByDistanceDesc(Document::getLocation, centerPoint)
@ -757,7 +759,7 @@ public class XmlScannerAllTest {
fieldSort(FieldUtils.getRealField(
FieldUtils.val(Document::getStarNum),
EntityInfoHelper.getEntityInfo(Document.class).getMappingColumnMap()));
fieldSortBuilder.order(SortOrder.DESC);
fieldSortBuilder.order(SortOrder.Desc);
wrapper.sort(fieldSortBuilder);
List<Document> documents = documentMapper.selectList(wrapper);
Assertions.assertEquals("22", documents.get(0).getEsId());
@ -852,8 +854,8 @@ public class XmlScannerAllTest {
@Order(6)
public void testGeoBoundingBox() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
GeoPoint leftTop = new GeoPoint(41.187328D, 115.498353D);
GeoPoint bottomRight = new GeoPoint(39.084509D, 117.610461D);
GeoLocation leftTop = new GeoLocation(41.187328D, 115.498353D);
GeoLocation bottomRight = new GeoLocation(39.084509D, 117.610461D);
wrapper.geoBoundingBox(Document::getLocation, leftTop, bottomRight);
List<Document> documents = documentMapper.selectList(wrapper);
Assertions.assertEquals(4, documents.size());
@ -864,12 +866,12 @@ public class XmlScannerAllTest {
@Order(6)
public void testGeoDistance() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
GeoPoint geoPoint = new GeoPoint(41.0, 116.0);
GeoLocation geoPoint = new GeoLocation(41.0, 116.0);
wrapper.geoDistance(Document::getLocation, 168.8, DistanceUnit.KILOMETERS, geoPoint);
GeoDistanceSortBuilder geoDistanceSortBuilder = SortBuilders.geoDistanceSort(FieldUtils.val(Document::getLocation), geoPoint)
.unit(DistanceUnit.KILOMETERS)
.geoDistance(GeoDistance.ARC)
.order(SortOrder.DESC);
.order(SortOrder.Desc);
wrapper.sort(geoDistanceSortBuilder);
List<Document> documents = documentMapper.selectList(wrapper);
@ -880,10 +882,10 @@ public class XmlScannerAllTest {
@Order(6)
public void testGeoPolygon() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
List<GeoPoint> geoPoints = new ArrayList<>();
GeoPoint geoPoint = new GeoPoint(40.178012, 116.577188);
GeoPoint geoPoint1 = new GeoPoint(40.169329, 116.586315);
GeoPoint geoPoint2 = new GeoPoint(40.178288, 116.591813);
List<GeoLocation> geoPoints = new ArrayList<>();
GeoLocation geoPoint = new GeoLocation(40.178012, 116.577188);
GeoLocation geoPoint1 = new GeoLocation(40.169329, 116.586315);
GeoLocation geoPoint2 = new GeoLocation(40.178288, 116.591813);
geoPoints.add(geoPoint);
geoPoints.add(geoPoint1);
geoPoints.add(geoPoint2);
@ -897,7 +899,7 @@ public class XmlScannerAllTest {
public void testGeoShape() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
Circle circle = new Circle(13, 14, 100);
wrapper.geoShape(Document::getGeoLocation, circle, ShapeRelation.DISJOINT);
wrapper.geoShape(Document::getGeoLocation, circle, GeoShapeRelation.DISJOINT);
List<Document> documents = documentMapper.selectList(wrapper);
Assertions.assertEquals(22, documents.size());
}
@ -926,7 +928,7 @@ public class XmlScannerAllTest {
String scriptCode = "cosineSimilarity(params.vector, 'vector') + 1.0";
QueryBuilder queryBuilder = QueryBuilders.scriptScoreQuery(QueryBuilders.matchAllQuery(), new Script(ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG, scriptCode, params));
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(queryBuilder);
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.setSearchSourceBuilder(searchSourceBuilder);
@ -988,7 +990,7 @@ public class XmlScannerAllTest {
// SQL写法
// where business_type = 1 and (state = 9 or (state = 8 and bidding_sign = 1)) or (business_type = 2 and state in (2,3))
// RestHighLevelClient写法
// ElasticsearchClient写法
List<Integer> values = Arrays.asList(2, 3);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.termQuery("business_type", 1));

View File

@ -110,7 +110,7 @@ public class Document {
/**
* 嵌套类型 注意,务必像下面示例一样指定类型为nested及其nested class,否则会导致框架无法正常运行
*/
@IndexField(fieldType = FieldType.NESTED, nestedClass = User.class)
@IndexField(fieldType = FieldType.NESTED, nestedOrObjectClass = User.class)
private List<User> users;
/**

View File

@ -43,7 +43,7 @@ public class User {
/**
* 多级嵌套
*/
@IndexField(fieldType = FieldType.NESTED, nestedClass = Faq.class)
@IndexField(fieldType = FieldType.NESTED, nestedOrObjectClass = Faq.class)
private Set<Faq> faqs;
/**
* 高亮显示的内容

View File

@ -13,8 +13,8 @@
<artifactId>easy-es-spring</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<dependencies>

View File

@ -4,7 +4,7 @@ import lombok.Setter;
import org.dromara.easyes.common.property.EasyEsDynamicProperties;
import org.dromara.easyes.common.property.EasyEsProperties;
import org.dromara.easyes.common.strategy.AutoProcessIndexStrategy;
import org.dromara.easyes.common.utils.RestHighLevelClientUtils;
import org.dromara.easyes.common.utils.EsClientUtils;
import org.dromara.easyes.core.index.AutoProcessIndexNotSmoothlyStrategy;
import org.dromara.easyes.core.index.AutoProcessIndexSmoothlyStrategy;
import org.dromara.easyes.spring.factory.IndexStrategyFactory;
@ -45,22 +45,21 @@ public class EasyEsConfiguration implements InitializingBean {
}
@Bean
public RestHighLevelClientUtils restHighLevelClientUtils() {
RestHighLevelClientUtils restHighLevelClientUtils = new RestHighLevelClientUtils();
public EsClientUtils esClientUtils() {
EsClientUtils esClientUtils = new EsClientUtils();
if (this.easyEsDynamicProperties == null) {
this.easyEsDynamicProperties = new EasyEsDynamicProperties();
}
Map<String, EasyEsProperties> datasourceMap = this.easyEsDynamicProperties.getDatasource();
if (datasourceMap.isEmpty()) {
// 设置默认数据源,兼容不使用多数据源配置场景的老用户使用习惯
datasourceMap.put(RestHighLevelClientUtils.DEFAULT_DS, this.easyEsProperties);
datasourceMap.put(EsClientUtils.DEFAULT_DS, this.easyEsProperties);
}
for (String key : datasourceMap.keySet()) {
EasyEsProperties easyEsConfigProperties = datasourceMap.get(key);
RestHighLevelClientUtils.registerRestHighLevelClient(key, RestHighLevelClientUtils
.restHighLevelClient(easyEsConfigProperties));
EsClientUtils.registerClient(key, () -> EsClientUtils.buildClient(easyEsConfigProperties));
}
return restHighLevelClientUtils;
return esClientUtils;
}
/**

View File

@ -1,24 +1,25 @@
package org.dromara.easyes.spring.config;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import org.dromara.easyes.annotation.EsDS;
import org.dromara.easyes.annotation.Intercepts;
import org.dromara.easyes.common.enums.ProcessIndexStrategyEnum;
import org.dromara.easyes.common.property.EasyEsProperties;
import org.dromara.easyes.common.property.GlobalConfig;
import org.dromara.easyes.common.strategy.AutoProcessIndexStrategy;
import org.dromara.easyes.common.utils.EsClientUtils;
import org.dromara.easyes.common.utils.LogUtils;
import org.dromara.easyes.common.utils.RestHighLevelClientUtils;
import org.dromara.easyes.common.utils.TypeUtils;
import org.dromara.easyes.core.biz.EntityInfo;
import org.dromara.easyes.core.cache.BaseCache;
import org.dromara.easyes.core.cache.GlobalConfigCache;
import org.dromara.easyes.core.cache.JacksonCache;
import org.dromara.easyes.core.proxy.EsMapperProxy;
import org.dromara.easyes.core.toolkit.EntityInfoHelper;
import org.dromara.easyes.extension.context.Interceptor;
import org.dromara.easyes.extension.context.InterceptorChain;
import org.dromara.easyes.extension.context.InterceptorChainHolder;
import org.dromara.easyes.spring.factory.IndexStrategyFactory;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
@ -29,7 +30,7 @@ import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import static org.dromara.easyes.common.constants.BaseEsConstants.ZERO;
import static org.dromara.easyes.common.utils.RestHighLevelClientUtils.DEFAULT_DS;
import static org.dromara.easyes.common.utils.EsClientUtils.DEFAULT_DS;
/**
* 代理类
@ -62,12 +63,18 @@ public class MapperFactoryBean<T> implements FactoryBean<T> {
// 初始化缓存
GlobalConfigCache.setGlobalConfig(globalConfig);
// 初始化entity缓存
BaseCache.initEntityCache(entityClass);
// jackson配置缓存
JacksonCache.init(EntityInfoHelper.ENTITY_INFO_CACHE);
//获取动态数据源 若未配置多数据源,则使用默认数据源
String restHighLevelClientId = Optional.ofNullable(mapperInterface.getAnnotation(EsDS.class))
.map(EsDS::value).orElse(DEFAULT_DS);
RestHighLevelClient client = this.applicationContext.getBean(RestHighLevelClientUtils.class)
ElasticsearchClient client = this.applicationContext.getBean(EsClientUtils.class)
.getClient(restHighLevelClientId);
BaseCache.initCache(mapperInterface, entityClass, client);
BaseCache.initMapperCache(mapperInterface, entityClass, client);
// 创建代理
T t = (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[]{mapperInterface}, esMapperProxy);

View File

@ -13,8 +13,8 @@
</parent>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<dependencies>

View File

@ -13,8 +13,8 @@
<artifactId>easy-es-springboot-test</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<dependencies>

View File

@ -111,7 +111,7 @@ public class Document {
/**
* 嵌套类型 注意,务必像下面示例一样指定类型为nested及其nested class,否则会导致框架无法正常运行
*/
@IndexField(fieldType = FieldType.NESTED, nestedClass = User.class)
@IndexField(fieldType = FieldType.NESTED, nestedOrObjectClass = User.class)
private List<User> users;
/**

View File

@ -43,7 +43,7 @@ public class User {
/**
* 多级嵌套
*/
@IndexField(fieldType = FieldType.NESTED, nestedClass = Faq.class)
@IndexField(fieldType = FieldType.NESTED, nestedOrObjectClass = Faq.class)
private Set<Faq> faqs;
/**
* 高亮显示的内容

View File

@ -1,6 +1,9 @@
package org.dromara.easyes.test.all;
import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch._types.GeoLocation;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import org.dromara.easyes.common.constants.BaseEsConstants;
import org.dromara.easyes.core.biz.EsPageInfo;
import org.dromara.easyes.core.biz.OrderByParam;
@ -17,8 +20,7 @@ import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.HttpAsyncResponseConsumerFactory;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.geo.GeoShapeRelation;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.geometry.Circle;
import org.elasticsearch.geometry.Point;
@ -168,7 +170,7 @@ public class AllTest {
@Order(4)
public void testUpdateBySetSearchSourceBuilder() {
LambdaEsUpdateWrapper<Document> wrapper = new LambdaEsUpdateWrapper<>();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.termQuery(FieldUtils.val(Document::getTitle) + KEYWORD_SUFFIX, "测试文档2"));
wrapper.setSearchSourceBuilder(searchSourceBuilder);
@ -535,7 +537,7 @@ public class AllTest {
@Order(6)
public void testSetSearchSourceBuilder() {
// 测试混合查询的另一种方式
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery(FieldUtils.val(Document::getCreator), "老汉"));
Optional.ofNullable(EntityInfoHelper.getEntityInfo(Document.class))
.flatMap(i -> Optional.ofNullable(i.getMaxResultWindow()))
@ -632,7 +634,7 @@ public class AllTest {
Assertions.assertEquals(10, saPageInfo.getList().size());
//获取下一页
List<Object> nextSearchAfter = saPageInfo.getNextSearchAfter();
List<FieldValue> nextSearchAfter = saPageInfo.getNextSearchAfter();
SAPageInfo<Document> next = documentMapper.searchAfterPage(lambdaEsQueryWrapper, nextSearchAfter, 10);
Assertions.assertEquals(10, next.getList().size());
}
@ -703,7 +705,7 @@ public class AllTest {
@Order(6)
public void testOrderByDistanceAsc() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
GeoPoint centerPoint = new GeoPoint(41.0, 116.0);
GeoLocation centerPoint = new GeoLocation(41.0, 116.0);
wrapper.match(Document::getCreator, "老汉")
.geoDistance(Document::getLocation, 168.8, centerPoint)
.orderByDistanceAsc(Document::getLocation, centerPoint);
@ -716,7 +718,7 @@ public class AllTest {
@Order(6)
public void testOrderByDistanceDesc() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
GeoPoint centerPoint = new GeoPoint(41.0, 116.0);
GeoLocation centerPoint = new GeoLocation(41.0, 116.0);
wrapper.match(Document::getCreator, "老汉")
.geoDistance(Document::getLocation, 168.8, centerPoint)
.orderByDistanceDesc(Document::getLocation, centerPoint);
@ -729,8 +731,8 @@ public class AllTest {
@Order(6)
public void testOrderByDistanceMulti() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
GeoPoint centerPoint = new GeoPoint(41.0, 116.0);
GeoPoint centerPoint1 = new GeoPoint(42.0, 118.0);
GeoLocation centerPoint = new GeoLocation(41.0, 116.0);
GeoLocation centerPoint1 = new GeoLocation(42.0, 118.0);
wrapper.match(Document::getCreator, "老汉")
.geoDistance(Document::getLocation, 168.8, centerPoint)
.orderByDistanceDesc(Document::getLocation, centerPoint)
@ -759,7 +761,7 @@ public class AllTest {
fieldSort(FieldUtils.getRealField(
FieldUtils.val(Document::getStarNum),
EntityInfoHelper.getEntityInfo(Document.class).getMappingColumnMap()));
fieldSortBuilder.order(SortOrder.DESC);
fieldSortBuilder.order(SortOrder.Desc);
wrapper.sort(fieldSortBuilder);
List<Document> documents = documentMapper.selectList(wrapper);
Assertions.assertEquals("22", documents.get(0).getEsId());
@ -854,8 +856,8 @@ public class AllTest {
@Order(6)
public void testGeoBoundingBox() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
GeoPoint leftTop = new GeoPoint(41.187328D, 115.498353D);
GeoPoint bottomRight = new GeoPoint(39.084509D, 117.610461D);
GeoLocation leftTop = new GeoLocation(41.187328D, 115.498353D);
GeoLocation bottomRight = new GeoLocation(39.084509D, 117.610461D);
wrapper.geoBoundingBox(Document::getLocation, leftTop, bottomRight);
List<Document> documents = documentMapper.selectList(wrapper);
Assertions.assertEquals(4, documents.size());
@ -866,12 +868,12 @@ public class AllTest {
@Order(6)
public void testGeoDistance() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
GeoPoint geoPoint = new GeoPoint(41.0, 116.0);
GeoLocation geoPoint = new GeoLocation(41.0, 116.0);
wrapper.geoDistance(Document::getLocation, 168.8, DistanceUnit.KILOMETERS, geoPoint);
GeoDistanceSortBuilder geoDistanceSortBuilder = SortBuilders.geoDistanceSort(FieldUtils.val(Document::getLocation), geoPoint)
.unit(DistanceUnit.KILOMETERS)
.geoDistance(GeoDistance.ARC)
.order(SortOrder.DESC);
.order(SortOrder.Desc);
wrapper.sort(geoDistanceSortBuilder);
List<Document> documents = documentMapper.selectList(wrapper);
@ -882,10 +884,10 @@ public class AllTest {
@Order(6)
public void testGeoPolygon() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
List<GeoPoint> geoPoints = new ArrayList<>();
GeoPoint geoPoint = new GeoPoint(40.178012, 116.577188);
GeoPoint geoPoint1 = new GeoPoint(40.169329, 116.586315);
GeoPoint geoPoint2 = new GeoPoint(40.178288, 116.591813);
List<GeoLocation> geoPoints = new ArrayList<>();
GeoLocation geoPoint = new GeoLocation(40.178012, 116.577188);
GeoLocation geoPoint1 = new GeoLocation(40.169329, 116.586315);
GeoLocation geoPoint2 = new GeoLocation(40.178288, 116.591813);
geoPoints.add(geoPoint);
geoPoints.add(geoPoint1);
geoPoints.add(geoPoint2);
@ -899,7 +901,7 @@ public class AllTest {
public void testGeoShape() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
Circle circle = new Circle(13, 14, 100);
wrapper.geoShape(Document::getGeoLocation, circle, ShapeRelation.DISJOINT);
wrapper.geoShape(Document::getGeoLocation, circle, GeoShapeRelation.DISJOINT);
List<Document> documents = documentMapper.selectList(wrapper);
Assertions.assertEquals(22, documents.size());
}
@ -928,7 +930,7 @@ public class AllTest {
String scriptCode = "cosineSimilarity(params.vector, 'vector') + 1.0";
QueryBuilder queryBuilder = QueryBuilders.scriptScoreQuery(QueryBuilders.matchAllQuery(), new Script(ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG, scriptCode, params));
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(queryBuilder);
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.setSearchSourceBuilder(searchSourceBuilder);
@ -990,7 +992,7 @@ public class AllTest {
// SQL写法
// where business_type = 1 and (state = 9 or (state = 8 and bidding_sign = 1)) or (business_type = 2 and state in (2,3))
// RestHighLevelClient写法
// ElasticsearchClient写法
List<Integer> values = Arrays.asList(2, 3);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.termQuery("business_type", 1));

View File

@ -1,5 +1,6 @@
package org.dromara.easyes.test.compare;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
import org.dromara.easyes.test.TestEasyEsApplication;
import org.dromara.easyes.test.entity.Document;
@ -7,7 +8,6 @@ import org.dromara.easyes.test.mapper.DocumentMapper;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
@ -33,12 +33,12 @@ public class CompareTest {
@Resource
private DocumentMapper documentMapper;
@Autowired
private RestHighLevelClient restHighLevelClient;
private ElasticsearchClient restHighLevelClient;
@Test
public void testCompare() {
// 需求:查询出文档标题为 "中国功夫"且作者为"老汉"的所有文档
// 传统方式, 直接用RestHighLevelClient进行查询 需要11行代码,还不包含解析代码
// 传统方式, 直接用ElasticsearchClient进行查询 需要11行代码,还不包含解析代码
String indexName = "document";
SearchRequest searchRequest = new SearchRequest(indexName);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
@ -46,7 +46,7 @@ public class CompareTest {
TermsQueryBuilder creatorTerm = QueryBuilders.termsQuery("creator", "老汉");
boolQueryBuilder.must(titleTerm);
boolQueryBuilder.must(creatorTerm);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
try {

View File

@ -1,11 +1,11 @@
package org.dromara.easyes.test.geo;
import co.elastic.clients.elasticsearch._types.GeoLocation;
import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
import org.dromara.easyes.test.TestEasyEsApplication;
import org.dromara.easyes.test.entity.Document;
import org.dromara.easyes.test.mapper.DocumentMapper;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.geo.GeoShapeRelation;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.geometry.Circle;
import org.junit.jupiter.api.Assertions;
@ -34,9 +34,9 @@ public class GeoTest {
// 查询位于下面左上点和右下点坐标构成的长方形内的所有点
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
// 左上点坐标
GeoPoint leftTop = new GeoPoint(41.187328D, 115.498353D);
GeoLocation leftTop = new GeoLocation(41.187328D, 115.498353D);
// 右下点坐标
GeoPoint bottomRight = new GeoPoint(39.084509D, 117.610461D);
GeoLocation bottomRight = new GeoLocation(39.084509D, 117.610461D);
wrapper.geoBoundingBox(Document::getLocation, leftTop, bottomRight);
// 查不在此长方形内的所有点
// wrapper.notInGeoBoundingBox(Document::getLocation, leftTop, bottomRight);
@ -48,9 +48,9 @@ public class GeoTest {
public void testGeoDistance() {
// 查询以纬度为41.0,经度为115.0为圆心,半径168.8公里内的所有点
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.geoDistance(Document::getLocation, 168.8, DistanceUnit.KILOMETERS, new GeoPoint(41.0, 116.0));
wrapper.geoDistance(Document::getLocation, 168.8, DistanceUnit.KILOMETERS, new GeoLocation(41.0, 116.0));
// 上面语法也可以写成下面这几种形式,效果是一样的,兼容不同用户习惯而已:
// wrapper.geoDistance(Document::getLocation,"1.5km",new GeoPoint(41.0,115.0));
// wrapper.geoDistance(Document::getLocation,"1.5km",new GeoLocation(41.0,115.0));
// wrapper.geoDistance(Document::getLocation, "1.5km", "41.0,115.0");
List<Document> documents = documentMapper.selectList(wrapper);
@ -61,10 +61,10 @@ public class GeoTest {
public void testGeoPolygon() {
// 查询以给定点列表构成的不规则图形内的所有点,点数至少为3个
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
List<GeoPoint> geoPoints = new ArrayList<>();
GeoPoint geoPoint = new GeoPoint(40.178012, 116.577188);
GeoPoint geoPoint1 = new GeoPoint(40.169329, 116.586315);
GeoPoint geoPoint2 = new GeoPoint(40.178288, 116.591813);
List<GeoLocation> geoPoints = new ArrayList<>();
GeoLocation geoPoint = new GeoLocation(40.178012, 116.577188);
GeoLocation geoPoint1 = new GeoLocation(40.169329, 116.586315);
GeoLocation geoPoint2 = new GeoLocation(40.178288, 116.591813);
geoPoints.add(geoPoint);
geoPoints.add(geoPoint1);
geoPoints.add(geoPoint2);
@ -98,7 +98,7 @@ public class GeoTest {
// 这里以圆形为例演示,其中x,y为圆心坐标,r为半径. 其它图形请读者自行演示,篇幅原因不一一演示了
Circle circle = new Circle(13, 14, 100);
// shapeRelation支持多种,如果不传则默认为within
wrapper.geoShape(Document::getGeoLocation, circle, ShapeRelation.INTERSECTS);
wrapper.geoShape(Document::getGeoLocation, circle, GeoShapeRelation.INTERSECTS);
List<Document> documents = documentMapper.selectList(wrapper);
System.out.println(documents);
}
@ -112,7 +112,7 @@ public class GeoTest {
centerDoc.setEsId("1");
centerDoc.setTitle("长沙站");
centerDoc.setContent("长沙站臭豆腐店");
GeoPoint center = new GeoPoint(28.194124244622135, 113.01327520919799);
GeoLocation center = new GeoLocation(28.194124244622135, 113.01327520919799);
centerDoc.setLocation(center.toString());
// 长沙火车站
@ -120,7 +120,7 @@ public class GeoTest {
document1.setEsId("2");
document1.setTitle("长沙火车站");
document1.setContent("长沙火车站臭豆腐店");
GeoPoint geoPoint1 = new GeoPoint(28.193708185086585, 113.01100069595336);
GeoLocation geoPoint1 = new GeoLocation(28.193708185086585, 113.01100069595336);
document1.setLocation(geoPoint1.toString());
// 长沙站南广场
@ -128,7 +128,7 @@ public class GeoTest {
document2.setEsId("3");
document2.setTitle("长沙站南广场");
document2.setContent("长沙站南广场臭豆腐店");
GeoPoint geoPoint2 = new GeoPoint(28.192195227668382, 113.01173025680541);
GeoLocation geoPoint2 = new GeoLocation(28.192195227668382, 113.01173025680541);
document2.setLocation(geoPoint2.toString());
@ -137,7 +137,7 @@ public class GeoTest {
document3.setEsId("4");
document3.setTitle("长沙市中医院");
document3.setContent("长沙市中医院臭豆腐店");
GeoPoint geoPoint3 = new GeoPoint(28.193367771534916, 113.00911242080687);
GeoLocation geoPoint3 = new GeoLocation(28.193367771534916, 113.00911242080687);
document3.setLocation(geoPoint3.toString());
// 阿波罗商业广场
@ -145,7 +145,7 @@ public class GeoTest {
document4.setEsId("5");
document4.setTitle("阿波罗商业广场");
document4.setContent("阿波罗商业广场臭豆腐店");
GeoPoint geoPoint4 = new GeoPoint(28.196582745180983, 113.00962740493773);
GeoLocation geoPoint4 = new GeoLocation(28.196582745180983, 113.00962740493773);
document4.setLocation(geoPoint4.toString());
// 朝阳一村
@ -153,7 +153,7 @@ public class GeoTest {
document5.setEsId("6");
document5.setTitle("朝阳一村");
document5.setContent("朝阳一村臭豆腐店");
GeoPoint geoPoint5 = new GeoPoint(28.188980122051586, 113.01177317214965);
GeoLocation geoPoint5 = new GeoLocation(28.188980122051586, 113.01177317214965);
document5.setLocation(geoPoint5.toString());
// 铭威大厦
@ -161,7 +161,7 @@ public class GeoTest {
document6.setEsId("7");
document6.setTitle("铭威大厦");
document6.setContent("铭威大厦臭豆腐店");
GeoPoint geoPoint6 = new GeoPoint(28.1905309497745, 113.01825338912963);
GeoLocation geoPoint6 = new GeoLocation(28.1905309497745, 113.01825338912963);
document6.setLocation(geoPoint6.toString());
// 袁家岭
@ -169,7 +169,7 @@ public class GeoTest {
document7.setEsId("8");
document7.setTitle("袁家岭");
document7.setContent("袁家岭豆腐店");
GeoPoint geoPoint7 = new GeoPoint(28.19450247915946, 113.00070101333617);
GeoLocation geoPoint7 = new GeoLocation(28.19450247915946, 113.00070101333617);
document7.setLocation(geoPoint7.toString());
List<Document> documents = Arrays.asList(centerDoc, document1, document2, document3, document4, document5, document6, document7);

View File

@ -1,6 +1,8 @@
package org.dromara.easyes.test.high;
import co.elastic.clients.elasticsearch._types.FieldValue;
import com.alibaba.fastjson.JSON;
import org.dromara.easyes.core.biz.EsPageInfo;
import org.dromara.easyes.core.biz.OrderByParam;
import org.dromara.easyes.core.biz.SAPageInfo;
@ -9,7 +11,6 @@ import org.dromara.easyes.core.kernel.EsWrappers;
import org.dromara.easyes.test.TestEasyEsApplication;
import org.dromara.easyes.test.entity.Document;
import org.dromara.easyes.test.mapper.DocumentMapper;
import com.alibaba.fastjson.JSON;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.sort.ScriptSortBuilder;
@ -138,7 +139,7 @@ public class HighTest {
//第一页
System.out.println(saPageInfo);
//获取下一页
List<Object> nextSearchAfter = saPageInfo.getNextSearchAfter();
List<FieldValue> nextSearchAfter = saPageInfo.getNextSearchAfter();
SAPageInfo<Document> documentSAPageInfo = documentMapper.searchAfterPage(lambdaEsQueryWrapper, nextSearchAfter, 10);
System.out.println(documentSAPageInfo);
}
@ -147,7 +148,7 @@ public class HighTest {
public void testSortByScore() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.match(Document::getContent, "技术");
wrapper.sortByScore(SortOrder.ASC);
wrapper.sortByScore(SortOrder.Asc);
List<Document> documents = documentMapper.selectList(wrapper);
System.out.println(documents);
}

View File

@ -15,12 +15,12 @@ public class IgnoreTest {
// @Resource
// DocumentMapper documentMapper;
// @Autowired
// private RestHighLevelClient client;
// private ElasticsearchClient client;
//
//
// @Test
// public void testSearch0() throws IOException {
// SearchSourceBuilder builder = new SearchSourceBuilder();
// SearchRequest.Builder builder = new SearchSourceBuilder();
// BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//
//// boolQueryBuilder.must(QueryBuilders.termQuery("overt", Boolean.TRUE));

View File

@ -1,6 +1,7 @@
package org.dromara.easyes.test.mix;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
import org.dromara.easyes.test.TestEasyEsApplication;
import org.dromara.easyes.test.entity.Document;
@ -67,8 +68,8 @@ public class MixTest {
*/
@Test
public void testMix1() {
// RestHighLevelClient原生语法
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// ElasticsearchClient原生语法
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("content", "推*").minimumShouldMatch("80%"));
// 仅利用EE查询并解析数据功能
@ -89,9 +90,9 @@ public class MixTest {
wrapper.eq(Document::getTitle, "老汉")
.match(Document::getContent, "推*");
// RestHighLevelClient原生语法
// ElasticsearchClient原生语法
Script script = new Script("doc['star_num'].value");
ScriptSortBuilder scriptSortBuilder = SortBuilders.scriptSort(script, ScriptSortBuilder.ScriptSortType.NUMBER).order(SortOrder.DESC);
ScriptSortBuilder scriptSortBuilder = SortBuilders.scriptSort(script, ScriptSortBuilder.ScriptSortType.NUMBER).order(SortOrder.Desc);
// 利用EE查询并解析数据
wrapper.sort(scriptSortBuilder);
@ -108,7 +109,7 @@ public class MixTest {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.eq(Document::getTitle, "老汉")
.match(Document::getContent, "推*");
SearchSourceBuilder searchSourceBuilder = documentMapper.getSearchSourceBuilder(wrapper);
SearchRequest.Builder searchSourceBuilder = documentMapper.getSearchSourceBuilder(wrapper);
// 追加或者设置一些SearchSourceBuilder支持但EE暂不支持的参数 不建议追加query参数,因为如果追加query参数会直接覆盖上面EE已经帮你生成好的query,以最后set的query为准
searchSourceBuilder.timeout(TimeValue.timeValueSeconds(3L));
@ -127,15 +128,15 @@ public class MixTest {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.eq(Document::getTitle, "老汉")
.match(Document::getContent, "推*");
SearchSourceBuilder searchSourceBuilder = documentMapper.getSearchSourceBuilder(wrapper);
SearchRequest.Builder searchSourceBuilder = documentMapper.getSearchSourceBuilder(wrapper);
// RestHighLevelClient原生语法
// ElasticsearchClient原生语法
AggregationBuilder aggregation = AggregationBuilders.terms("titleAgg")
.field("title");
searchSourceBuilder.aggregation(aggregation);
wrapper.setSearchSourceBuilder(searchSourceBuilder);
SearchResponse searchResponse = documentMapper.search(wrapper);
// tip: 聚合后的信息是动态的,框架无法解析,需要用户根据聚合器类型自行从桶中解析,参考RestHighLevelClient官方Aggregation解析文档
// tip: 聚合后的信息是动态的,框架无法解析,需要用户根据聚合器类型自行从桶中解析,参考ElasticsearchClient官方Aggregation解析文档
}
@ -148,7 +149,7 @@ public class MixTest {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.eq(Document::getTitle, "老汉")
.match(Document::getContent, "推*");
SearchSourceBuilder searchSourceBuilder = documentMapper.getSearchSourceBuilder(wrapper);
SearchRequest.Builder searchSourceBuilder = documentMapper.getSearchSourceBuilder(wrapper);
// 用户又想在上面的基础上,再追加一些个性化的查询参数进去 但实际上此时执行查询时,查询条件仅仅是最后设置的title=隔壁老王,前面的老汉推*会被覆盖
searchSourceBuilder.query(QueryBuilders.matchQuery("title", "隔壁老王"));
@ -169,8 +170,8 @@ public class MixTest {
.match(Document::getContent, "推*");
// SearchSourceBuilder的构造是自己new出来的,不是通过mapper.getSearchSourceBuilder(wrapper)构造 相当于脱裤子放P,那么上面的查询条件老汉推*自然不会生效
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.minScore(10.5f);
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.minScore(10.5);
wrapper.setSearchSourceBuilder(searchSourceBuilder);
List<Document> documents = documentMapper.selectList(wrapper);
System.out.println(documents);

View File

@ -1,12 +1,13 @@
package org.dromara.easyes.test.performance;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.StopWatch;
import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
import org.dromara.easyes.test.TestEasyEsApplication;
import org.dromara.easyes.test.entity.Document;
import org.dromara.easyes.test.mapper.DocumentMapper;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.StopWatch;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
@ -14,7 +15,6 @@ import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
@ -50,13 +50,13 @@ public class PerformanceTest {
private DocumentMapper documentMapper;
@Resource
private RestHighLevelClient client;
private ElasticsearchClient client;
@Test
public void testSelectByEE() {
StopWatch stopwatch = StopWatch.createStarted();
// 测试时需将Document实体上加上注解@TableName("索引名")
// 将查询索引指定为和通过RestHighLevelClient查询时一样的索引名称
// 将查询索引指定为和通过ElasticsearchClient查询时一样的索引名称
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.match(Document::getTitle, "茶叶")
.match(Document::getContent, "茶叶");
@ -67,14 +67,14 @@ public class PerformanceTest {
stopwatch.stop();
log.info("本次查询从:{}条数据中共命中:{}条数据,耗时总计:{}毫秒", count, documents.size(), stopwatch.getTime(TimeUnit.MILLISECONDS));
// 本次查询从:5135条数据中共命中:15条数据,耗时总计:434毫秒 多次测试均值维持440毫秒左右
// 对比下面直接使用RestHighLevelClient查询,查询仅慢10毫秒左右, 除去注释,节省了5倍代码,且查询越复杂,节省越多
// 对比下面直接使用ElasticsearchClient查询,查询仅慢10毫秒左右, 除去注释,节省了5倍代码,且查询越复杂,节省越多
}
@Test
public void testSelectByRestHighLevelClient() {
public void testSelectByElasticsearchClient() {
// 构建查询条件
StopWatch stopwatch = StopWatch.createStarted();
SearchSourceBuilder builder = new SearchSourceBuilder();
SearchRequest.Builder builder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.matchQuery("title", "茶叶"));
boolQueryBuilder.must(QueryBuilders.matchQuery("content", "茶叶"));
@ -124,11 +124,11 @@ public class PerformanceTest {
stopwatch.stop();
log.info("本次共插入:{}条数据,耗时:{}毫秒", documents.size(), stopwatch.getTime(TimeUnit.MILLISECONDS));
// 本次共插入:100条数据,耗时:343毫秒 多次测试稳定在340毫秒左右
// 对比下面直接使用RestHighLevelClient 并无明显差异
// 对比下面直接使用ElasticsearchClient 并无明显差异
}
@Test
public void testInsertByRestHighLevelClient() {
public void testInsertByElasticsearchClient() {
StopWatch stopWatch = StopWatch.createStarted();
BulkRequest bulkRequest = new BulkRequest();
int total = 100;
@ -161,11 +161,11 @@ public class PerformanceTest {
stopWatch.stop();
log.info("耗时:{}毫秒", stopWatch.getTime(TimeUnit.MILLISECONDS));
// 多次测试平均耗时:330毫秒
// 对比下面直接使用RestHighLevelClient 并无明显差异
// 对比下面直接使用ElasticsearchClient 并无明显差异
}
@Test
public void testUpdateByRestHighLevelClient() {
public void testUpdateByElasticsearchClient() {
StopWatch stopWatch = StopWatch.createStarted();
Document document = new Document();
document.setTitle("哈哈哈");
@ -189,11 +189,11 @@ public class PerformanceTest {
stopWatch.stop();
log.info("耗时:{}毫秒", stopWatch.getTime(TimeUnit.MILLISECONDS));
// 多次测试平均耗时耗时:131毫秒
// 对比下面直接使用RestHighLevelClient 并无明显差异
// 对比下面直接使用ElasticsearchClient 并无明显差异
}
@Test
public void testDeleteByRestHighLevelClient() {
public void testDeleteByElasticsearchClient() {
StopWatch stopWatch = StopWatch.createStarted();
DeleteRequest deleteRequest = new DeleteRequest("document", "RWF0SH8B0E2Rzy0qcFBz");
try {

View File

@ -1,6 +1,7 @@
package org.dromara.easyes.test.select;
import co.elastic.clients.elasticsearch._types.FieldValue;
import org.dromara.easyes.core.biz.SAPageInfo;
import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
import org.dromara.easyes.core.kernel.EsWrappers;
@ -62,7 +63,7 @@ public class SearchAfterTest {
System.out.println(saPageInfo);
// 第二页,从saPageInfo中把上一次的nextSearchAfter回传给后端
List<Object> nextSearchAfter = saPageInfo.getNextSearchAfter();
List<FieldValue> nextSearchAfter = saPageInfo.getNextSearchAfter();
SAPageInfo<Document> saPageInfo1 = documentMapper.searchAfterPage(wrapper, nextSearchAfter, 10);
System.out.println(saPageInfo1);
}

View File

@ -1,6 +1,7 @@
package org.dromara.easyes.test.vector;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
import org.dromara.easyes.test.TestEasyEsApplication;
import org.dromara.easyes.test.entity.Document;
@ -59,7 +60,7 @@ public class VectorTest {
String scriptCode = "cosineSimilarity(params.vector, 'vector') + 1.0";
QueryBuilder queryBuilder = QueryBuilders.scriptScoreQuery(QueryBuilders.matchAllQuery(), new Script(ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG, scriptCode, params));
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(queryBuilder);
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.setSearchSourceBuilder(searchSourceBuilder);