mirror of
https://gitee.com/dromara/easy-es.git
synced 2025-12-06 17:18:57 +08:00
v2.0.0-beta3
This commit is contained in:
parent
787de793f0
commit
60f0e5a870
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.dromara.easy-es</groupId>
|
||||
<artifactId>easy-es-parent</artifactId>
|
||||
<version>2.0.0-beta2</version>
|
||||
<version>2.0.0-beta3</version>
|
||||
<relativePath>../easy-es-parent</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.dromara.easy-es</groupId>
|
||||
<artifactId>easy-es-parent</artifactId>
|
||||
<version>2.0.0-beta2</version>
|
||||
<version>2.0.0-beta3</version>
|
||||
<relativePath>../easy-es-parent</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -2,6 +2,8 @@ package org.dromara.easyes.starter.config;
|
||||
|
||||
import org.dromara.easyes.core.config.GlobalConfig;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
@ -15,6 +17,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(value = "easy-es")
|
||||
@ConditionalOnExpression("'${easy-es.address:x}'!='x'")
|
||||
@ConditionalOnProperty(prefix = "easy-es", name = {"enable"}, havingValue = "true", matchIfMissing = true)
|
||||
public class EasyEsConfigProperties {
|
||||
/**
|
||||
|
||||
@ -1,18 +1,19 @@
|
||||
package org.dromara.easyes.starter.config;
|
||||
|
||||
import org.dromara.easyes.common.utils.ExceptionUtils;
|
||||
import org.dromara.easyes.common.utils.RestHighLevelClientBuilder;
|
||||
import org.dromara.easyes.common.utils.StringUtils;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.client.CredentialsProvider;
|
||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
import org.dromara.easyes.common.utils.ExceptionUtils;
|
||||
import org.dromara.easyes.common.utils.RestHighLevelClientBuilder;
|
||||
import org.dromara.easyes.common.utils.StringUtils;
|
||||
import org.elasticsearch.client.RestClient;
|
||||
import org.elasticsearch.client.RestClientBuilder;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
@ -35,6 +36,7 @@ import static org.dromara.easyes.common.constants.BaseEsConstants.DEFAULT_SCHEMA
|
||||
@Configuration
|
||||
@ConditionalOnClass(RestHighLevelClient.class)
|
||||
@EnableConfigurationProperties(EasyEsConfigProperties.class)
|
||||
@ConditionalOnExpression("'${easy-es.address:x}'!='x'")
|
||||
@ConditionalOnProperty(prefix = "easy-es", name = {"enable"}, havingValue = "true", matchIfMissing = true)
|
||||
public class EsAutoConfiguration {
|
||||
@Autowired
|
||||
|
||||
@ -10,6 +10,7 @@ import org.dromara.easyes.core.toolkit.IndexUtils;
|
||||
import org.dromara.easyes.starter.service.AutoProcessIndexService;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -20,6 +21,7 @@ import org.springframework.stereotype.Service;
|
||||
**/
|
||||
@Service
|
||||
@ConditionalOnClass(RestHighLevelClient.class)
|
||||
@ConditionalOnExpression("'${easy-es.address:x}'!='x'")
|
||||
@ConditionalOnProperty(prefix = "easy-es", name = {"enable"}, havingValue = "true", matchIfMissing = true)
|
||||
public class AutoProcessIndexNotSmoothlyServiceImpl implements AutoProcessIndexService {
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ import org.dromara.easyes.core.toolkit.IndexUtils;
|
||||
import org.dromara.easyes.starter.service.AutoProcessIndexService;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -23,6 +24,7 @@ import static org.dromara.easyes.common.constants.BaseEsConstants.SO_SUFFIX;
|
||||
**/
|
||||
@Service
|
||||
@ConditionalOnClass(RestHighLevelClient.class)
|
||||
@ConditionalOnExpression("'${easy-es.address:x}'!='x'")
|
||||
@ConditionalOnProperty(prefix = "easy-es", name = {"enable"}, havingValue = "true", matchIfMissing = true)
|
||||
public class AutoProcessIndexSmoothlyServiceImpl implements AutoProcessIndexService {
|
||||
@Override
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.dromara.easy-es</groupId>
|
||||
<artifactId>easy-es-parent</artifactId>
|
||||
<version>2.0.0-beta2</version>
|
||||
<version>2.0.0-beta3</version>
|
||||
<relativePath>../easy-es-parent</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -1,41 +0,0 @@
|
||||
package org.dromara.easyes.common.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 参数类型
|
||||
* <p>
|
||||
* Copyright © 2021 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@AllArgsConstructor
|
||||
public enum BaseEsParamTypeEnum {
|
||||
/**
|
||||
* AND开头左括号 (
|
||||
*/
|
||||
AND_LEFT_BRACKET(1),
|
||||
/**
|
||||
* AND开头右括号 )
|
||||
*/
|
||||
AND_RIGHT_BRACKET(2),
|
||||
/**
|
||||
* OR开头左括号 (
|
||||
*/
|
||||
OR_LEFT_BRACKET(3),
|
||||
/**
|
||||
* OR开头右括号 )
|
||||
*/
|
||||
OR_RIGHT_BRACKET(4),
|
||||
/**
|
||||
* OR 左右括号都包含的情况 比如:
|
||||
* wrapper.eq(User::getName, "张三")
|
||||
* .or()
|
||||
* .eq(Document::getAge, 18);
|
||||
*/
|
||||
OR_ALL(5);
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
@Getter
|
||||
private Integer type;
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
package org.dromara.easyes.common.enums;
|
||||
|
||||
/**
|
||||
* 查询参数Nested类型枚举
|
||||
* <p>
|
||||
* Copyright © 2021 xpc1024 All Rights Reserved
|
||||
**/
|
||||
public enum NestedEnum {
|
||||
/**
|
||||
* 与条件,相当于mysql中的and,必须满足且返回得分
|
||||
*/
|
||||
MUST,
|
||||
/**
|
||||
* 取反的与条件,必须不满足
|
||||
*/
|
||||
MUST_NOT,
|
||||
/**
|
||||
* 与条件必须满足,但不返回得分,效率更高
|
||||
*/
|
||||
FILTER,
|
||||
/**
|
||||
* 或条件,相当于mysql中的or
|
||||
*/
|
||||
SHOULD;
|
||||
}
|
||||
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.dromara.easy-es</groupId>
|
||||
<artifactId>easy-es-parent</artifactId>
|
||||
<version>2.0.0-beta2</version>
|
||||
<version>2.0.0-beta3</version>
|
||||
<relativePath>../easy-es-parent</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -79,6 +79,21 @@ public interface Query<Children, T, R> extends Serializable {
|
||||
return notSelect(Arrays.stream(columns).map(FieldUtils::getFieldNameNotConvertId).toArray(String[]::new));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置最小得分 低于此分值的文档将不召回
|
||||
*
|
||||
* @param score 最小得分
|
||||
* @return wrapper
|
||||
*/
|
||||
Children minScore(Float score);
|
||||
|
||||
/**
|
||||
* 开启计算得分 默认值为关闭状态
|
||||
*
|
||||
* @return wrapper
|
||||
*/
|
||||
Children trackScores();
|
||||
|
||||
/**
|
||||
* 设置不查询字段
|
||||
*
|
||||
@ -116,4 +131,23 @@ public interface Query<Children, T, R> extends Serializable {
|
||||
*/
|
||||
Children index(boolean condition, String... indexNames);
|
||||
|
||||
/**
|
||||
* 设置查询偏好
|
||||
*
|
||||
* @param preference 偏好
|
||||
* @return wrapper
|
||||
*/
|
||||
default Children preference(String preference) {
|
||||
return preference(true, preference);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置查询偏好
|
||||
*
|
||||
* @param condition 条件
|
||||
* @param preference 偏好
|
||||
* @return wrapper
|
||||
*/
|
||||
Children preference(boolean condition, String preference);
|
||||
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
package org.dromara.easyes.core.config;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
import org.dromara.easyes.annotation.rely.FieldStrategy;
|
||||
import org.dromara.easyes.annotation.rely.IdType;
|
||||
import org.dromara.easyes.common.enums.ProcessIndexStrategyEnum;
|
||||
import org.dromara.easyes.common.enums.RefreshPolicy;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
|
||||
import static org.dromara.easyes.common.constants.BaseEsConstants.EMPTY_STR;
|
||||
@ -22,9 +22,9 @@ public class GlobalConfig {
|
||||
*/
|
||||
private boolean printDsl = true;
|
||||
/**
|
||||
* process index mode Smoothly by default 索引处理模式 默认开启平滑模式
|
||||
* process index mode Manual by default 索引处理模式 默认开启手动模式
|
||||
*/
|
||||
private ProcessIndexStrategyEnum processIndexMode = ProcessIndexStrategyEnum.SMOOTHLY;
|
||||
private ProcessIndexStrategyEnum processIndexMode = ProcessIndexStrategyEnum.MANUAL;
|
||||
/**
|
||||
* Rebuild index timeout unit: hour, default: 72 重建索引超时时间 单位小时,默认72
|
||||
*/
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
package org.dromara.easyes.core.core;
|
||||
|
||||
import org.apache.lucene.search.join.ScoreMode;
|
||||
import org.dromara.easyes.annotation.rely.FieldType;
|
||||
import org.dromara.easyes.core.biz.EntityFieldInfo;
|
||||
import org.dromara.easyes.core.biz.OrderByParam;
|
||||
import org.apache.lucene.search.join.ScoreMode;
|
||||
import org.dromara.easyes.core.conditions.function.*;
|
||||
import org.elasticsearch.common.geo.GeoDistance;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
@ -678,6 +678,18 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children minScore(Float score) {
|
||||
getWrapper().minScore(score);
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children trackScores() {
|
||||
getWrapper().trackScores();
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children index(boolean condition, String... indexNames) {
|
||||
getWrapper().index(condition, indexNames);
|
||||
@ -696,6 +708,12 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children preference(boolean condition, String preference) {
|
||||
getWrapper().preference(condition, preference);
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children maxResultWindow(Integer maxResultWindow) {
|
||||
getWrapper().maxResultWindow(maxResultWindow);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package org.dromara.easyes.core.core;
|
||||
|
||||
import org.apache.lucene.search.join.ScoreMode;
|
||||
import org.dromara.easyes.annotation.rely.FieldType;
|
||||
import org.dromara.easyes.common.enums.AggregationTypeEnum;
|
||||
import org.dromara.easyes.common.enums.EsQueryTypeEnum;
|
||||
@ -8,7 +9,6 @@ import org.dromara.easyes.common.utils.*;
|
||||
import org.dromara.easyes.core.biz.*;
|
||||
import org.dromara.easyes.core.conditions.function.*;
|
||||
import org.dromara.easyes.core.toolkit.EntityInfoHelper;
|
||||
import org.apache.lucene.search.join.ScoreMode;
|
||||
import org.elasticsearch.common.geo.GeoDistance;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.geo.ShapeRelation;
|
||||
@ -261,8 +261,6 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
|
||||
|
||||
@Override
|
||||
public Children between(boolean condition, String column, Object from, Object to, ZoneId timeZone, String format, Float boost) {
|
||||
Assert.notNull(from, "from must not be null in between query");
|
||||
Assert.notNull(to, "to must not be null in between query");
|
||||
return addParam(condition, column, from, to, timeZone, format, boost);
|
||||
}
|
||||
|
||||
@ -529,15 +527,26 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
|
||||
|
||||
@Override
|
||||
public Children index(boolean condition, String... indexNames) {
|
||||
if (ArrayUtils.isEmpty(indexNames)) {
|
||||
throw ExceptionUtils.eee("indexNames can not be empty");
|
||||
}
|
||||
if (condition) {
|
||||
if (ArrayUtils.isEmpty(indexNames)) {
|
||||
throw ExceptionUtils.eee("indexNames can not be empty");
|
||||
}
|
||||
this.indexNames = indexNames;
|
||||
}
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children preference(boolean condition, String preference) {
|
||||
if (condition) {
|
||||
if (StringUtils.isBlank(preference)) {
|
||||
return typedThis;
|
||||
}
|
||||
this.preference = preference;
|
||||
}
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children setSearchSourceBuilder(boolean condition, SearchSourceBuilder searchSourceBuilder) {
|
||||
if (condition) {
|
||||
@ -570,6 +579,18 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children minScore(Float score) {
|
||||
minScore = score;
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children trackScores() {
|
||||
trackScores = Boolean.TRUE;
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children notSelect(String... columns) {
|
||||
this.exclude = columns;
|
||||
@ -689,7 +710,7 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
|
||||
}
|
||||
|
||||
/**
|
||||
* 追加基础嵌套
|
||||
* 追加基础嵌套 整个框架最难的点之一
|
||||
*
|
||||
* @param param 参数
|
||||
* @param queryTypeEnum 查询类型
|
||||
@ -706,13 +727,6 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
|
||||
// 入队之前需要先对MP中的拼接类型特殊处理
|
||||
processJoin(param);
|
||||
|
||||
// 这两种情况需要重置其prevType
|
||||
if (NESTED_NOT.equals(queryTypeEnum)) {
|
||||
prevQueryType = NESTED_NOT;
|
||||
} else if (NESTED_FILTER.equals(queryTypeEnum)) {
|
||||
prevQueryType = NESTED_FILTER;
|
||||
}
|
||||
|
||||
paramQueue.add(param);
|
||||
this.parentId = param.getId();
|
||||
parentIdStack.push(parentId);
|
||||
@ -827,6 +841,8 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
|
||||
*/
|
||||
private Children addParam(boolean condition, String column, Object var1, Object var2, Object var3, Object var4, Float boost) {
|
||||
if (condition) {
|
||||
Assert.notNull(var1, "from must not be null in between query");
|
||||
Assert.notNull(var2, "to must not be null in between query");
|
||||
Param param = new Param();
|
||||
param.setExt1(var1);
|
||||
param.setExt2(var2);
|
||||
|
||||
@ -20,6 +20,13 @@ import java.util.List;
|
||||
* Copyright © 2021 xpc1024 All Rights Reserved
|
||||
**/
|
||||
public interface BaseEsMapper<T> {
|
||||
/**
|
||||
* 获取mapper中的entityClass
|
||||
*
|
||||
* @return entityClass
|
||||
*/
|
||||
Class<T> getEntityClass();
|
||||
|
||||
/**
|
||||
* 是否存在索引
|
||||
*
|
||||
|
||||
@ -1,18 +1,5 @@
|
||||
package org.dromara.easyes.core.core;
|
||||
|
||||
import org.dromara.easyes.annotation.rely.FieldStrategy;
|
||||
import org.dromara.easyes.annotation.rely.IdType;
|
||||
import org.dromara.easyes.common.constants.BaseEsConstants;
|
||||
import org.dromara.easyes.common.enums.EsQueryTypeEnum;
|
||||
import org.dromara.easyes.common.enums.MethodEnum;
|
||||
import org.dromara.easyes.common.utils.*;
|
||||
import org.dromara.easyes.core.biz.*;
|
||||
import org.dromara.easyes.core.cache.BaseCache;
|
||||
import org.dromara.easyes.core.cache.GlobalConfigCache;
|
||||
import org.dromara.easyes.core.toolkit.EntityInfoHelper;
|
||||
import org.dromara.easyes.core.toolkit.FieldUtils;
|
||||
import org.dromara.easyes.core.toolkit.IndexUtils;
|
||||
import org.dromara.easyes.core.toolkit.PageHelper;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.serializer.SerializeFilter;
|
||||
@ -21,6 +8,20 @@ import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
|
||||
import lombok.Setter;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.dromara.easyes.annotation.rely.FieldStrategy;
|
||||
import org.dromara.easyes.annotation.rely.IdType;
|
||||
import org.dromara.easyes.common.constants.BaseEsConstants;
|
||||
import org.dromara.easyes.common.enums.EsQueryTypeEnum;
|
||||
import org.dromara.easyes.common.enums.MethodEnum;
|
||||
import org.dromara.easyes.common.enums.RefreshPolicy;
|
||||
import org.dromara.easyes.common.utils.*;
|
||||
import org.dromara.easyes.core.biz.*;
|
||||
import org.dromara.easyes.core.cache.BaseCache;
|
||||
import org.dromara.easyes.core.cache.GlobalConfigCache;
|
||||
import org.dromara.easyes.core.toolkit.EntityInfoHelper;
|
||||
import org.dromara.easyes.core.toolkit.FieldUtils;
|
||||
import org.dromara.easyes.core.toolkit.IndexUtils;
|
||||
import org.dromara.easyes.core.toolkit.PageHelper;
|
||||
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
|
||||
import org.elasticsearch.action.admin.indices.refresh.RefreshResponse;
|
||||
import org.elasticsearch.action.bulk.BulkItemResponse;
|
||||
@ -90,6 +91,11 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
@Setter
|
||||
private Class<T> entityClass;
|
||||
|
||||
@Override
|
||||
public Class<T> getEntityClass() {
|
||||
return entityClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean existsIndex(String indexName) {
|
||||
if (StringUtils.isEmpty(indexName)) {
|
||||
@ -187,6 +193,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
public String executeDSL(String dsl, String indexName) {
|
||||
Assert.notNull(indexName, "indexName must not null");
|
||||
Request request = new Request(MethodEnum.GET.name(), indexName + DSL_ENDPOINT);
|
||||
request.setJsonEntity(dsl);
|
||||
Response response = client.getLowLevelClient().performRequest(request);
|
||||
return EntityUtils.toString(response.getEntity());
|
||||
}
|
||||
@ -221,6 +228,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
public String getSource(Wrapper<T> wrapper) {
|
||||
// 获取由本框架生成的es查询参数 用于验证生成语法的正确性
|
||||
SearchRequest searchRequest = new SearchRequest(getIndexNames(wrapper.indexNames));
|
||||
Optional.ofNullable(wrapper.preference).ifPresent(searchRequest::preference);
|
||||
Optional.ofNullable(getRouting()).ifPresent(searchRequest::routing);
|
||||
SearchSourceBuilder searchSourceBuilder = WrapperProcessor.buildSearchSourceBuilder(wrapper, entityClass);
|
||||
searchRequest.source(searchSourceBuilder);
|
||||
@ -302,6 +310,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
// 不去重,直接count获取,效率更高
|
||||
CountRequest countRequest = new CountRequest(getIndexNames(wrapper.indexNames));
|
||||
Optional.ofNullable(getRouting()).ifPresent(countRequest::routing);
|
||||
Optional.ofNullable(wrapper.preference).ifPresent(countRequest::preference);
|
||||
QueryBuilder queryBuilder = Optional.ofNullable(wrapper.searchSourceBuilder)
|
||||
.map(SearchSourceBuilder::query)
|
||||
.orElseGet(() -> WrapperProcessor.initBoolQueryBuilder(wrapper.paramQueue, entityClass));
|
||||
@ -379,6 +388,13 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
@Override
|
||||
public Integer delete(Wrapper<T> wrapper) {
|
||||
DeleteByQueryRequest request = new DeleteByQueryRequest(getIndexNames(wrapper.indexNames));
|
||||
EntityInfo entityInfo = EntityInfoHelper.getEntityInfo(entityClass);
|
||||
Optional.ofNullable(entityInfo)
|
||||
.flatMap(i->Optional.ofNullable(i.getMaxResultWindow()))
|
||||
.ifPresent(request::setBatchSize);
|
||||
if (RefreshPolicy.IMMEDIATE.getValue().equals(getRefreshPolicy())) {
|
||||
request.setRefresh(true);
|
||||
}
|
||||
Optional.ofNullable(getRouting()).ifPresent(request::setRouting);
|
||||
BoolQueryBuilder boolQueryBuilder = WrapperProcessor.initBoolQueryBuilder(wrapper.paramQueue, entityClass);
|
||||
request.setQuery(boolQueryBuilder);
|
||||
@ -474,28 +490,6 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<T> doSelectBatchIds(Collection<? extends Serializable> idList, String indexName) {
|
||||
// 构造查询参数
|
||||
List<String> stringIdList = idList.stream().map(Object::toString).collect(Collectors.toList());
|
||||
SearchRequest searchRequest = new SearchRequest(getIndexNames(indexName));
|
||||
Optional.ofNullable(getRouting()).ifPresent(searchRequest::routing);
|
||||
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
|
||||
sourceBuilder.query(QueryBuilders.termsQuery(DEFAULT_ES_ID_NAME, stringIdList));
|
||||
sourceBuilder.size(idList.size());
|
||||
searchRequest.source(sourceBuilder);
|
||||
|
||||
// 请求es获取数据
|
||||
SearchHit[] searchHitArray = getSearchHitArray(searchRequest);
|
||||
if (ArrayUtils.isEmpty(searchHitArray)) {
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
|
||||
// 批量解析数据
|
||||
return Arrays.stream(searchHitArray)
|
||||
.map(this::parseOne)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public T selectOne(Wrapper<T> wrapper) {
|
||||
// 请求es获取数据
|
||||
@ -792,6 +786,36 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
return doBulkRequest(bulkRequest, RequestOptions.DEFAULT);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 执行根据id批量查询
|
||||
*
|
||||
* @param idList id数组
|
||||
* @param indexName 索引名
|
||||
* @return 数据
|
||||
*/
|
||||
private List<T> doSelectBatchIds(Collection<? extends Serializable> idList, String indexName) {
|
||||
// 构造查询参数
|
||||
List<String> stringIdList = idList.stream().map(Object::toString).collect(Collectors.toList());
|
||||
SearchRequest searchRequest = new SearchRequest(getIndexNames(indexName));
|
||||
Optional.ofNullable(getRouting()).ifPresent(searchRequest::routing);
|
||||
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
|
||||
sourceBuilder.query(QueryBuilders.termsQuery(DEFAULT_ES_ID_NAME, stringIdList));
|
||||
sourceBuilder.size(idList.size());
|
||||
searchRequest.source(sourceBuilder);
|
||||
|
||||
// 请求es获取数据
|
||||
SearchHit[] searchHitArray = getSearchHitArray(searchRequest);
|
||||
if (ArrayUtils.isEmpty(searchHitArray)) {
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
|
||||
// 批量解析数据
|
||||
return Arrays.stream(searchHitArray)
|
||||
.map(this::parseOne)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行根据id查询
|
||||
*
|
||||
@ -829,6 +853,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
// 构建es restHighLevelClient 查询参数
|
||||
SearchRequest searchRequest = new SearchRequest(getIndexNames(wrapper.indexNames));
|
||||
Optional.ofNullable(getRouting()).ifPresent(searchRequest::routing);
|
||||
Optional.ofNullable(wrapper.preference).ifPresent(searchRequest::preference);
|
||||
|
||||
// 用户在wrapper中指定的混合查询条件优先级最高
|
||||
SearchSourceBuilder searchSourceBuilder = Optional.ofNullable(wrapper.searchSourceBuilder)
|
||||
@ -882,6 +907,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
// 构建查询条件
|
||||
SearchRequest searchRequest = new SearchRequest(indexName);
|
||||
Optional.ofNullable(getRouting()).ifPresent(searchRequest::routing);
|
||||
Optional.ofNullable(wrapper.preference).ifPresent(searchRequest::preference);
|
||||
SearchSourceBuilder searchSourceBuilder;
|
||||
if (Objects.isNull(wrapper.searchSourceBuilder)) {
|
||||
searchSourceBuilder = new SearchSourceBuilder();
|
||||
@ -894,7 +920,10 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
}
|
||||
searchSourceBuilder.fetchSource(includes, null);
|
||||
searchSourceBuilder.trackTotalHits(true);
|
||||
searchSourceBuilder.size(GlobalConfigCache.getGlobalConfig().getDbConfig().getBatchUpdateThreshold());
|
||||
int size = Optional.ofNullable(entityInfo)
|
||||
.map(EntityInfo::getMaxResultWindow)
|
||||
.orElse(GlobalConfigCache.getGlobalConfig().getDbConfig().getBatchUpdateThreshold());
|
||||
searchSourceBuilder.size(size);
|
||||
BoolQueryBuilder boolQueryBuilder = WrapperProcessor.initBoolQueryBuilder(wrapper.paramQueue, entityClass);
|
||||
searchSourceBuilder.query(boolQueryBuilder);
|
||||
} else {
|
||||
@ -1150,6 +1179,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
private SearchHit[] getSearchHitArray(Wrapper<T> wrapper) {
|
||||
SearchRequest searchRequest = new SearchRequest(getIndexNames(wrapper.indexNames));
|
||||
Optional.ofNullable(getRouting()).ifPresent(searchRequest::routing);
|
||||
Optional.ofNullable(wrapper.preference).ifPresent(searchRequest::preference);
|
||||
|
||||
// 用户在wrapper中指定的混合查询条件优先级最高
|
||||
SearchSourceBuilder searchSourceBuilder = Objects.isNull(wrapper.searchSourceBuilder) ?
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package org.dromara.easyes.core.core;
|
||||
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import org.dromara.easyes.core.biz.*;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
@ -35,6 +36,14 @@ public abstract class Wrapper<T> implements Cloneable {
|
||||
* 不查字段
|
||||
*/
|
||||
protected String[] exclude;
|
||||
/**
|
||||
* 排除_score 小于 min_score 中指定的最小值的文档
|
||||
*/
|
||||
protected Float minScore;
|
||||
/**
|
||||
* 自定义排序时(如 脚本里面使用 _score),是否计算分数
|
||||
*/
|
||||
protected Boolean trackScores;
|
||||
/**
|
||||
* 从第多少条开始查询
|
||||
*/
|
||||
@ -43,6 +52,10 @@ public abstract class Wrapper<T> implements Cloneable {
|
||||
* 查询多少条记录
|
||||
*/
|
||||
protected Integer size;
|
||||
/**
|
||||
* 当前查询的查询偏好
|
||||
*/
|
||||
protected String preference;
|
||||
/**
|
||||
* 当前操作作用的索引名数组
|
||||
*/
|
||||
@ -109,8 +122,9 @@ public abstract class Wrapper<T> implements Cloneable {
|
||||
*
|
||||
* @return Wrapper
|
||||
*/
|
||||
@SneakyThrows
|
||||
protected Wrapper<T> clone() {
|
||||
return this.clone();
|
||||
return (Wrapper<T>) super.clone();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -136,8 +136,7 @@ public class WrapperProcessor {
|
||||
setBool(bool, queryBuilder, param.getPrevQueryType());
|
||||
break;
|
||||
case QUERY_STRING:
|
||||
realField = getRealFieldAndSuffix(param.getColumn(), fieldTypeMap, mappingColumnMap);
|
||||
queryBuilder = QueryBuilders.queryStringQuery(realField).boost(param.getBoost());
|
||||
queryBuilder = QueryBuilders.queryStringQuery(param.getColumn()).boost(param.getBoost());
|
||||
setBool(bool, queryBuilder, param.getPrevQueryType());
|
||||
break;
|
||||
case PREFIX:
|
||||
@ -335,12 +334,19 @@ public class WrapperProcessor {
|
||||
// 设置查询或不查询字段
|
||||
setFetchSource(wrapper, mappingColumnMap, searchSourceBuilder);
|
||||
|
||||
// 设置排除_score 小于 min_score 中指定的最小值的文档
|
||||
Optional.ofNullable(wrapper.minScore).ifPresent(searchSourceBuilder::minScore);
|
||||
|
||||
// 设置自定义排序时(如 脚本里面使用 _score) 是否计算分数
|
||||
Optional.ofNullable(wrapper.trackScores).ifPresent(searchSourceBuilder::trackScores);
|
||||
|
||||
// 设置聚合参数
|
||||
setAggregations(wrapper, mappingColumnMap, searchSourceBuilder);
|
||||
|
||||
// 设置查询起止参数
|
||||
Optional.ofNullable(wrapper.from).ifPresent(searchSourceBuilder::from);
|
||||
MyOptional.ofNullable(wrapper.size).ifPresent(searchSourceBuilder::size, DEFAULT_SIZE);
|
||||
MyOptional.ofNullable(wrapper.size).ifPresent(searchSourceBuilder::size,
|
||||
entityInfo.getMaxResultWindow() != null ? entityInfo.getMaxResultWindow() : DEFAULT_SIZE);
|
||||
|
||||
// 根据全局配置决定是否开启全部查询
|
||||
if (GlobalConfigCache.getGlobalConfig().getDbConfig().isEnableTrackTotalHits()) {
|
||||
@ -556,7 +562,7 @@ public class WrapperProcessor {
|
||||
aggregationBuilder = AggregationBuilders.sum(name).field(realField);
|
||||
break;
|
||||
case TERMS:
|
||||
aggregationBuilder = AggregationBuilders.terms(name).field(realField).size(Integer.MAX_VALUE);
|
||||
aggregationBuilder = AggregationBuilders.terms(name).field(realField);
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("不支持的聚合类型,参见AggregationTypeEnum");
|
||||
|
||||
@ -347,6 +347,8 @@ public class IndexUtils {
|
||||
type = FieldType.DOUBLE.getType();
|
||||
break;
|
||||
case BIG_DECIMAL:
|
||||
type = FieldType.SCALED_FLOAT.getType();
|
||||
break;
|
||||
case STRING:
|
||||
case CHAR:
|
||||
type = FieldType.KEYWORD_TEXT.getType();
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.dromara.easy-es</groupId>
|
||||
<artifactId>easy-es-parent</artifactId>
|
||||
<version>2.0.0-beta2</version>
|
||||
<version>2.0.0-beta3</version>
|
||||
<relativePath>../easy-es-parent</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>org.dromara.easy-es</groupId>
|
||||
<artifactId>easy-es-parent</artifactId>
|
||||
<version>2.0.0-beta2</version>
|
||||
<version>2.0.0-beta3</version>
|
||||
|
||||
<name>easy-es-parent</name>
|
||||
<description>easy use for elastic search</description>
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.dromara.easy-es</groupId>
|
||||
<artifactId>easy-es</artifactId>
|
||||
<version>2.0.0-beta2</version>
|
||||
<version>2.0.0-beta3</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
@ -58,6 +58,14 @@ public class AllTest {
|
||||
@Resource
|
||||
private DocumentMapper documentMapper;
|
||||
|
||||
@Test
|
||||
@Order(0)
|
||||
public void testCreateIndex() {
|
||||
// 0.前置操作 创建索引 需确保索引托管模式处于manual手动挡,若为自动挡则会冲突.
|
||||
boolean success = documentMapper.createIndex();
|
||||
Assertions.assertTrue(success);
|
||||
}
|
||||
|
||||
// 1.新增
|
||||
@Test
|
||||
@Order(1)
|
||||
@ -181,7 +189,7 @@ public class AllTest {
|
||||
@Test
|
||||
@Order(6)
|
||||
public void testDSL() {
|
||||
String dsl = "{\"size\":10000,\"query\":{\"bool\":{\"must\":[{\"term\":{\"title.keyword\":{\"value\":\"测试文档2\",\"boost\":1.0}}}],\"adjust_pure_negative\":true,\"boost\":1.0}}\"track_total_hits\":2147483647}";
|
||||
String dsl = "{\"query\":{\"bool\":{\"must\":[{\"term\":{\"title.keyword\":{\"value\":\"测试文档3\",\"boost\":1.0}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"track_total_hits\":2147483647,\"highlight\":{\"pre_tags\":[\"<em>\"],\"post_tags\":[\"</em>\"],\"fragment_size\":2,\"fields\":{\"content\":{\"type\":\"unified\"}}}}";
|
||||
String jsonResult = documentMapper.executeDSL(dsl);
|
||||
System.out.println(jsonResult);
|
||||
Assertions.assertNotNull(jsonResult);
|
||||
@ -191,7 +199,6 @@ public class AllTest {
|
||||
@Order(6)
|
||||
public void testSelectOne() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
|
||||
wrapper.match(Document::getContent, "内容")
|
||||
.orderByAsc(Document::getStarNum, Document::getEsId)
|
||||
.limit(1);
|
||||
@ -233,20 +240,20 @@ public class AllTest {
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void testIgnoreCase(){
|
||||
public void testIgnoreCase() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.eq(Document::getCaseTest,"test");
|
||||
wrapper.eq(Document::getCaseTest, "test");
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
Assertions.assertEquals(1,documents.size());
|
||||
Assertions.assertEquals(1, documents.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void testIp(){
|
||||
public void testIp() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.eq(Document::getIpAddress,"192.168.0.0/16");
|
||||
wrapper.eq(Document::getIpAddress, "192.168.0.0/16");
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
Assertions.assertEquals(documents.size(),1);
|
||||
Assertions.assertEquals(documents.size(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -258,6 +265,16 @@ public class AllTest {
|
||||
Assertions.assertEquals(22L, count);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void testSelectCountDistinct() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.match(Document::getCustomField, "字段");
|
||||
wrapper.distinct(Document::getStarNum);
|
||||
Long count = documentMapper.selectCount(wrapper, true);
|
||||
Assertions.assertEquals(21L, count);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void testConditionAllEq() {
|
||||
@ -498,7 +515,9 @@ public class AllTest {
|
||||
// 测试混合查询的另一种方式
|
||||
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
|
||||
searchSourceBuilder.query(QueryBuilders.matchQuery(FieldUtils.val(Document::getCreator), "老汉"));
|
||||
searchSourceBuilder.size(BaseEsConstants.DEFAULT_SIZE);
|
||||
Optional.ofNullable(EntityInfoHelper.getEntityInfo(Document.class))
|
||||
.flatMap(i -> Optional.ofNullable(i.getMaxResultWindow()))
|
||||
.ifPresent(searchSourceBuilder::size);
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.setSearchSourceBuilder(searchSourceBuilder);
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
@ -541,7 +560,7 @@ public class AllTest {
|
||||
public void testConditionFilter() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.eq(Document::getStarNum, 10)
|
||||
.filter(i -> i.eq(Document::getTitle, "测试文档10"));
|
||||
.filter().eq(Document::getTitle, "测试文档10");
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
Assertions.assertEquals(1, documents.size());
|
||||
}
|
||||
@ -550,8 +569,8 @@ public class AllTest {
|
||||
@Order(6)
|
||||
public void testConditionNot() {
|
||||
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.in(Document::getStarNum, 10,11,12,13)
|
||||
.not(i->i.eq(Document::getTitle,"测试文档10").eq(Document::getTitle,"测试文档11"));
|
||||
wrapper.in(Document::getStarNum, 10, 11, 12, 13)
|
||||
.and(i -> i.not().eq(Document::getTitle, "测试文档10").not().eq(Document::getTitle, "测试文档11"));
|
||||
List<Document> documents = documentMapper.selectList(wrapper);
|
||||
Assertions.assertEquals(2, documents.size());
|
||||
}
|
||||
@ -919,4 +938,5 @@ public class AllTest {
|
||||
.or(i -> i.eq("business_type", 2).in("state", 2, 3));
|
||||
documentMapper.selectList(wrapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
easy-es:
|
||||
enable: true
|
||||
# enable: true
|
||||
address: 10.20.64.228:9200
|
||||
schema: http
|
||||
username: elastic
|
||||
password: WG7WVmuNMtM4GwNYkyWH
|
||||
# username: elastic
|
||||
# password: WG7WVmuNMtM4GwNYkyWH
|
||||
keep-alive-millis: 18000
|
||||
global-config:
|
||||
process-index-mode: smoothly
|
||||
process-index-mode: manual
|
||||
async-process-index-blocking: true
|
||||
print-dsl: true
|
||||
db-config:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user