mirror of
https://gitee.com/dromara/easy-es.git
synced 2025-12-06 09:09:13 +08:00
feat: 主键字段也可以自定义es中名称
This commit is contained in:
parent
4f193f0f24
commit
42aef5f199
@ -90,7 +90,7 @@ Easy-Es是一款简化ElasticSearch搜索引擎操作的开源框架,全自动
|
||||
TermsQueryBuilder creatorTerm = QueryBuilders.termsQuery("creator", "码保国");
|
||||
boolQueryBuilder.must(titleTerm);
|
||||
boolQueryBuilder.must(creatorTerm);
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchRequest.Builder();
|
||||
searchSourceBuilder.query(boolQueryBuilder);
|
||||
searchRequest.source(searchSourceBuilder);
|
||||
try {
|
||||
|
||||
@ -77,7 +77,7 @@ String indexName = "document";
|
||||
TermsQueryBuilder creatorTerm = QueryBuilders.termsQuery("creator", "Guy");
|
||||
boolQueryBuilder.must(titleTerm);
|
||||
boolQueryBuilder.must(creatorTerm);
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchRequest.Builder();
|
||||
searchSourceBuilder.query(boolQueryBuilder);
|
||||
searchRequest.source(searchSourceBuilder);
|
||||
try {
|
||||
|
||||
@ -15,6 +15,14 @@ import java.lang.annotation.Target;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface IndexId {
|
||||
|
||||
/**
|
||||
* 自定义字段在es中的名称
|
||||
*
|
||||
* @return 字段在es中的名称
|
||||
*/
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*
|
||||
|
||||
@ -15,6 +15,14 @@ public class JoinField {
|
||||
*/
|
||||
private String parent;
|
||||
|
||||
public JoinField() {
|
||||
}
|
||||
|
||||
public JoinField(String name, String parent) {
|
||||
this.name = name;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
package org.dromara.easyes.common.join;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Setter
|
||||
public class BaseJoin {
|
||||
|
||||
public Map<String, Map<String, String>> joinFiled;
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, Map<String, String>> getJoinField() {
|
||||
return joinFiled;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加join字段信息. json示例如下:
|
||||
* "fieldName": {
|
||||
* "name": xxx,
|
||||
* "parentId": xxx
|
||||
* }
|
||||
*
|
||||
* @param fieldName join字段名称(json中的key)
|
||||
* @param name 名称
|
||||
* @param parentId 父id
|
||||
*/
|
||||
public void addJoinField(String fieldName, String name, String parentId) {
|
||||
joinFiled = new HashMap<>() {{
|
||||
put(fieldName, new HashMap<>() {{
|
||||
put("name", name);
|
||||
if (parentId != null) {
|
||||
put("parent", parentId);
|
||||
}
|
||||
}});
|
||||
}};
|
||||
}
|
||||
}
|
||||
@ -119,7 +119,7 @@ public class EsClientUtils {
|
||||
return requestConfigBuilder;
|
||||
});
|
||||
|
||||
return new ElasticsearchClient(new RestClientTransport(builder.build(), new JacksonJsonpMapper(JsonUtils.base())));
|
||||
return new ElasticsearchClient(new RestClientTransport(builder.build(), new JacksonJsonpMapper(JsonUtils.OM_DEFAULT)));
|
||||
}
|
||||
|
||||
public ElasticsearchClient getClient(String clientId) {
|
||||
|
||||
@ -26,10 +26,8 @@ public class JsonUtils {
|
||||
|
||||
/**
|
||||
* 默认jackson配置
|
||||
* 不打印类信息
|
||||
* 时间序列化为字符串
|
||||
*/
|
||||
public static final ObjectMapper OM_DEFAULT = base();
|
||||
public static ObjectMapper OM_DEFAULT = base();
|
||||
private static final DefaultPrettyPrinter DEFAULT_PRETTY_PRINTER = new DefaultPrettyPrinter();
|
||||
|
||||
public static JsonMapper base() {
|
||||
|
||||
@ -25,14 +25,20 @@ import java.util.Map;
|
||||
*/
|
||||
public class JacksonCache {
|
||||
|
||||
public static JsonInclude.Value NON_NULL = JsonInclude.Value.construct(JsonInclude.Include.NON_NULL, null);
|
||||
public static JsonInclude.Value NON_EMPTY = JsonInclude.Value.construct(JsonInclude.Include.NON_EMPTY, null);
|
||||
|
||||
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());
|
||||
config.includeMap.put(e.getKeyProperty(), NON_NULL);
|
||||
config.includeMap.put(getterMethod(clz, e.getKeyProperty()), NON_NULL);
|
||||
JacksonCustomConfig.jacksonConfigMap.put(clz, config);
|
||||
}
|
||||
|
||||
@ -95,14 +101,12 @@ public class JacksonCache {
|
||||
}
|
||||
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);
|
||||
config.includeMap.put(getterName, NON_NULL);
|
||||
config.includeMap.put(f.getColumn(), NON_NULL);
|
||||
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);
|
||||
config.includeMap.put(getterName, NON_EMPTY);
|
||||
config.includeMap.put(f.getColumn(), NON_EMPTY);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@ -37,6 +37,7 @@ import org.dromara.easyes.annotation.rely.RefreshPolicy;
|
||||
import org.dromara.easyes.common.constants.BaseEsConstants;
|
||||
import org.dromara.easyes.common.enums.EsQueryTypeEnum;
|
||||
import org.dromara.easyes.common.enums.OrderTypeEnum;
|
||||
import org.dromara.easyes.common.join.BaseJoin;
|
||||
import org.dromara.easyes.common.property.GlobalConfig;
|
||||
import org.dromara.easyes.common.utils.*;
|
||||
import org.dromara.easyes.core.biz.*;
|
||||
@ -198,12 +199,54 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
return getSearchResponse(wrapper, null, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchResponse<T> search(SearchRequest searchRequest, TransportOptions requestOptions) throws IOException {
|
||||
printDSL(searchRequest);
|
||||
SearchResponse<T> response = client.withTransportOptions(requestOptions).search(searchRequest, entityClass);
|
||||
printResponseErrors(response);
|
||||
return response;
|
||||
/**
|
||||
* 根据全局配置决定是否控制台打印DSL语句
|
||||
*
|
||||
* @param request es请求参数
|
||||
* @param client es客户端
|
||||
*/
|
||||
public static void printDSL(RequestBase request, ElasticsearchClient client) {
|
||||
if (request == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String method = "";
|
||||
String requestUrl = "";
|
||||
String fullUrl = "";
|
||||
String dsl = "";
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
Endpoint<RequestBase, ?, ?> endpoint = (Endpoint<RequestBase, ?, ?>) request.getClass()
|
||||
.getDeclaredField("_ENDPOINT").get(null);
|
||||
method = endpoint.method(request);
|
||||
requestUrl = endpoint.requestUrl(request);
|
||||
|
||||
|
||||
Map<String, String> params = endpoint.queryParameters(request);
|
||||
StringBuilder fullUrlSb = new StringBuilder(requestUrl);
|
||||
String delim = "?";
|
||||
for (Map.Entry<String, String> param : params.entrySet()) {
|
||||
fullUrlSb.append(delim);
|
||||
delim = "&";
|
||||
fullUrlSb.append(param.getKey()).append("=").append(URLEncoder.encode(param.getValue(), StandardCharsets.UTF_8));
|
||||
}
|
||||
fullUrl = fullUrlSb.toString();
|
||||
|
||||
if (request instanceof JsonpSerializable) {
|
||||
dsl = JsonpUtils.toJsonString(request, client._transport().jsonpMapper());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// No endpoint, ignore
|
||||
}
|
||||
|
||||
GlobalConfig globalConfig = GlobalConfigCache.getGlobalConfig();
|
||||
if (globalConfig.isPrintDsl()) {
|
||||
String prefix = globalConfig.isIKunMode() ? I_KUN_PREFIX : DSL_PREFIX;
|
||||
LogUtils.info(prefix +
|
||||
"\n" + method + " " + fullUrl +
|
||||
"\n" + dsl
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -285,32 +328,11 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long selectCount(Wrapper<T> wrapper, boolean distinct) {
|
||||
if (distinct) {
|
||||
// 去重, 总数来源于桶, 只查id列,节省内存 拷贝是防止追加的只查id列影响到count后的其它查询
|
||||
Wrapper<T> clone = wrapper.clone();
|
||||
clone.include = new String[]{DEFAULT_ES_ID_NAME};
|
||||
SearchResponse<T> response = getSearchResponse(clone);
|
||||
return parseCount(response, Objects.nonNull(clone.distinctField));
|
||||
} else {
|
||||
// 不去重,直接count获取,效率更高
|
||||
BoolQuery query = getBoolQuery(wrapper);
|
||||
|
||||
CountRequest req = CountRequest.of(a -> a
|
||||
.index(WrapperProcessor.getIndexName(entityClass, wrapper.indexNames))
|
||||
.routing(wrapper.routing)
|
||||
.preference(wrapper.preference)
|
||||
.query(query._toQuery())
|
||||
);
|
||||
CountResponse rsp;
|
||||
try {
|
||||
printDSL(req);
|
||||
rsp = client.withTransportOptions(getTransportOptions()).count(req);
|
||||
} catch (IOException e) {
|
||||
throw ExceptionUtils.eee("selectCount exception", e);
|
||||
}
|
||||
return rsp.count();
|
||||
}
|
||||
public SearchResponse<T> search(SearchRequest searchRequest, TransportOptions requestOptions) throws IOException {
|
||||
printDSL(searchRequest, client);
|
||||
SearchResponse<T> response = client.withTransportOptions(requestOptions).search(searchRequest, entityClass);
|
||||
printResponseErrors(response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -445,24 +467,31 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer delete(Wrapper<T> wrapper) {
|
||||
EntityInfo entityInfo = EntityInfoHelper.getEntityInfo(entityClass);
|
||||
public Long selectCount(Wrapper<T> wrapper, boolean distinct) {
|
||||
if (distinct) {
|
||||
// 去重, 总数来源于桶, 只查id列,节省内存 拷贝是防止追加的只查id列影响到count后的其它查询
|
||||
Wrapper<T> clone = wrapper.clone();
|
||||
clone.include = new String[]{EntityInfoHelper.getEntityInfo(entityClass).getKeyProperty()};
|
||||
SearchResponse<T> response = getSearchResponse(clone);
|
||||
return parseCount(response, Objects.nonNull(clone.distinctField));
|
||||
} else {
|
||||
// 不去重,直接count获取,效率更高
|
||||
BoolQuery query = getBoolQuery(wrapper);
|
||||
|
||||
DeleteByQueryRequest request = DeleteByQueryRequest.of(a -> a
|
||||
CountRequest req = CountRequest.of(a -> a
|
||||
.index(WrapperProcessor.getIndexName(entityClass, wrapper.indexNames))
|
||||
.query(getBoolQuery(wrapper)._toQuery())
|
||||
.routing(wrapper.routing)
|
||||
.refresh(Refresh.True.equals(getRefreshPolicy()))
|
||||
.scrollSize(entityInfo == null ? null : entityInfo.getMaxResultWindow())
|
||||
.preference(wrapper.preference)
|
||||
.query(query._toQuery())
|
||||
);
|
||||
|
||||
printDSL(request);
|
||||
CountResponse rsp;
|
||||
try {
|
||||
DeleteByQueryResponse bulkResponse = client.deleteByQuery(request);
|
||||
// 单次删除通常不会超过21亿, 这里为了兼容老API设计,仍转为int 2.0版本将调整为long
|
||||
return bulkResponse.deleted() == null ? BaseEsConstants.ZERO : bulkResponse.deleted().intValue();
|
||||
printDSL(req, client);
|
||||
rsp = client.withTransportOptions(getTransportOptions()).count(req);
|
||||
} catch (IOException e) {
|
||||
throw ExceptionUtils.eee("delete error, dsl:%s", e);
|
||||
throw ExceptionUtils.eee("selectCount exception", e);
|
||||
}
|
||||
return rsp.count();
|
||||
}
|
||||
}
|
||||
|
||||
@ -715,35 +744,25 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行插入单条数据
|
||||
*
|
||||
* @param entity 插入对象
|
||||
* @param routing 路由
|
||||
* @param parentId 父id
|
||||
* @param indexName 索引名
|
||||
* @return 成功条数
|
||||
*/
|
||||
private Integer doInsert(T entity, String routing, String parentId, String indexName) {
|
||||
// 构建请求入参
|
||||
IndexRequest.Builder<T> indexRequest = buildIndexRequest(entity, routing, parentId, indexName);
|
||||
@Override
|
||||
public Integer delete(Wrapper<T> wrapper) {
|
||||
EntityInfo entityInfo = EntityInfoHelper.getEntityInfo(entityClass);
|
||||
|
||||
Optional.ofNullable(routing).ifPresent(indexRequest::routing);
|
||||
indexRequest.refresh(getRefreshPolicy());
|
||||
DeleteByQueryRequest request = DeleteByQueryRequest.of(a -> a
|
||||
.index(WrapperProcessor.getIndexName(entityClass, wrapper.indexNames))
|
||||
.query(getBoolQuery(wrapper)._toQuery())
|
||||
.routing(wrapper.routing)
|
||||
.refresh(Refresh.True.equals(getRefreshPolicy()))
|
||||
.scrollSize(entityInfo == null ? null : entityInfo.getMaxResultWindow())
|
||||
);
|
||||
|
||||
printDSL(request, client);
|
||||
try {
|
||||
IndexResponse indexResponse = client.withTransportOptions(getTransportOptions()).index(indexRequest.build());
|
||||
if (Objects.equals(indexResponse.result(), Result.Created)) {
|
||||
setId(entity, indexResponse.id());
|
||||
return BaseEsConstants.ONE;
|
||||
} else if (Objects.equals(indexResponse.result(), Result.Updated)) {
|
||||
// 该id已存在,数据被更新的情况
|
||||
return BaseEsConstants.ZERO;
|
||||
} else {
|
||||
throw ExceptionUtils.eee("insert failed, result:%s entity:%s", indexResponse.result(), entity);
|
||||
}
|
||||
DeleteByQueryResponse bulkResponse = client.deleteByQuery(request);
|
||||
// 单次删除通常不会超过21亿, 这里为了兼容老API设计,仍转为int 2.0版本将调整为long
|
||||
return bulkResponse.deleted() == null ? BaseEsConstants.ZERO : bulkResponse.deleted().intValue();
|
||||
} catch (IOException e) {
|
||||
throw ExceptionUtils.eee("insert entity:%s exception", e, entity.toString());
|
||||
throw ExceptionUtils.eee("delete error, dsl:%s", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -788,6 +807,36 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
return doBulkRequest(bulkRequest, getTransportOptions(), entityList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行插入单条数据
|
||||
*
|
||||
* @param entity 插入对象
|
||||
* @param routing 路由
|
||||
* @param parentId 父id
|
||||
* @param indexName 索引名
|
||||
* @return 成功条数
|
||||
*/
|
||||
private Integer doInsert(T entity, String routing, String parentId, String indexName) {
|
||||
// 构建请求入参
|
||||
IndexRequest<T> indexRequest = buildIndexRequest(entity, routing, parentId, indexName)
|
||||
.refresh(getRefreshPolicy()).build();
|
||||
|
||||
printDSL(indexRequest, client);
|
||||
try {
|
||||
IndexResponse indexResponse = client.withTransportOptions(getTransportOptions()).index(indexRequest);
|
||||
if (Objects.equals(indexResponse.result(), Result.Created)) {
|
||||
setId(entity, indexResponse.id());
|
||||
return BaseEsConstants.ONE;
|
||||
} else if (Objects.equals(indexResponse.result(), Result.Updated)) {
|
||||
// 该id已存在,数据被更新的情况
|
||||
return BaseEsConstants.ZERO;
|
||||
} else {
|
||||
throw ExceptionUtils.eee("insert failed, result:%s entity:%s", indexResponse.result(), entity);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw ExceptionUtils.eee("insert entity:%s exception", e, entity.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行根据id删除指定数据
|
||||
@ -803,7 +852,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
.refresh(getRefreshPolicy())
|
||||
.build();
|
||||
|
||||
printDSL(request);
|
||||
printDSL(request, client);
|
||||
try {
|
||||
DeleteResponse deleteResponse = client.withTransportOptions(getTransportOptions()).delete(request);
|
||||
if (Objects.equals(deleteResponse.result(), Result.Deleted)) {
|
||||
@ -815,7 +864,6 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
return BaseEsConstants.ZERO;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 执行根据id批量删除
|
||||
*
|
||||
@ -847,7 +895,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
.operations(operations)
|
||||
);
|
||||
|
||||
printDSL(request);
|
||||
printDSL(request, client);
|
||||
return doBulkRequest(request, getTransportOptions());
|
||||
}
|
||||
|
||||
@ -867,7 +915,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
.refresh(getRefreshPolicy())
|
||||
.build();
|
||||
|
||||
printDSL(updateRequest);
|
||||
printDSL(updateRequest, client);
|
||||
|
||||
// 执行更新
|
||||
try {
|
||||
@ -882,43 +930,6 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
return BaseEsConstants.ZERO;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行根据id批量更新
|
||||
*
|
||||
* @param entityList 更新数据列表
|
||||
* @param routing 路由
|
||||
* @param indexName 索引名
|
||||
* @return 总成功条数
|
||||
*/
|
||||
private Integer doUpdateBatchByIds(Collection<T> entityList, String routing, String indexName) {
|
||||
// 封装批量请求参数
|
||||
List<BulkOperation> operations = new ArrayList<>();
|
||||
entityList.forEach(e -> {
|
||||
String idValue = getIdValue(e);
|
||||
UpdateRequest<T, T> updateRequest = buildUpdateRequest(e, idValue, indexName).build();
|
||||
BulkOperation operation = BulkOperation.of(a ->
|
||||
a.update(b -> b
|
||||
.id(updateRequest.id())
|
||||
.ifPrimaryTerm(updateRequest.ifPrimaryTerm())
|
||||
.ifSeqNo(updateRequest.ifSeqNo())
|
||||
.index(updateRequest.index())
|
||||
.requireAlias(updateRequest.requireAlias())
|
||||
.retryOnConflict(updateRequest.retryOnConflict())
|
||||
.routing(updateRequest.routing())
|
||||
));
|
||||
operations.add(operation);
|
||||
});
|
||||
|
||||
BulkRequest request = BulkRequest.of(a -> a
|
||||
.routing(routing)
|
||||
.refresh(getRefreshPolicy())
|
||||
.operations(operations)
|
||||
);
|
||||
|
||||
printDSL(request);
|
||||
return doBulkRequest(request, getTransportOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行根据条件更新
|
||||
*
|
||||
@ -957,6 +968,42 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
return doBulkRequest(bulkRequest, getTransportOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行根据id批量更新
|
||||
*
|
||||
* @param entityList 更新数据列表
|
||||
* @param routing 路由
|
||||
* @param indexName 索引名
|
||||
* @return 总成功条数
|
||||
*/
|
||||
private Integer doUpdateBatchByIds(Collection<T> entityList, String routing, String indexName) {
|
||||
// 封装批量请求参数
|
||||
List<BulkOperation> operations = new ArrayList<>();
|
||||
entityList.forEach(e -> {
|
||||
String idValue = getIdValue(e);
|
||||
UpdateRequest<T, T> updateRequest = buildUpdateRequest(e, idValue, indexName).build();
|
||||
BulkOperation operation = BulkOperation.of(a ->
|
||||
a.update(b -> b
|
||||
.id(updateRequest.id())
|
||||
.ifPrimaryTerm(updateRequest.ifPrimaryTerm())
|
||||
.ifSeqNo(updateRequest.ifSeqNo())
|
||||
.index(updateRequest.index())
|
||||
.requireAlias(updateRequest.requireAlias())
|
||||
.retryOnConflict(updateRequest.retryOnConflict())
|
||||
.routing(updateRequest.routing())
|
||||
));
|
||||
operations.add(operation);
|
||||
});
|
||||
|
||||
BulkRequest request = BulkRequest.of(a -> a
|
||||
.routing(routing)
|
||||
.refresh(getRefreshPolicy())
|
||||
.operations(operations)
|
||||
);
|
||||
|
||||
printDSL(request, client);
|
||||
return doBulkRequest(request, getTransportOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行根据id批量查询
|
||||
@ -974,8 +1021,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
.routing(routing)
|
||||
.query(QueryBuilders.ids().values(ids).build()._toQuery())
|
||||
.size(idList.size())
|
||||
.build()
|
||||
;
|
||||
.build();
|
||||
|
||||
// 请求es获取数据
|
||||
List<Hit<T>> searchHits = getSearchHits(searchRequest);
|
||||
@ -1003,8 +1049,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
.index(indexName)
|
||||
.routing(routing)
|
||||
.query(QueryBuilders.ids().values(List.of(id.toString())).build()._toQuery())
|
||||
.build()
|
||||
;
|
||||
.build();
|
||||
// 请求es获取数据
|
||||
List<Hit<T>> searchHits = getSearchHits(searchRequest);
|
||||
if (CollectionUtils.isEmpty(searchHits)) {
|
||||
@ -1016,6 +1061,22 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 生成DelRequest请求参数
|
||||
*
|
||||
* @param id id
|
||||
* @param indexName 索引名
|
||||
* @return DelRequest
|
||||
*/
|
||||
private DeleteRequest.Builder generateDelRequest(Serializable id, String indexName) {
|
||||
if (Objects.isNull(id) || StringUtils.isEmpty(id.toString())) {
|
||||
throw ExceptionUtils.eee("id must not be null or empty");
|
||||
}
|
||||
return new DeleteRequest.Builder()
|
||||
.id(id.toString())
|
||||
.index(indexName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取es查询结果返回体
|
||||
*
|
||||
@ -1039,7 +1100,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
if (needSearchAfter && searchRequest.sort().isEmpty()) {
|
||||
throw ExceptionUtils.eee("searchAfter必须要进行排序");
|
||||
}
|
||||
printDSL(searchRequest);
|
||||
printDSL(searchRequest, client);
|
||||
|
||||
try {
|
||||
// 执行查询
|
||||
@ -1051,23 +1112,6 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 生成DelRequest请求参数
|
||||
*
|
||||
* @param id id
|
||||
* @param indexName 索引名
|
||||
* @return DelRequest
|
||||
*/
|
||||
private DeleteRequest.Builder generateDelRequest(Serializable id, String indexName) {
|
||||
if (Objects.isNull(id) || StringUtils.isEmpty(id.toString())) {
|
||||
throw ExceptionUtils.eee("id must not be null or empty");
|
||||
}
|
||||
return new DeleteRequest.Builder()
|
||||
.id(id.toString())
|
||||
.index(indexName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询数据列表
|
||||
*
|
||||
@ -1086,11 +1130,15 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
builder.query(wrapper.searchBuilder.build().query());
|
||||
} else {
|
||||
EntityInfo entityInfo = EntityInfoHelper.getEntityInfo(entityClass);
|
||||
int size = entityInfo == null ? GlobalConfigCache.getGlobalConfig().getDbConfig().getBatchUpdateThreshold()
|
||||
: entityInfo.getMaxResultWindow().intValue();
|
||||
if (entityInfo == null) {
|
||||
throw ExceptionUtils.eee("entityClass must not be null or empty");
|
||||
}
|
||||
Integer batchUpdateThreshold = GlobalConfigCache.getGlobalConfig().getDbConfig().getBatchUpdateThreshold();
|
||||
int maxResultWindow = entityInfo.getMaxResultWindow().intValue();
|
||||
int size = batchUpdateThreshold > maxResultWindow ? maxResultWindow : batchUpdateThreshold;
|
||||
builder
|
||||
// 只查id列,节省内存
|
||||
.source(a -> a.filter(b -> b.includes(DEFAULT_ES_ID_NAME)))
|
||||
.source(a -> a.filter(b -> b.includes(entityInfo.getKeyProperty())))
|
||||
.trackTotalHits(a -> a.enabled(true))
|
||||
.query(WrapperProcessor.initBoolQueryBuilder(wrapper.paramQueue, entityClass).build()._toQuery())
|
||||
.size(size)
|
||||
@ -1098,7 +1146,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
}
|
||||
|
||||
SearchRequest searchRequest = builder.build();
|
||||
printDSL(searchRequest);
|
||||
printDSL(searchRequest, client);
|
||||
try {
|
||||
// 查询数据明细
|
||||
SearchResponse<T> response = client.withTransportOptions(getTransportOptions()).search(searchRequest, entityClass);
|
||||
@ -1112,32 +1160,6 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建创建数据请求参数
|
||||
*
|
||||
* @param entity 实体
|
||||
* @param routing 路由
|
||||
* @param parentId 父id
|
||||
* @param indexName 索引名
|
||||
* @return es请求参数
|
||||
*/
|
||||
private IndexRequest.Builder<T> buildIndexRequest(T entity, String routing, String parentId, String indexName) {
|
||||
IndexRequest.Builder<T> indexRequest = new IndexRequest.Builder<T>()
|
||||
.index(indexName)
|
||||
.document(entity);
|
||||
|
||||
// id预处理,除下述情况,其它情况使用es默认的id
|
||||
EntityInfo entityInfo = EntityInfoHelper.getEntityInfo(entityClass);
|
||||
|
||||
if (IdType.UUID.equals(entityInfo.getIdType())) {
|
||||
indexRequest.id(UUID.randomUUID().toString());
|
||||
} else if (IdType.CUSTOMIZE.equals(entityInfo.getIdType())) {
|
||||
indexRequest.id(getIdValue(entity));
|
||||
}
|
||||
|
||||
return indexRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建更新数据请求参数
|
||||
*
|
||||
@ -1417,6 +1439,41 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
return search(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建创建数据请求参数
|
||||
*
|
||||
* @param entity 实体
|
||||
* @param routing 路由
|
||||
* @param parentId 父id
|
||||
* @param indexName 索引名
|
||||
* @return es请求参数
|
||||
*/
|
||||
private IndexRequest.Builder<T> buildIndexRequest(T entity, String routing, String parentId, String indexName) {
|
||||
IndexRequest.Builder<T> indexRequest = new IndexRequest.Builder<T>()
|
||||
.routing(routing)
|
||||
.index(indexName)
|
||||
.document(entity);
|
||||
|
||||
// id预处理,除下述情况,其它情况使用es默认的id
|
||||
EntityInfo entityInfo = EntityInfoHelper.getEntityInfo(entityClass);
|
||||
|
||||
if (IdType.UUID.equals(entityInfo.getIdType())) {
|
||||
indexRequest.id(UUID.randomUUID().toString());
|
||||
} else if (IdType.CUSTOMIZE.equals(entityInfo.getIdType())) {
|
||||
indexRequest.id(getIdValue(entity));
|
||||
}
|
||||
|
||||
// 针对父子类型-追加joinField信息
|
||||
if (StringUtils.isNotBlank(entityInfo.getJoinAlias())) {
|
||||
if (!(entity instanceof BaseJoin b)) {
|
||||
throw ExceptionUtils.eee("实体类" + entityClass.getName() + "必须继承BaseJoin实现Join功能");
|
||||
}
|
||||
b.addJoinField(entityInfo.getJoinFieldName(), entityInfo.getJoinAlias(), entityInfo.isChild() ? parentId : null);
|
||||
}
|
||||
|
||||
return indexRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从es中请求获取searchHit数组
|
||||
*
|
||||
@ -1424,7 +1481,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
* @return searchHit数组
|
||||
*/
|
||||
private List<Hit<T>> getSearchHits(SearchRequest searchRequest) {
|
||||
printDSL(searchRequest);
|
||||
printDSL(searchRequest, client);
|
||||
SearchResponse<T> response;
|
||||
try {
|
||||
response = client.withTransportOptions(getTransportOptions()).search(searchRequest, entityClass);
|
||||
@ -1435,29 +1492,6 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
return parseSearchHitArray(response);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 从es中请求获取searchHit数组
|
||||
*
|
||||
* @param wrapper 参数包装类
|
||||
* @return searchHit数组
|
||||
*/
|
||||
private List<Hit<T>> getSearchHits(Wrapper<T> wrapper) {
|
||||
// 用户在wrapper中指定的混合查询条件优先级最高
|
||||
SearchRequest searchRequest = Optional.ofNullable(wrapper.searchBuilder)
|
||||
.orElse(WrapperProcessor.buildSearchSourceBuilder(wrapper, entityClass)).build();
|
||||
|
||||
printDSL(searchRequest);
|
||||
SearchResponse<T> response;
|
||||
try {
|
||||
response = client.withTransportOptions(getTransportOptions()).search(searchRequest, entityClass);
|
||||
} catch (IOException e) {
|
||||
throw ExceptionUtils.eee("getSearchHitArray IOException, searchRequest:%s", e, searchRequest.toString());
|
||||
}
|
||||
printResponseErrors(response);
|
||||
return parseSearchHitArray(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建更新文档的json
|
||||
*
|
||||
@ -1501,31 +1535,25 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行bulk创建请求,并返回成功个数,封装id
|
||||
* 从es中请求获取searchHit数组
|
||||
*
|
||||
* @param bulkRequest 批量请求参数
|
||||
* @param requestOptions 类型
|
||||
* @param entityList 实体列表
|
||||
* @return 成功个数
|
||||
* @param wrapper 参数包装类
|
||||
* @return searchHit数组
|
||||
*/
|
||||
private int doBulkRequest(BulkRequest bulkRequest, TransportOptions requestOptions, Collection<T> entityList) {
|
||||
int totalSuccess = 0;
|
||||
try {
|
||||
BulkResponse bulkResponse = client.withTransportOptions(requestOptions).bulk(bulkRequest);
|
||||
if (bulkResponse.errors()) {
|
||||
LogUtils.error(bulkResponse.toString());
|
||||
}
|
||||
private List<Hit<T>> getSearchHits(Wrapper<T> wrapper) {
|
||||
// 用户在wrapper中指定的混合查询条件优先级最高
|
||||
SearchRequest searchRequest = Optional.ofNullable(wrapper.searchBuilder)
|
||||
.orElse(WrapperProcessor.buildSearchSourceBuilder(wrapper, entityClass)).build();
|
||||
|
||||
for (BulkResponseItem item : bulkResponse.items()) {
|
||||
if (Objects.equals(item.status(), 200)) {
|
||||
setId(entityList.toArray()[totalSuccess], item.id());
|
||||
totalSuccess++;
|
||||
}
|
||||
}
|
||||
printDSL(searchRequest, client);
|
||||
SearchResponse<T> response;
|
||||
try {
|
||||
response = client.withTransportOptions(getTransportOptions()).search(searchRequest, entityClass);
|
||||
} catch (IOException e) {
|
||||
throw ExceptionUtils.eee("bulkRequest exception", e);
|
||||
throw ExceptionUtils.eee("getSearchHitArray IOException, searchRequest:%s", e, searchRequest.toString());
|
||||
}
|
||||
return totalSuccess;
|
||||
printResponseErrors(response);
|
||||
return parseSearchHitArray(response);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1627,55 +1655,34 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据全局配置决定是否控制台打印DSL语句
|
||||
* 执行bulk创建请求,并返回成功个数,封装id
|
||||
*
|
||||
* @param request es请求参数
|
||||
* @param bulkRequest 批量请求参数
|
||||
* @param requestOptions 类型
|
||||
* @param entityList 实体列表
|
||||
* @return 成功个数
|
||||
*/
|
||||
private void printDSL(RequestBase request) {
|
||||
if (request == null) {
|
||||
return;
|
||||
}
|
||||
private int doBulkRequest(BulkRequest bulkRequest, TransportOptions requestOptions, Collection<T> entityList) {
|
||||
printDSL(bulkRequest, client);
|
||||
|
||||
String method = "";
|
||||
String requestUrl = "";
|
||||
String fullUrl = "";
|
||||
String dsl = "";
|
||||
int totalSuccess = 0;
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
Endpoint<RequestBase, ?, ?> endpoint = (Endpoint<RequestBase, ?, ?>) this.getClass()
|
||||
.getDeclaredField("_ENDPOINT").get(null);
|
||||
method = endpoint.method(request);
|
||||
requestUrl = endpoint.requestUrl(request);
|
||||
|
||||
|
||||
Map<String, String> params = endpoint.queryParameters(request);
|
||||
StringBuilder fullUrlSb = new StringBuilder(requestUrl);
|
||||
String delim = "?";
|
||||
for (Map.Entry<String, String> param : params.entrySet()) {
|
||||
fullUrlSb.append(delim);
|
||||
delim = "&";
|
||||
fullUrlSb.append(param.getKey()).append("=").append(URLEncoder.encode(param.getValue(), StandardCharsets.UTF_8));
|
||||
}
|
||||
fullUrl = fullUrlSb.toString();
|
||||
|
||||
if (this instanceof JsonpSerializable) {
|
||||
dsl = JsonpUtils.toString((JsonpSerializable) this, new StringBuilder()).toString();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// No endpoint, ignore
|
||||
BulkResponse bulkResponse = client.withTransportOptions(requestOptions).bulk(bulkRequest);
|
||||
if (bulkResponse.errors()) {
|
||||
LogUtils.error(bulkResponse.toString());
|
||||
}
|
||||
|
||||
GlobalConfig globalConfig = GlobalConfigCache.getGlobalConfig();
|
||||
if (globalConfig.isPrintDsl()) {
|
||||
String prefix = globalConfig.isIKunMode() ? I_KUN_PREFIX : DSL_PREFIX;
|
||||
LogUtils.info(prefix +
|
||||
"\nmethod: " + method +
|
||||
"\nrequestUrl: " + requestUrl +
|
||||
"\nfullUrl: " + fullUrl +
|
||||
"\nDSL:" + dsl
|
||||
);
|
||||
for (BulkResponseItem item : bulkResponse.items()) {
|
||||
if (Objects.equals(item.status(), 201)) {
|
||||
// setId(entityList.toArray()[totalSuccess], item.id());
|
||||
totalSuccess++;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw ExceptionUtils.eee("bulkRequest exception", e);
|
||||
}
|
||||
return totalSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对响应结构进行判断,如果有错误,则抛出异常
|
||||
|
||||
@ -661,9 +661,11 @@ public class EntityInfoHelper {
|
||||
.setIdClass(field.getType())
|
||||
.setKeyProperty(field.getName());
|
||||
|
||||
entityInfo.getNotSerializeField().add(DEFAULT_ID_NAME);
|
||||
entityInfo.getNotSerializeField().add(field.getName());
|
||||
entityInfo.getMappingColumnMap().putIfAbsent(field.getName(), DEFAULT_ID_NAME);
|
||||
String mappingColumn = !StringUtils.isBlank(tableId.value().trim()) ? tableId.value():
|
||||
getMappingColumn(dbConfig, field);
|
||||
entityInfo.getMappingColumnMap().putIfAbsent(field.getName(), mappingColumn);
|
||||
entityInfo.getColumnMappingMap().putIfAbsent(mappingColumn, field.getName());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -688,9 +690,10 @@ public class EntityInfoHelper {
|
||||
.setKeyField(field)
|
||||
.setIdClass(field.getType())
|
||||
.setClazz(field.getDeclaringClass());
|
||||
entityInfo.getNotSerializeField().add(DEFAULT_ID_NAME);
|
||||
entityInfo.getNotSerializeField().add(field.getName());
|
||||
entityInfo.getMappingColumnMap().putIfAbsent(field.getName(), DEFAULT_ID_NAME);
|
||||
entityInfo.getNotSerializeField().add(column);
|
||||
String mappingColumn = getMappingColumn(dbConfig, field);
|
||||
entityInfo.getMappingColumnMap().putIfAbsent(column, mappingColumn);
|
||||
entityInfo.getColumnMappingMap().putIfAbsent(mappingColumn, column);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -781,10 +784,10 @@ public class EntityInfoHelper {
|
||||
if (settings == null) {
|
||||
return;
|
||||
}
|
||||
IndexSettings.Builder builder = entityInfo.getIndexSettings();
|
||||
builder.numberOfReplicas(settings.replicasNum() + "");
|
||||
builder.numberOfShards(settings.shardsNum() + "");
|
||||
builder.maxResultWindow((int)settings.maxResultWindow());
|
||||
IndexSettings.Builder builder = entityInfo.getIndexSettings()
|
||||
.numberOfReplicas(settings.replicasNum() + "")
|
||||
.numberOfShards(settings.shardsNum() + "")
|
||||
.maxResultWindow((int) settings.maxResultWindow());
|
||||
if (StringUtils.isNotBlank(settings.refreshInterval())) {
|
||||
builder.refreshInterval(a -> a.time(settings.refreshInterval()));
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.dromara.easyes.common.constants.BaseEsConstants.*;
|
||||
import static org.dromara.easyes.common.constants.BaseEsConstants.KEYWORD_SUFFIX;
|
||||
|
||||
/**
|
||||
* 核心 处理字段名称工具类
|
||||
@ -36,12 +36,7 @@ public class FieldUtils {
|
||||
* @return 泛型
|
||||
*/
|
||||
public static <R> String getFieldName(R func) {
|
||||
String fieldName = getFieldNameNotConvertId(func);
|
||||
if (DEFAULT_ID_NAME.equals(fieldName)) {
|
||||
// id统一转为_id
|
||||
fieldName = DEFAULT_ES_ID_NAME;
|
||||
}
|
||||
return fieldName;
|
||||
return getFieldNameNotConvertId(func);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -172,7 +167,7 @@ public class FieldUtils {
|
||||
public static String getRealField(String field, Map<String, String> mappingColumnMap) {
|
||||
String customField = mappingColumnMap.get(field);
|
||||
if (Objects.nonNull(customField)) {
|
||||
return DEFAULT_ID_NAME.equals(customField) ? DEFAULT_ES_ID_NAME : customField;
|
||||
return customField;
|
||||
} else {
|
||||
GlobalConfig.DbConfig dbConfig = GlobalConfigCache.getGlobalConfig().getDbConfig();
|
||||
if (dbConfig.isMapUnderscoreToCamelCase()) {
|
||||
|
||||
@ -22,6 +22,7 @@ import org.dromara.easyes.common.property.GlobalConfig;
|
||||
import org.dromara.easyes.common.utils.*;
|
||||
import org.dromara.easyes.core.biz.*;
|
||||
import org.dromara.easyes.core.cache.GlobalConfigCache;
|
||||
import org.dromara.easyes.core.kernel.BaseEsMapperImpl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
@ -147,6 +148,7 @@ public class IndexUtils {
|
||||
|
||||
// 创建索引
|
||||
try {
|
||||
BaseEsMapperImpl.printDSL(createIndexRequest, client);
|
||||
CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest);
|
||||
return createIndexResponse.acknowledged();
|
||||
} catch (IOException e) {
|
||||
@ -165,6 +167,7 @@ public class IndexUtils {
|
||||
CreateIndexRequest request = CreateIndexRequest.of(x -> x.index(indexName));
|
||||
CreateIndexResponse createIndexResponse;
|
||||
try {
|
||||
BaseEsMapperImpl.printDSL(request, client);
|
||||
createIndexResponse = client.indices().create(request);
|
||||
} catch (IOException e) {
|
||||
LogUtils.info("===> distribute lock index has created");
|
||||
@ -195,6 +198,7 @@ public class IndexUtils {
|
||||
public static GetIndexResponse getIndex(ElasticsearchClient client, String indexName) {
|
||||
GetIndexRequest request = GetIndexRequest.of(x -> x.index(indexName));
|
||||
try {
|
||||
BaseEsMapperImpl.printDSL(request, client);
|
||||
return client.indices().get(request);
|
||||
} catch (IOException e) {
|
||||
throw ExceptionUtils.eee("getIndex exception indexName: %s", e, indexName);
|
||||
@ -221,9 +225,10 @@ public class IndexUtils {
|
||||
*/
|
||||
public static Boolean addAliases(ElasticsearchClient client, String indexName, String... aliases) {
|
||||
Action action = Action.of(x -> x.add(y -> y.aliases(Arrays.asList(aliases)).index(indexName)));
|
||||
UpdateAliasesRequest aliasesRequest = UpdateAliasesRequest.of(x -> x.actions(action));
|
||||
UpdateAliasesRequest request = UpdateAliasesRequest.of(x -> x.actions(action));
|
||||
try {
|
||||
UpdateAliasesResponse response = client.indices().updateAliases(aliasesRequest);
|
||||
BaseEsMapperImpl.printDSL(request, client);
|
||||
UpdateAliasesResponse response = client.indices().updateAliases(request);
|
||||
return response.acknowledged();
|
||||
} catch (IOException e) {
|
||||
LogUtils.warn("addDefaultAlias exception", e.toString());
|
||||
@ -242,7 +247,7 @@ public class IndexUtils {
|
||||
*/
|
||||
public static boolean reindex(ElasticsearchClient client, String oldIndexName, String releaseIndexName, Long maxResultWindow) {
|
||||
int reindexTimeOutHours = GlobalConfigCache.getGlobalConfig().getReindexTimeOutHours();
|
||||
ReindexRequest reindexRequest = ReindexRequest.of(a -> {
|
||||
ReindexRequest request = ReindexRequest.of(a -> {
|
||||
a
|
||||
.source(b -> b.index(oldIndexName))
|
||||
.dest(c -> c.index(releaseIndexName).opType(BaseEsConstants.DEFAULT_DEST_OP_TYPE))
|
||||
@ -256,7 +261,8 @@ public class IndexUtils {
|
||||
return a;
|
||||
});
|
||||
try {
|
||||
ReindexResponse response = client.reindex(reindexRequest);
|
||||
BaseEsMapperImpl.printDSL(request, client);
|
||||
ReindexResponse response = client.reindex(request);
|
||||
List<BulkIndexByScrollFailure> failures = response.failures();
|
||||
return CollectionUtils.isEmpty(failures);
|
||||
} catch (IOException e) {
|
||||
@ -315,8 +321,7 @@ public class IndexUtils {
|
||||
.runtime(mappings.runtime())
|
||||
.enabled(mappings.enabled())
|
||||
.subobjects(mappings.subobjects())
|
||||
.dataStreamTimestamp(mappings.dataStreamTimestamp())
|
||||
;
|
||||
.dataStreamTimestamp(mappings.dataStreamTimestamp());
|
||||
esIndexInfo.setMapping(builder);
|
||||
}
|
||||
|
||||
@ -438,6 +443,7 @@ public class IndexUtils {
|
||||
ByteNumberProperty property = ByteNumberProperty.of(a -> {
|
||||
Optional.ofNullable(indexParam.getBoost()).ifPresent(a::boost);
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
return a;
|
||||
});
|
||||
properties.put(fieldName, property._toProperty());
|
||||
@ -447,6 +453,7 @@ public class IndexUtils {
|
||||
ShortNumberProperty property = ShortNumberProperty.of(a -> {
|
||||
Optional.ofNullable(indexParam.getBoost()).ifPresent(a::boost);
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
return a;
|
||||
});
|
||||
properties.put(fieldName, property._toProperty());
|
||||
@ -456,6 +463,7 @@ public class IndexUtils {
|
||||
IntegerNumberProperty property = IntegerNumberProperty.of(a -> {
|
||||
Optional.ofNullable(indexParam.getBoost()).ifPresent(a::boost);
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
return a;
|
||||
});
|
||||
properties.put(fieldName, property._toProperty());
|
||||
@ -465,6 +473,7 @@ public class IndexUtils {
|
||||
LongNumberProperty property = LongNumberProperty.of(a -> {
|
||||
Optional.ofNullable(indexParam.getBoost()).ifPresent(a::boost);
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
return a;
|
||||
});
|
||||
properties.put(fieldName, property._toProperty());
|
||||
@ -474,6 +483,7 @@ public class IndexUtils {
|
||||
FloatNumberProperty property = FloatNumberProperty.of(a -> {
|
||||
Optional.ofNullable(indexParam.getBoost()).ifPresent(a::boost);
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
return a;
|
||||
});
|
||||
properties.put(fieldName, property._toProperty());
|
||||
@ -483,6 +493,7 @@ public class IndexUtils {
|
||||
DoubleNumberProperty property = DoubleNumberProperty.of(a -> {
|
||||
Optional.ofNullable(indexParam.getBoost()).ifPresent(a::boost);
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
return a;
|
||||
});
|
||||
properties.put(fieldName, property._toProperty());
|
||||
@ -492,6 +503,7 @@ public class IndexUtils {
|
||||
HalfFloatNumberProperty property = HalfFloatNumberProperty.of(a -> {
|
||||
Optional.ofNullable(indexParam.getBoost()).ifPresent(a::boost);
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
return a;
|
||||
});
|
||||
properties.put(fieldName, property._toProperty());
|
||||
@ -503,6 +515,7 @@ public class IndexUtils {
|
||||
ScaledFloatNumberProperty property = ScaledFloatNumberProperty.of(a -> {
|
||||
Optional.ofNullable(indexParam.getBoost()).ifPresent(a::boost);
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
a.scalingFactor(scalingFactor);
|
||||
return a;
|
||||
});
|
||||
@ -513,6 +526,7 @@ public class IndexUtils {
|
||||
BooleanProperty property = BooleanProperty.of(a -> {
|
||||
Optional.ofNullable(indexParam.getBoost()).ifPresent(a::boost);
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
return a;
|
||||
});
|
||||
properties.put(fieldName, property._toProperty());
|
||||
@ -522,6 +536,7 @@ public class IndexUtils {
|
||||
DateProperty property = DateProperty.of(a -> {
|
||||
Optional.ofNullable(indexParam.getBoost()).ifPresent(a::boost);
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
a.format(indexParam.getDateFormat());
|
||||
return a;
|
||||
});
|
||||
@ -531,6 +546,7 @@ public class IndexUtils {
|
||||
if (FieldType.BINARY.getType().equals(indexParam.getFieldType())) {
|
||||
BinaryProperty property = BinaryProperty.of(a -> {
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
return a;
|
||||
});
|
||||
properties.put(fieldName, property._toProperty());
|
||||
@ -540,9 +556,8 @@ public class IndexUtils {
|
||||
KeywordProperty property = KeywordProperty.of(a -> {
|
||||
Optional.ofNullable(indexParam.getBoost()).ifPresent(a::boost);
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
if (indexParam.isIgnoreCase()) {
|
||||
a.normalizer(LOWERCASE_NORMALIZER);
|
||||
}
|
||||
buildInnerFields(a, indexParam);
|
||||
a.normalizer(indexParam.isIgnoreCase() ? LOWERCASE_NORMALIZER : null);
|
||||
return a;
|
||||
});
|
||||
properties.put(fieldName, property._toProperty());
|
||||
@ -552,10 +567,11 @@ public class IndexUtils {
|
||||
int ignoreAbove = Optional.ofNullable(indexParam.getIgnoreAbove()).orElse(DEFAULT_IGNORE_ABOVE);
|
||||
TextProperty property = TextProperty.of(a -> {
|
||||
Optional.ofNullable(indexParam.getBoost()).ifPresent(a::boost);
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
Optional.ofNullable(indexParam.getAnalyzer()).map(String::toLowerCase).ifPresent(a::analyzer);
|
||||
Optional.ofNullable(indexParam.getSearchAnalyzer()).map(String::toLowerCase).ifPresent(a::searchAnalyzer);
|
||||
MyOptional.ofNullable(indexParam.getFieldData()).ifTrue(a::fielddata);
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
return a;
|
||||
});
|
||||
properties.put(fieldName, property._toProperty());
|
||||
@ -566,6 +582,7 @@ public class IndexUtils {
|
||||
TextProperty property = TextProperty.of(a -> {
|
||||
Optional.ofNullable(indexParam.getBoost()).ifPresent(a::boost);
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
a.fields(FieldType.KEYWORD.getType(), c -> c
|
||||
.keyword(d -> {
|
||||
d.ignoreAbove(ignoreAbove);
|
||||
@ -587,6 +604,7 @@ public class IndexUtils {
|
||||
int ignoreAbove = Optional.ofNullable(indexParam.getIgnoreAbove()).orElse(DEFAULT_IGNORE_ABOVE);
|
||||
WildcardProperty property = WildcardProperty.of(a -> {
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
return a;
|
||||
});
|
||||
properties.put(fieldName, property._toProperty());
|
||||
@ -599,6 +617,7 @@ public class IndexUtils {
|
||||
Map<String, Property> nested = initInfo(entityInfo, dbConfig, new HashMap<>(), esIndexParams);
|
||||
NestedProperty property = NestedProperty.of(a -> {
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
a.properties(nested);
|
||||
return a;
|
||||
});
|
||||
@ -612,6 +631,7 @@ public class IndexUtils {
|
||||
Map<String, Property> nested = initInfo(entityInfo, dbConfig, new HashMap<>(), esIndexParams);
|
||||
ObjectProperty property = ObjectProperty.of(a -> {
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
a.properties(nested);
|
||||
return a;
|
||||
});
|
||||
@ -624,6 +644,7 @@ public class IndexUtils {
|
||||
if (FieldType.GEO_POINT.getType().equals(indexParam.getFieldType())) {
|
||||
GeoPointProperty property = GeoPointProperty.of(a -> {
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
return a;
|
||||
});
|
||||
properties.put(fieldName, property._toProperty());
|
||||
@ -632,6 +653,7 @@ public class IndexUtils {
|
||||
if (FieldType.GEO_SHAPE.getType().equals(indexParam.getFieldType())) {
|
||||
GeoShapeProperty property = GeoShapeProperty.of(a -> {
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
return a;
|
||||
});
|
||||
properties.put(fieldName, property._toProperty());
|
||||
@ -641,6 +663,7 @@ public class IndexUtils {
|
||||
IpProperty property = IpProperty.of(a -> {
|
||||
Optional.ofNullable(indexParam.getBoost()).ifPresent(a::boost);
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
return a;
|
||||
});
|
||||
properties.put(fieldName, property._toProperty());
|
||||
@ -649,6 +672,7 @@ public class IndexUtils {
|
||||
if (FieldType.COMPLETION.getType().equals(indexParam.getFieldType())) {
|
||||
CompletionProperty property = CompletionProperty.of(a -> {
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
Optional.ofNullable(indexParam.getAnalyzer()).map(String::toLowerCase).ifPresent(a::analyzer);
|
||||
Optional.ofNullable(indexParam.getSearchAnalyzer()).map(String::toLowerCase).ifPresent(a::searchAnalyzer);
|
||||
return a;
|
||||
@ -660,6 +684,7 @@ public class IndexUtils {
|
||||
TokenCountProperty property = TokenCountProperty.of(a -> {
|
||||
Optional.ofNullable(indexParam.getBoost()).ifPresent(a::boost);
|
||||
buildCopyTo(a, entityInfo.isIndexEqualStage(), indexParam.getCopyToList());
|
||||
buildInnerFields(a, indexParam);
|
||||
return a;
|
||||
});
|
||||
properties.put(fieldName, property._toProperty());
|
||||
@ -669,7 +694,10 @@ public class IndexUtils {
|
||||
return;
|
||||
}
|
||||
if (FieldType.PERCOLATOR.getType().equals(indexParam.getFieldType())) {
|
||||
PercolatorProperty property = PercolatorProperty.of(a -> a);
|
||||
PercolatorProperty property = PercolatorProperty.of(a -> {
|
||||
buildInnerFields(a, indexParam);
|
||||
return a;
|
||||
});
|
||||
properties.put(fieldName, property._toProperty());
|
||||
return;
|
||||
}
|
||||
@ -971,8 +999,7 @@ public class IndexUtils {
|
||||
* @return 索引参数列表
|
||||
*/
|
||||
public static List<EsIndexParam> initIndexParam(EntityInfo entityInfo, Class<?> clazz, List<EntityFieldInfo> fieldList) {
|
||||
List<EntityFieldInfo> copyFieldList = new ArrayList<>();
|
||||
copyFieldList.addAll(fieldList);
|
||||
List<EntityFieldInfo> copyFieldList = new ArrayList<>(fieldList);
|
||||
|
||||
List<EsIndexParam> esIndexParamList = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(copyFieldList)) {
|
||||
@ -983,7 +1010,7 @@ public class IndexUtils {
|
||||
String esFieldType = IndexUtils.getEsFieldType(field.getFieldType(), field.getColumnType());
|
||||
esIndexParam.setFieldType(esFieldType);
|
||||
if (field.isFieldData()) {
|
||||
esIndexParam.setFieldData(field.isFieldData());
|
||||
esIndexParam.setFieldData(true);
|
||||
}
|
||||
esIndexParam.setFieldName(field.getMappingColumn());
|
||||
esIndexParam.setScalingFactor(field.getScalingFactor());
|
||||
|
||||
@ -5,6 +5,7 @@ import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.dromara.easyes.annotation.*;
|
||||
import org.dromara.easyes.annotation.rely.*;
|
||||
import org.dromara.easyes.common.join.BaseJoin;
|
||||
import org.dromara.easyes.test.settings.MySettingsProvider;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
@ -25,9 +26,9 @@ import java.util.List;
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Settings(shardsNum = 3, replicasNum = 2, settingsProvider = MySettingsProvider.class)
|
||||
@IndexName(value = "easyes_solon_document", keepGlobalPrefix = true, refreshPolicy = RefreshPolicy.IMMEDIATE)
|
||||
@IndexName(value = "easyes_solon_document_8", keepGlobalPrefix = true, refreshPolicy = RefreshPolicy.IMMEDIATE)
|
||||
@Join(nodes = {@Node(parentClass = Document.class, childClasses = {Author.class, Comment.class}), @Node(parentClass = Author.class, childClasses = Contact.class)})
|
||||
public class Document {
|
||||
public class Document extends BaseJoin {
|
||||
/**
|
||||
* es中的唯一id,字段名随便起,我这里演示用esId,你也可以用id(推荐),bizId等.
|
||||
* 如果你想自定义es中的id为你提供的id,比如MySQL中的id,请将注解中的type指定为customize或直接在全局配置文件中指定,如此id便支持任意数据类型)
|
||||
|
||||
@ -1,22 +1,18 @@
|
||||
package org.dromara.easyes.test.settings;
|
||||
|
||||
import co.elastic.clients.elasticsearch.indices.IndexSettings;
|
||||
import org.dromara.easyes.annotation.rely.DefaultSettingsProvider;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 由于es索引的settings灵活多变,框架只能针对一部分场景作简化,其余场景需要用户自定义实现
|
||||
* <p>
|
||||
* Copyright © 2024 xpc1024 All Rights Reserved
|
||||
**/
|
||||
public class MySettingsProvider extends DefaultSettingsProvider {
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getSettings() {
|
||||
// TODO 这里可以自定义你的settings实现,将自定义的settings置入map并返回即可
|
||||
Map<String, Object> mySettings = new HashMap<>();
|
||||
// 例如指定查询操作的慢日志阈值为30秒,当查询操作的执行时间超过此阈值时,Elasticsearch会记录相应的慢日志并发出警告
|
||||
mySettings.put("index.search.slowlog.threshold.query.warn", "30s");
|
||||
return mySettings;
|
||||
public void settings(IndexSettings.Builder builder) {
|
||||
builder.index(a -> a.search(b -> b
|
||||
.slowlog(c -> c.threshold(d -> d.query(e -> e.warn(f -> f.time("30s")))))));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,45 +1,34 @@
|
||||
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._types.*;
|
||||
import co.elastic.clients.elasticsearch._types.aggregations.Aggregate;
|
||||
import co.elastic.clients.elasticsearch._types.aggregations.LongTermsBucket;
|
||||
import co.elastic.clients.elasticsearch._types.query_dsl.BoolQuery;
|
||||
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
|
||||
import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders;
|
||||
import co.elastic.clients.elasticsearch.core.SearchRequest;
|
||||
import co.elastic.clients.elasticsearch.core.SearchResponse;
|
||||
import co.elastic.clients.json.JsonData;
|
||||
import co.elastic.clients.transport.rest_client.RestClientOptions;
|
||||
import org.dromara.easyes.common.constants.BaseEsConstants;
|
||||
import org.dromara.easyes.core.biz.EntityInfo;
|
||||
import org.dromara.easyes.core.biz.EsPageInfo;
|
||||
import org.dromara.easyes.core.biz.OrderByParam;
|
||||
import org.dromara.easyes.core.biz.SAPageInfo;
|
||||
import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
|
||||
import org.dromara.easyes.core.conditions.update.LambdaEsUpdateWrapper;
|
||||
import org.dromara.easyes.core.kernel.EsWrappers;
|
||||
import org.dromara.easyes.core.kernel.WrapperProcessor;
|
||||
import org.dromara.easyes.core.toolkit.EntityInfoHelper;
|
||||
import org.dromara.easyes.core.toolkit.FieldUtils;
|
||||
import org.dromara.easyes.test.TestEasyEsApplication;
|
||||
import org.dromara.easyes.test.entity.Document;
|
||||
import org.dromara.easyes.test.mapper.DocumentMapper;
|
||||
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.GeoShapeRelation;
|
||||
import org.elasticsearch.common.unit.DistanceUnit;
|
||||
import org.elasticsearch.geometry.Circle;
|
||||
import org.elasticsearch.geometry.Point;
|
||||
import org.elasticsearch.geometry.Rectangle;
|
||||
import org.elasticsearch.index.query.BoolQueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptType;
|
||||
import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms;
|
||||
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedAvg;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedMax;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedMin;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedSum;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.elasticsearch.search.sort.FieldSortBuilder;
|
||||
import org.elasticsearch.search.sort.GeoDistanceSortBuilder;
|
||||
import org.elasticsearch.search.sort.SortBuilders;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.noear.solon.annotation.Inject;
|
||||
import org.noear.solon.test.SolonTest;
|
||||
@ -96,6 +85,7 @@ public class AllTest {
|
||||
document.setEnglish("Calcium Gluconate");
|
||||
document.setBigNum(new BigDecimal("66.66"));
|
||||
document.setVector(new double[]{0.39684247970581666, 0.768707156181666, 0.5145490765571666});
|
||||
// System.out.println(JsonUtils.toJsonPrettyStr(document));
|
||||
int successCount = documentMapper.insert(document);
|
||||
Assertions.assertEquals(successCount, 1);
|
||||
}
|
||||
@ -116,7 +106,6 @@ public class AllTest {
|
||||
document.setGeoLocation(point.toString());
|
||||
document.setStarNum(i);
|
||||
document.setVector(new double[]{35.89684247970581666, 86.268707156181666, 133.1145490765571666});
|
||||
|
||||
// 针对个别数据 造一些差异项 方便测试不同场景
|
||||
if (i == 2) {
|
||||
document.setLocation("40.17836693398477,116.64002551005981");
|
||||
@ -168,8 +157,12 @@ public class AllTest {
|
||||
@Order(4)
|
||||
public void testUpdateBySetSearchSourceBuilder() {
|
||||
LambdaEsUpdateWrapper<Document> wrapper = new LambdaEsUpdateWrapper<>();
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
|
||||
searchSourceBuilder.query(QueryBuilders.termQuery(FieldUtils.val(Document::getTitle) + KEYWORD_SUFFIX, "测试文档2"));
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchRequest.Builder();
|
||||
searchSourceBuilder.query(QueryBuilders.term()
|
||||
.field(FieldUtils.val(Document::getTitle) + KEYWORD_SUFFIX)
|
||||
.value("测试文档2")
|
||||
.build()._toQuery()
|
||||
);
|
||||
wrapper.setSearchSourceBuilder(searchSourceBuilder);
|
||||
|
||||
Document document = new Document();
|
||||
@ -231,9 +224,9 @@ public class AllTest {
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void testDefaultMethod(){
|
||||
public void testDefaultMethod() {
|
||||
List<Document> documents = documentMapper.testDefaultMethod();
|
||||
Assertions.assertEquals(documents.size(),1);
|
||||
Assertions.assertEquals(documents.size(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -433,11 +426,10 @@ public class AllTest {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.match(Document::getContent, "测试")
|
||||
.groupBy(Document::getStarNum);
|
||||
SearchResponse response = documentMapper.search(wrapper);
|
||||
ParsedLongTerms parsedLongTerms = response.getAggregations()
|
||||
.get("starNumTerms");
|
||||
Terms.Bucket bucket = parsedLongTerms.getBuckets().get(0);
|
||||
Assertions.assertTrue(bucket.getKey().equals(1L) && bucket.getDocCount() == 2L);
|
||||
SearchResponse<Document> response = documentMapper.search(wrapper);
|
||||
Aggregate aggregate = response.aggregations().get("starNumTerms");
|
||||
LongTermsBucket bucket = aggregate.lterms().buckets().array().get(0);
|
||||
Assertions.assertTrue(bucket.key() == 1L && bucket.docCount() == 2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -446,10 +438,9 @@ public class AllTest {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.match(Document::getContent, "测试")
|
||||
.max(Document::getStarNum);
|
||||
SearchResponse response = documentMapper.search(wrapper);
|
||||
ParsedMax parsedMax = response.getAggregations()
|
||||
.get("starNumMax");
|
||||
Assertions.assertTrue(parsedMax.getValue() > 21);
|
||||
SearchResponse<Document> response = documentMapper.search(wrapper);
|
||||
Aggregate agg = response.aggregations().get("starNumMax");
|
||||
Assertions.assertTrue(agg.valueCount().value() > 21);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -458,10 +449,9 @@ public class AllTest {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.match(Document::getContent, "测试")
|
||||
.min(Document::getStarNum);
|
||||
SearchResponse response = documentMapper.search(wrapper);
|
||||
ParsedMin parsedMin = response.getAggregations()
|
||||
.get("starNumMin");
|
||||
Assertions.assertTrue(parsedMin.getValue() > 0 && parsedMin.getValue() < 2);
|
||||
SearchResponse<Document> response = documentMapper.search(wrapper);
|
||||
double parsedMin = response.aggregations().get("starNumMin").valueCount().value();
|
||||
Assertions.assertTrue(parsedMin > 0 && parsedMin < 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -470,10 +460,9 @@ public class AllTest {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.match(Document::getContent, "测试")
|
||||
.sum(Document::getStarNum);
|
||||
SearchResponse response = documentMapper.search(wrapper);
|
||||
ParsedSum parsedSum = response.getAggregations()
|
||||
.get("starNumSum");
|
||||
Assertions.assertTrue(parsedSum.getValue() >= 252);
|
||||
SearchResponse<Document> response = documentMapper.search(wrapper);
|
||||
double parsedSum = response.aggregations().get("starNumSum").valueCount().value();
|
||||
Assertions.assertTrue(parsedSum >= 252);
|
||||
}
|
||||
|
||||
|
||||
@ -483,10 +472,9 @@ public class AllTest {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.match(Document::getContent, "测试")
|
||||
.avg(Document::getStarNum);
|
||||
SearchResponse response = documentMapper.search(wrapper);
|
||||
ParsedAvg parsedAvg = response.getAggregations()
|
||||
.get("starNumAvg");
|
||||
Assertions.assertTrue(parsedAvg.getValue() > 11 && parsedAvg.getValue() < 12);
|
||||
SearchResponse<Document> response = documentMapper.search(wrapper);
|
||||
double parsedAvg = response.aggregations().get("starNumAvg").valueCount().value();
|
||||
Assertions.assertTrue(parsedAvg > 11 && parsedAvg < 12);
|
||||
}
|
||||
|
||||
|
||||
@ -534,12 +522,15 @@ public class AllTest {
|
||||
@Test
|
||||
@Order(6)
|
||||
public void testSetSearchSourceBuilder() {
|
||||
EntityInfo e = EntityInfoHelper.getEntityInfo(Document.class);
|
||||
// 测试混合查询的另一种方式
|
||||
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()))
|
||||
.ifPresent(searchSourceBuilder::size);
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchRequest.Builder()
|
||||
.query(QueryBuilders.match()
|
||||
.field(FieldUtils.val(Document::getCreator))
|
||||
.query("老汉")
|
||||
.build()._toQuery()
|
||||
)
|
||||
.size(e.getMaxResultWindow().intValue());
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.setSearchSourceBuilder(searchSourceBuilder);
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
@ -703,7 +694,7 @@ public class AllTest {
|
||||
@Order(6)
|
||||
public void testOrderByDistanceAsc() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
GeoLocation centerPoint = new GeoLocation(41.0, 116.0);
|
||||
GeoLocation centerPoint = GeoLocation.of(a -> a.latlon(a1 -> a1.lat(41.0).lon(116.0)));
|
||||
wrapper.match(Document::getCreator, "老汉")
|
||||
.geoDistance(Document::getLocation, 168.8, centerPoint)
|
||||
.orderByDistanceAsc(Document::getLocation, centerPoint);
|
||||
@ -716,7 +707,7 @@ public class AllTest {
|
||||
@Order(6)
|
||||
public void testOrderByDistanceDesc() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
GeoLocation centerPoint = new GeoLocation(41.0, 116.0);
|
||||
GeoLocation centerPoint = GeoLocation.of(a -> a.latlon(a1 -> a1.lat(41.0).lon(116.0)));
|
||||
wrapper.match(Document::getCreator, "老汉")
|
||||
.geoDistance(Document::getLocation, 168.8, centerPoint)
|
||||
.orderByDistanceDesc(Document::getLocation, centerPoint);
|
||||
@ -729,8 +720,8 @@ public class AllTest {
|
||||
@Order(6)
|
||||
public void testOrderByDistanceMulti() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
GeoLocation centerPoint = new GeoLocation(41.0, 116.0);
|
||||
GeoLocation centerPoint1 = new GeoLocation(42.0, 118.0);
|
||||
GeoLocation centerPoint = GeoLocation.of(a -> a.latlon(a1 -> a1.lat(41.0).lon(116.0)));
|
||||
GeoLocation centerPoint1 = GeoLocation.of(a -> a.latlon(a1 -> a1.lat(42.0).lon(118.0)));
|
||||
wrapper.match(Document::getCreator, "老汉")
|
||||
.geoDistance(Document::getLocation, 168.8, centerPoint)
|
||||
.orderByDistanceDesc(Document::getLocation, centerPoint)
|
||||
@ -753,14 +744,17 @@ public class AllTest {
|
||||
@Test
|
||||
@Order(6)
|
||||
public void testSort() {
|
||||
String realField = FieldUtils.getRealField(
|
||||
FieldUtils.val(Document::getStarNum),
|
||||
EntityInfoHelper.getEntityInfo(Document.class).getMappingColumnMap()
|
||||
);
|
||||
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.match(Document::getCreator, "老汉");
|
||||
FieldSortBuilder fieldSortBuilder = SortBuilders.
|
||||
fieldSort(FieldUtils.getRealField(
|
||||
FieldUtils.val(Document::getStarNum),
|
||||
EntityInfoHelper.getEntityInfo(Document.class).getMappingColumnMap()));
|
||||
fieldSortBuilder.order(SortOrder.Desc);
|
||||
wrapper.sort(fieldSortBuilder);
|
||||
wrapper.sort(SortOptions.of(a -> a.field(b -> b
|
||||
.field(realField)
|
||||
.order(SortOrder.Desc)
|
||||
)));
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
Assertions.assertEquals("22", documents.get(0).getEsId());
|
||||
Assertions.assertEquals("21", documents.get(1).getEsId());
|
||||
@ -781,7 +775,7 @@ public class AllTest {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.matchPhrase(Document::getContent, "测试");
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
Assertions.assertTrue(documents.size() > 0);
|
||||
Assertions.assertFalse(documents.isEmpty());
|
||||
|
||||
LambdaEsQueryWrapper<Document> wrapper1 = new LambdaEsQueryWrapper<>();
|
||||
wrapper1.matchPhrase(Document::getContent, "内容测试");
|
||||
@ -845,7 +839,7 @@ public class AllTest {
|
||||
public void testHighLight() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.match(Document::getContent, "测试")
|
||||
.match(Document::getCustomField,"字段");
|
||||
.match(Document::getCustomField, "字段");
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
Assertions.assertTrue(documents.get(0).getHighlightContent().contains("测试"));
|
||||
}
|
||||
@ -854,8 +848,8 @@ public class AllTest {
|
||||
@Order(6)
|
||||
public void testGeoBoundingBox() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
GeoLocation leftTop = new GeoLocation(41.187328D, 115.498353D);
|
||||
GeoLocation bottomRight = new GeoLocation(39.084509D, 117.610461D);
|
||||
GeoLocation leftTop = GeoLocation.of(a -> a.latlon(a1 -> a1.lat(41.187328D).lon(115.498353D)));
|
||||
GeoLocation bottomRight = GeoLocation.of(a -> a.latlon(a1 -> a1.lat(39.084509D).lon(117.610461D)));
|
||||
wrapper.geoBoundingBox(Document::getLocation, leftTop, bottomRight);
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
Assertions.assertEquals(4, documents.size());
|
||||
@ -866,14 +860,15 @@ public class AllTest {
|
||||
@Order(6)
|
||||
public void testGeoDistance() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
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);
|
||||
|
||||
wrapper.sort(geoDistanceSortBuilder);
|
||||
GeoLocation geoPoint = GeoLocation.of(a -> a.latlon(a1 -> a1.lat(41.0).lon(116.0)));
|
||||
wrapper.geoDistance(Document::getLocation, 168.8, DistanceUnit.Kilometers, geoPoint);
|
||||
wrapper.sort(SortOptions.of(a -> a.geoDistance(b -> b
|
||||
.field(FieldUtils.val(Document::getLocation))
|
||||
.location(geoPoint)
|
||||
.unit(DistanceUnit.Kilometers)
|
||||
.distanceType(GeoDistanceType.Arc)
|
||||
.order(SortOrder.Desc)
|
||||
)));
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
Assertions.assertEquals(4, documents.size());
|
||||
}
|
||||
@ -883,9 +878,9 @@ public class AllTest {
|
||||
public void testGeoPolygon() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
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);
|
||||
GeoLocation geoPoint = GeoLocation.of(a -> a.latlon(a1 -> a1.lat(40.178012).lon(116.577188)));
|
||||
GeoLocation geoPoint1 = GeoLocation.of(a -> a.latlon(a1 -> a1.lat(40.169329).lon(116.586315)));
|
||||
GeoLocation geoPoint2 = GeoLocation.of(a -> a.latlon(a1 -> a1.lat(40.178288).lon(116.591813)));
|
||||
geoPoints.add(geoPoint);
|
||||
geoPoints.add(geoPoint1);
|
||||
geoPoints.add(geoPoint2);
|
||||
@ -899,7 +894,7 @@ public class AllTest {
|
||||
public void testGeoShape() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
Circle circle = new Circle(13, 14, 100);
|
||||
wrapper.geoShape(Document::getGeoLocation, circle, GeoShapeRelation.DISJOINT);
|
||||
wrapper.geoShape(Document::getGeoLocation, circle, GeoShapeRelation.Disjoint);
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
Assertions.assertEquals(22, documents.size());
|
||||
}
|
||||
@ -923,13 +918,16 @@ public class AllTest {
|
||||
@Order(6)
|
||||
public void testVector() {
|
||||
// 向量查询, 查询条件构造
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("vector", new double[]{0.39684247970581055, 0.7687071561813354, 0.5145490765571594});
|
||||
String scriptCode = "cosineSimilarity(params.vector, 'vector') + 1.0";
|
||||
QueryBuilder queryBuilder = QueryBuilders.scriptScoreQuery(QueryBuilders.matchAllQuery(), new Script(ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG, scriptCode, params));
|
||||
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
|
||||
searchSourceBuilder.query(queryBuilder);
|
||||
Query query = Query.of(a -> a.scriptScore(b -> b
|
||||
.query(QueryBuilders.matchAll().build()._toQuery())
|
||||
.script(d -> d
|
||||
.lang(ScriptLanguage.Painless)
|
||||
.params("vector", JsonData.of(new double[]{0.39684247970581055, 0.7687071561813354, 0.5145490765571594}))
|
||||
.source("cosineSimilarity(params.vector, 'vector') + 1.0")
|
||||
)
|
||||
));
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchRequest.Builder();
|
||||
searchSourceBuilder.query(query);
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.setSearchSourceBuilder(searchSourceBuilder);
|
||||
|
||||
@ -941,11 +939,10 @@ public class AllTest {
|
||||
@Order(6)
|
||||
public void testSetRequestOptions() {
|
||||
// 可设置自定义请求参数,覆盖默认配置, 解决报错 entity content is too long [168583249] for the configured buffer limit [104857600]
|
||||
RequestOptions.Builder options = RequestOptions.DEFAULT.toBuilder();
|
||||
options.setHttpAsyncResponseConsumerFactory(
|
||||
RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
|
||||
builder.setHttpAsyncResponseConsumerFactory(
|
||||
new HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory(4 * 104857600));
|
||||
final RequestOptions requestOptions = options.build();
|
||||
Boolean success = documentMapper.setRequestOptions(requestOptions);
|
||||
Boolean success = documentMapper.setRequestOptions(new RestClientOptions(builder.build(), true));
|
||||
Assertions.assertTrue(success);
|
||||
}
|
||||
|
||||
@ -991,12 +988,20 @@ public class AllTest {
|
||||
// where business_type = 1 and (state = 9 or (state = 8 and bidding_sign = 1)) or (business_type = 2 and state in (2,3))
|
||||
|
||||
// ElasticsearchClient写法
|
||||
List<Integer> values = Arrays.asList(2, 3);
|
||||
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
|
||||
boolQueryBuilder.must(QueryBuilders.termQuery("business_type", 1));
|
||||
boolQueryBuilder.must(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("state", 9))
|
||||
.should(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("state", 8)).must(QueryBuilders.termQuery("bidding_sign", 1))));
|
||||
boolQueryBuilder.should(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("business_type", 2)).must(QueryBuilders.termsQuery("state", values)));
|
||||
List<FieldValue> values = Arrays.asList(WrapperProcessor.fieldValue(2), WrapperProcessor.fieldValue(3));
|
||||
BoolQuery.Builder boolQueryBuilder = QueryBuilders.bool()
|
||||
.must(a -> a.term(b -> b.field("business_type").value(1)))
|
||||
.must(a -> a.bool(b -> b
|
||||
.must(c -> c.term(d -> d.field("state").value(9)))
|
||||
.should(c -> c.bool(d -> d
|
||||
.must(f -> f.term(e -> e.field("state").value(8)))
|
||||
.must(f -> f.term(e -> e.field("bidding_sign").value(1)))
|
||||
))
|
||||
))
|
||||
.should(a -> a.bool(c -> c
|
||||
.must(d -> d.term(e -> e.field("business_type").value(2)))
|
||||
.must(d -> d.terms(e -> e.field("state").terms(f -> f.value(values))))
|
||||
));
|
||||
|
||||
System.out.println(boolQueryBuilder);
|
||||
System.out.println("--------------------");
|
||||
|
||||
@ -1,137 +1,137 @@
|
||||
package org.dromara.easyes.test.index;
|
||||
|
||||
import org.dromara.easyes.annotation.rely.Analyzer;
|
||||
import org.dromara.easyes.annotation.rely.FieldType;
|
||||
import org.dromara.easyes.core.conditions.index.LambdaEsIndexWrapper;
|
||||
import org.dromara.easyes.test.TestEasyEsApplication;
|
||||
import org.dromara.easyes.test.entity.Document;
|
||||
import org.dromara.easyes.test.mapper.DocumentMapper;
|
||||
import org.elasticsearch.client.indices.GetIndexResponse;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.noear.solon.annotation.Inject;
|
||||
import org.noear.solon.test.SolonTest;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 不了解Es索引概念的建议先去了解 懒汉可以简单理解为MySQL中的一张表
|
||||
* 索引测试 注意,此测试类下所有方法请先关闭自动挡模式,开启手动挡 配置: process-index-mode=manual
|
||||
* <p>
|
||||
* Copyright © 2021 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@Disabled
|
||||
@SolonTest(classes = TestEasyEsApplication.class)
|
||||
public class IndexTest {
|
||||
@Inject
|
||||
private DocumentMapper documentMapper;
|
||||
|
||||
/**
|
||||
* 测试创建索引 根据实体类字段及其注解配置创建索引 大多数场景适用,最为简单,但灵活性稍差
|
||||
* 创建的索引与自动挡-运动模式一样,但触发方式为手动调用 区别是自动挡模式下索引创建及更新随spring容器启动时自动执行
|
||||
*/
|
||||
@Test
|
||||
public void testCreateIndexByEntity() {
|
||||
// 绝大多数场景推荐使用 简单至上
|
||||
boolean ok = documentMapper.createIndex();
|
||||
Assertions.assertTrue(ok);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试创建索引 根据自定义信息去创建,最为灵活,用此种方式可支持任何es支持的索引
|
||||
*/
|
||||
@Test
|
||||
public void testCreateIndex() {
|
||||
// 复杂场景使用
|
||||
LambdaEsIndexWrapper<Document> wrapper = new LambdaEsIndexWrapper<>();
|
||||
// 此处简单起见 索引名称须保持和实体类名称一致,字母小写 后面章节会教大家更如何灵活配置和使用索引
|
||||
wrapper.indexName(Document.class.getSimpleName().toLowerCase());
|
||||
|
||||
// 此处将文章标题映射为keyword类型(不支持分词),文档内容映射为text类型(支持分词查询)
|
||||
wrapper.mapping(Document::getTitle, FieldType.KEYWORD, 2.0f)
|
||||
.mapping(Document::getLocation, FieldType.GEO_POINT)
|
||||
.mapping(Document::getGeoLocation, FieldType.GEO_SHAPE)
|
||||
.mapping(Document::getContent, FieldType.TEXT, Analyzer.IK_SMART, Analyzer.IK_MAX_WORD);
|
||||
|
||||
// 0.9.8+版本,增加对符串字段名称的支持,Document实体中须在对应字段上加上@Tablefield(value="wu-la")用于映射此字段值
|
||||
wrapper.mapping("wu-la", FieldType.TEXT, Analyzer.IK_MAX_WORD, Analyzer.IK_MAX_WORD);
|
||||
|
||||
// 设置分片及副本信息,可缺省
|
||||
wrapper.settings(3, 2);
|
||||
|
||||
// 设置别名信息,可缺省
|
||||
String aliasName = "daily";
|
||||
wrapper.createAlias(aliasName);
|
||||
|
||||
// 设置父子信息,若无父子文档关系则无需设置
|
||||
wrapper.join("joinField", "document", "comment");
|
||||
|
||||
// 创建索引
|
||||
boolean isOk = documentMapper.createIndex(wrapper);
|
||||
Assertions.assertTrue(isOk);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExistsIndex() {
|
||||
// 测试是否存在指定名称的索引
|
||||
String indexName = Document.class.getSimpleName().toLowerCase();
|
||||
boolean existsIndex = documentMapper.existsIndex(indexName);
|
||||
Assertions.assertTrue(existsIndex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetIndex() {
|
||||
GetIndexResponse indexResponse = documentMapper.getIndex();
|
||||
// 这里打印下索引结构信息 其它分片等信息皆可从indexResponse中取
|
||||
indexResponse.getMappings().forEach((k, v) -> System.out.println(v.getSourceAsMap()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateIndex() {
|
||||
// 测试更新索引
|
||||
LambdaEsIndexWrapper<Document> wrapper = new LambdaEsIndexWrapper<>();
|
||||
// 指定要更新哪个索引
|
||||
String indexName = Document.class.getSimpleName().toLowerCase();
|
||||
wrapper.indexName(indexName);
|
||||
wrapper.mapping(Document::getCreator, FieldType.KEYWORD);
|
||||
wrapper.mapping(Document::getGmtCreate, FieldType.DATE);
|
||||
boolean isOk = documentMapper.updateIndex(wrapper);
|
||||
Assertions.assertTrue(isOk);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteIndex() {
|
||||
// 测试删除索引
|
||||
// 指定要删除哪个索引
|
||||
String indexName = Document.class.getSimpleName().toLowerCase();
|
||||
boolean isOk = documentMapper.deleteIndex(indexName);
|
||||
Assertions.assertTrue(isOk);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateIndexByMap() {
|
||||
// 演示通过自定义map创建索引,最为灵活,若我提供的创建索引API不能满足时可用此方法
|
||||
LambdaEsIndexWrapper<Document> wrapper = new LambdaEsIndexWrapper<>();
|
||||
wrapper.indexName(Document.class.getSimpleName().toLowerCase());
|
||||
wrapper.settings(3, 2);
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
Map<String, Object> prop = new HashMap<>();
|
||||
Map<String, String> field = new HashMap<>();
|
||||
field.put("type", FieldType.KEYWORD.getType());
|
||||
prop.put("this_is_field", field);
|
||||
map.put("properties", prop);
|
||||
wrapper.mapping(map);
|
||||
boolean isOk = documentMapper.createIndex(wrapper);
|
||||
Assertions.assertTrue(isOk);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActiveIndex(){
|
||||
String indexName = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
documentMapper.setCurrentActiveIndex(indexName);
|
||||
}
|
||||
}
|
||||
//package org.dromara.easyes.test.index;
|
||||
//
|
||||
//import org.dromara.easyes.annotation.rely.Analyzer;
|
||||
//import org.dromara.easyes.annotation.rely.FieldType;
|
||||
//import org.dromara.easyes.core.conditions.index.LambdaEsIndexWrapper;
|
||||
//import org.dromara.easyes.test.TestEasyEsApplication;
|
||||
//import org.dromara.easyes.test.entity.Document;
|
||||
//import org.dromara.easyes.test.mapper.DocumentMapper;
|
||||
//import org.elasticsearch.client.indices.GetIndexResponse;
|
||||
//import org.junit.jupiter.api.Assertions;
|
||||
//import org.junit.jupiter.api.Disabled;
|
||||
//import org.junit.jupiter.api.Test;
|
||||
//import org.noear.solon.annotation.Inject;
|
||||
//import org.noear.solon.test.SolonTest;
|
||||
//
|
||||
//import java.time.LocalDate;
|
||||
//import java.time.format.DateTimeFormatter;
|
||||
//import java.util.HashMap;
|
||||
//import java.util.Map;
|
||||
//
|
||||
///**
|
||||
// * 不了解Es索引概念的建议先去了解 懒汉可以简单理解为MySQL中的一张表
|
||||
// * 索引测试 注意,此测试类下所有方法请先关闭自动挡模式,开启手动挡 配置: process-index-mode=manual
|
||||
// * <p>
|
||||
// * Copyright © 2021 xpc1024 All Rights Reserved
|
||||
// **/
|
||||
//@Disabled
|
||||
//@SolonTest(classes = TestEasyEsApplication.class)
|
||||
//public class IndexTest {
|
||||
// @Inject
|
||||
// private DocumentMapper documentMapper;
|
||||
//
|
||||
// /**
|
||||
// * 测试创建索引 根据实体类字段及其注解配置创建索引 大多数场景适用,最为简单,但灵活性稍差
|
||||
// * 创建的索引与自动挡-运动模式一样,但触发方式为手动调用 区别是自动挡模式下索引创建及更新随spring容器启动时自动执行
|
||||
// */
|
||||
// @Test
|
||||
// public void testCreateIndexByEntity() {
|
||||
// // 绝大多数场景推荐使用 简单至上
|
||||
// boolean ok = documentMapper.createIndex();
|
||||
// Assertions.assertTrue(ok);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 测试创建索引 根据自定义信息去创建,最为灵活,用此种方式可支持任何es支持的索引
|
||||
// */
|
||||
// @Test
|
||||
// public void testCreateIndex() {
|
||||
// // 复杂场景使用
|
||||
// LambdaEsIndexWrapper<Document> wrapper = new LambdaEsIndexWrapper<>();
|
||||
// // 此处简单起见 索引名称须保持和实体类名称一致,字母小写 后面章节会教大家更如何灵活配置和使用索引
|
||||
// wrapper.indexName(Document.class.getSimpleName().toLowerCase());
|
||||
//
|
||||
// // 此处将文章标题映射为keyword类型(不支持分词),文档内容映射为text类型(支持分词查询)
|
||||
// wrapper.mapping(Document::getTitle, FieldType.KEYWORD, 2.0f)
|
||||
// .mapping(Document::getLocation, FieldType.GEO_POINT)
|
||||
// .mapping(Document::getGeoLocation, FieldType.GEO_SHAPE)
|
||||
// .mapping(Document::getContent, FieldType.TEXT, Analyzer.IK_SMART, Analyzer.IK_MAX_WORD);
|
||||
//
|
||||
// // 0.9.8+版本,增加对符串字段名称的支持,Document实体中须在对应字段上加上@Tablefield(value="wu-la")用于映射此字段值
|
||||
// wrapper.mapping("wu-la", FieldType.TEXT, Analyzer.IK_MAX_WORD, Analyzer.IK_MAX_WORD);
|
||||
//
|
||||
// // 设置分片及副本信息,可缺省
|
||||
// wrapper.settings(3, 2);
|
||||
//
|
||||
// // 设置别名信息,可缺省
|
||||
// String aliasName = "daily";
|
||||
// wrapper.createAlias(aliasName);
|
||||
//
|
||||
// // 设置父子信息,若无父子文档关系则无需设置
|
||||
// wrapper.join("joinField", "document", "comment");
|
||||
//
|
||||
// // 创建索引
|
||||
// boolean isOk = documentMapper.createIndex(wrapper);
|
||||
// Assertions.assertTrue(isOk);
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testExistsIndex() {
|
||||
// // 测试是否存在指定名称的索引
|
||||
// String indexName = Document.class.getSimpleName().toLowerCase();
|
||||
// boolean existsIndex = documentMapper.existsIndex(indexName);
|
||||
// Assertions.assertTrue(existsIndex);
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testGetIndex() {
|
||||
// GetIndexResponse indexResponse = documentMapper.getIndex();
|
||||
// // 这里打印下索引结构信息 其它分片等信息皆可从indexResponse中取
|
||||
// indexResponse.getMappings().forEach((k, v) -> System.out.println(v.getSourceAsMap()));
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testUpdateIndex() {
|
||||
// // 测试更新索引
|
||||
// LambdaEsIndexWrapper<Document> wrapper = new LambdaEsIndexWrapper<>();
|
||||
// // 指定要更新哪个索引
|
||||
// String indexName = Document.class.getSimpleName().toLowerCase();
|
||||
// wrapper.indexName(indexName);
|
||||
// wrapper.mapping(Document::getCreator, FieldType.KEYWORD);
|
||||
// wrapper.mapping(Document::getGmtCreate, FieldType.DATE);
|
||||
// boolean isOk = documentMapper.updateIndex(wrapper);
|
||||
// Assertions.assertTrue(isOk);
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testDeleteIndex() {
|
||||
// // 测试删除索引
|
||||
// // 指定要删除哪个索引
|
||||
// String indexName = Document.class.getSimpleName().toLowerCase();
|
||||
// boolean isOk = documentMapper.deleteIndex(indexName);
|
||||
// Assertions.assertTrue(isOk);
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testCreateIndexByMap() {
|
||||
// // 演示通过自定义map创建索引,最为灵活,若我提供的创建索引API不能满足时可用此方法
|
||||
// LambdaEsIndexWrapper<Document> wrapper = new LambdaEsIndexWrapper<>();
|
||||
// wrapper.indexName(Document.class.getSimpleName().toLowerCase());
|
||||
// wrapper.settings(3, 2);
|
||||
// Map<String, Object> map = new HashMap<>();
|
||||
// Map<String, Object> prop = new HashMap<>();
|
||||
// Map<String, String> field = new HashMap<>();
|
||||
// field.put("type", FieldType.KEYWORD.getType());
|
||||
// prop.put("this_is_field", field);
|
||||
// map.put("properties", prop);
|
||||
// wrapper.mapping(map);
|
||||
// boolean isOk = documentMapper.createIndex(wrapper);
|
||||
// Assertions.assertTrue(isOk);
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testActiveIndex(){
|
||||
// String indexName = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
// documentMapper.setCurrentActiveIndex(indexName);
|
||||
// }
|
||||
//}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
easy-es:
|
||||
# enable: true
|
||||
address: 127.0.0.1:9200
|
||||
address: cdev.rancher.good20.com:30156
|
||||
# schema: http
|
||||
# username: elastic
|
||||
# password: WG7WVmuNMtM4GwNYkyWH
|
||||
username: elastic
|
||||
password: mg123456
|
||||
keep-alive-millis: 18000
|
||||
global-config:
|
||||
i-kun-mode: true
|
||||
|
||||
@ -35,7 +35,6 @@ import org.elasticsearch.search.aggregations.metrics.ParsedAvg;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedMax;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedMin;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedSum;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.elasticsearch.search.sort.FieldSortBuilder;
|
||||
import org.elasticsearch.search.sort.GeoDistanceSortBuilder;
|
||||
import org.elasticsearch.search.sort.SortBuilders;
|
||||
@ -168,7 +167,7 @@ public class XmlScannerAllTest {
|
||||
@Order(4)
|
||||
public void testUpdateBySetSearchSourceBuilder() {
|
||||
LambdaEsUpdateWrapper<Document> wrapper = new LambdaEsUpdateWrapper<>();
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchRequest.Builder();
|
||||
searchSourceBuilder.query(QueryBuilders.termQuery(FieldUtils.val(Document::getTitle) + KEYWORD_SUFFIX, "测试文档2"));
|
||||
wrapper.setSearchSourceBuilder(searchSourceBuilder);
|
||||
|
||||
@ -535,7 +534,7 @@ public class XmlScannerAllTest {
|
||||
@Order(6)
|
||||
public void testSetSearchSourceBuilder() {
|
||||
// 测试混合查询的另一种方式
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchRequest.Builder();
|
||||
searchSourceBuilder.query(QueryBuilders.matchQuery(FieldUtils.val(Document::getCreator), "老汉"));
|
||||
Optional.ofNullable(EntityInfoHelper.getEntityInfo(Document.class))
|
||||
.flatMap(i -> Optional.ofNullable(i.getMaxResultWindow()))
|
||||
@ -928,7 +927,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));
|
||||
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchRequest.Builder();
|
||||
searchSourceBuilder.query(queryBuilder);
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.setSearchSourceBuilder(searchSourceBuilder);
|
||||
|
||||
@ -36,7 +36,6 @@ import org.elasticsearch.search.aggregations.metrics.ParsedAvg;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedMax;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedMin;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedSum;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.elasticsearch.search.sort.FieldSortBuilder;
|
||||
import org.elasticsearch.search.sort.GeoDistanceSortBuilder;
|
||||
import org.elasticsearch.search.sort.SortBuilders;
|
||||
@ -170,7 +169,7 @@ public class AllTest {
|
||||
@Order(4)
|
||||
public void testUpdateBySetSearchSourceBuilder() {
|
||||
LambdaEsUpdateWrapper<Document> wrapper = new LambdaEsUpdateWrapper<>();
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchRequest.Builder();
|
||||
searchSourceBuilder.query(QueryBuilders.termQuery(FieldUtils.val(Document::getTitle) + KEYWORD_SUFFIX, "测试文档2"));
|
||||
wrapper.setSearchSourceBuilder(searchSourceBuilder);
|
||||
|
||||
@ -537,7 +536,7 @@ public class AllTest {
|
||||
@Order(6)
|
||||
public void testSetSearchSourceBuilder() {
|
||||
// 测试混合查询的另一种方式
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchRequest.Builder();
|
||||
searchSourceBuilder.query(QueryBuilders.matchQuery(FieldUtils.val(Document::getCreator), "老汉"));
|
||||
Optional.ofNullable(EntityInfoHelper.getEntityInfo(Document.class))
|
||||
.flatMap(i -> Optional.ofNullable(i.getMaxResultWindow()))
|
||||
@ -930,7 +929,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));
|
||||
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchRequest.Builder();
|
||||
searchSourceBuilder.query(queryBuilder);
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.setSearchSourceBuilder(searchSourceBuilder);
|
||||
|
||||
@ -12,7 +12,6 @@ import org.elasticsearch.index.query.BoolQueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.index.query.TermQueryBuilder;
|
||||
import org.elasticsearch.index.query.TermsQueryBuilder;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -46,7 +45,7 @@ public class CompareTest {
|
||||
TermsQueryBuilder creatorTerm = QueryBuilders.termsQuery("creator", "老汉");
|
||||
boolQueryBuilder.must(titleTerm);
|
||||
boolQueryBuilder.must(creatorTerm);
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchRequest.Builder();
|
||||
searchSourceBuilder.query(boolQueryBuilder);
|
||||
searchRequest.source(searchSourceBuilder);
|
||||
try {
|
||||
|
||||
@ -20,7 +20,7 @@ public class IgnoreTest {
|
||||
//
|
||||
// @Test
|
||||
// public void testSearch0() throws IOException {
|
||||
// SearchRequest.Builder builder = new SearchSourceBuilder();
|
||||
// SearchRequest.Builder builder = new SearchRequest.Builder();
|
||||
// BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
|
||||
//
|
||||
//// boolQueryBuilder.must(QueryBuilders.termQuery("overt", Boolean.TRUE));
|
||||
|
||||
@ -13,7 +13,6 @@ import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.search.aggregations.AggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.AggregationBuilders;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.elasticsearch.search.sort.ScriptSortBuilder;
|
||||
import org.elasticsearch.search.sort.SortBuilders;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
@ -69,7 +68,7 @@ public class MixTest {
|
||||
@Test
|
||||
public void testMix1() {
|
||||
// ElasticsearchClient原生语法
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchRequest.Builder();
|
||||
searchSourceBuilder.query(QueryBuilders.matchQuery("content", "推*").minimumShouldMatch("80%"));
|
||||
|
||||
// 仅利用EE查询并解析数据功能
|
||||
@ -170,7 +169,7 @@ public class MixTest {
|
||||
.match(Document::getContent, "推*");
|
||||
|
||||
// SearchSourceBuilder的构造是自己new出来的,不是通过mapper.getSearchSourceBuilder(wrapper)构造 相当于脱裤子放P,那么上面的查询条件老汉推*自然不会生效
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchRequest.Builder();
|
||||
searchSourceBuilder.minScore(10.5);
|
||||
wrapper.setSearchSourceBuilder(searchSourceBuilder);
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
|
||||
@ -17,7 +17,6 @@ import org.elasticsearch.action.update.UpdateRequest;
|
||||
import org.elasticsearch.client.RequestOptions;
|
||||
import org.elasticsearch.index.query.BoolQueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
|
||||
import org.elasticsearch.xcontent.XContentType;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
@ -74,7 +73,7 @@ public class PerformanceTest {
|
||||
public void testSelectByElasticsearchClient() {
|
||||
// 构建查询条件
|
||||
StopWatch stopwatch = StopWatch.createStarted();
|
||||
SearchRequest.Builder builder = new SearchSourceBuilder();
|
||||
SearchRequest.Builder builder = new SearchRequest.Builder();
|
||||
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
|
||||
boolQueryBuilder.must(QueryBuilders.matchQuery("title", "茶叶"));
|
||||
boolQueryBuilder.must(QueryBuilders.matchQuery("content", "茶叶"));
|
||||
|
||||
@ -10,7 +10,6 @@ import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptType;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@ -60,7 +59,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));
|
||||
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchSourceBuilder();
|
||||
SearchRequest.Builder searchSourceBuilder = new SearchRequest.Builder();
|
||||
searchSourceBuilder.query(queryBuilder);
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.setSearchSourceBuilder(searchSourceBuilder);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user