mirror of
https://gitee.com/dromara/easy-es.git
synced 2025-12-06 17:18:57 +08:00
v2.0.0-beta6
1.新增父子类型对一父多子以及一父多子多孙场景的索引自动化支持 2.增加对父子类型所有查询功能支持 3.所有CRUD方法支持方法粒度的自定义路由功能 4.提供全新自定义注解@Settings,支持便捷预设与灵活自定义功能,可支持ES索引中所有Settings的编辑处理 5.javadoc及注释和部分代码细节优化 6.其它优化持续更新中...
This commit is contained in:
parent
46a0081fad
commit
53b906da78
@ -5,6 +5,8 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static org.dromara.easyes.annotation.rely.AnnotationConstants.DEFAULT_JOIN_FIELD_NAME;
|
||||
|
||||
/**
|
||||
* 父子类型
|
||||
* <p>
|
||||
@ -13,8 +15,24 @@ import java.lang.annotation.Target;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface Join {
|
||||
String joinField() default "joinField";
|
||||
/**
|
||||
* join字段在es中的名字
|
||||
*
|
||||
* @return 索引中的join字段名称 默认为joinField
|
||||
*/
|
||||
String joinField() default DEFAULT_JOIN_FIELD_NAME;
|
||||
|
||||
/**
|
||||
* 根节点别名 不指定则默认使用加了当前注解的根类的名称小写作为根节点别名(推荐)
|
||||
*
|
||||
* @return 根节点别名
|
||||
*/
|
||||
String rootAlias() default "";
|
||||
|
||||
Child[] children() default {};
|
||||
/**
|
||||
* 非根节点
|
||||
*
|
||||
* @return 非根节点列表
|
||||
*/
|
||||
Node[] nodes() default {};
|
||||
}
|
||||
|
||||
@ -12,9 +12,9 @@ import java.lang.annotation.Target;
|
||||
**/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
|
||||
public @interface Child {
|
||||
public @interface Node {
|
||||
/**
|
||||
* 父文档别名 非必填,默认值为当前类名小写
|
||||
* 父文档别名 非必填,不指定时默认值为parentClass类名小写(推荐)
|
||||
*
|
||||
* @return 父文档别名
|
||||
*/
|
||||
@ -28,9 +28,9 @@ public @interface Child {
|
||||
Class<?> parentClass();
|
||||
|
||||
/**
|
||||
* 子文档别名列表
|
||||
* 子文档别名列表,不指定则为子文档类名小写列表(推荐) 若要自定义必须与childClasses数量和顺序一致
|
||||
*
|
||||
* @return 子文档别名列表 非必填,默认值为子文档类名小写
|
||||
* @return 子文档别名列表 非必填,默认值为子文档类名小写列表
|
||||
*/
|
||||
String[] childAliases() default {};
|
||||
|
||||
@ -34,4 +34,8 @@ public interface AnnotationConstants {
|
||||
* 默认索引别名
|
||||
*/
|
||||
String DEFAULT_ALIAS = "ee_default_alias";
|
||||
/**
|
||||
* 默认join字段名称
|
||||
*/
|
||||
String DEFAULT_JOIN_FIELD_NAME = "joinField";
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import org.elasticsearch.common.geo.GeoDistance;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.unit.DistanceUnit;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.search.aggregations.BucketOrder;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.elasticsearch.search.sort.SortBuilder;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
@ -13,8 +14,8 @@ import org.elasticsearch.search.sort.SortOrder;
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
||||
import static org.dromara.easyes.common.constants.BaseEsConstants.DEFAULT_BOOST;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.dromara.easyes.common.constants.BaseEsConstants.DEFAULT_BOOST;
|
||||
|
||||
/**
|
||||
* 高阶语法相关
|
||||
@ -1704,4 +1705,45 @@ public interface Func<Children, R> extends Serializable {
|
||||
* @return wrapper
|
||||
*/
|
||||
Children mix(boolean condition, QueryBuilder queryBuilder);
|
||||
|
||||
|
||||
/**
|
||||
* 聚合桶排序
|
||||
*
|
||||
* @param bucketOrder 排序规则
|
||||
* @return wrapper
|
||||
*/
|
||||
default Children bucketOrder(BucketOrder bucketOrder) {
|
||||
return bucketOrder(true, bucketOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
* 聚合桶排序
|
||||
*
|
||||
* @param condition 条件
|
||||
* @param bucketOrder 桶排序规则
|
||||
* @return wrapper
|
||||
*/
|
||||
default Children bucketOrder(boolean condition, BucketOrder bucketOrder) {
|
||||
return bucketOrder(condition, Arrays.asList(bucketOrder));
|
||||
}
|
||||
|
||||
/**
|
||||
* 聚合桶排序
|
||||
*
|
||||
* @param bucketOrders 排序规则列表
|
||||
* @return wrapper
|
||||
*/
|
||||
default Children bucketOrder(List<BucketOrder> bucketOrders) {
|
||||
return bucketOrder(true, bucketOrders);
|
||||
}
|
||||
|
||||
/**
|
||||
* 聚合桶排序
|
||||
*
|
||||
* @param condition 条件
|
||||
* @param bucketOrders 排序规则列表
|
||||
* @return wrapper
|
||||
*/
|
||||
Children bucketOrder(boolean condition, List<BucketOrder> bucketOrders);
|
||||
}
|
||||
|
||||
@ -214,6 +214,15 @@ public interface Nested<Param, Children> extends Serializable {
|
||||
*/
|
||||
Children hasChild(boolean condition, String type, Consumer<Param> consumer, ScoreMode scoreMode);
|
||||
|
||||
/**
|
||||
* 父子类型-根据子查父匹配 返回子文档 无需指定父,由框架根据@Join注解自行推断其父
|
||||
*
|
||||
* @param consumer 嵌套条件函数
|
||||
* @return wrapper
|
||||
*/
|
||||
default Children hasParent(Consumer<Param> consumer) {
|
||||
return hasParent(true, null, consumer);
|
||||
}
|
||||
|
||||
/**
|
||||
* 父子类型-根据子查父匹配 返回子文档
|
||||
|
||||
@ -13,6 +13,7 @@ import org.elasticsearch.common.unit.DistanceUnit;
|
||||
import org.elasticsearch.geometry.Geometry;
|
||||
import org.elasticsearch.index.query.Operator;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.search.aggregations.BucketOrder;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.elasticsearch.search.sort.SortBuilder;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
@ -654,6 +655,13 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Children bucketOrder(boolean condition, List<BucketOrder> bucketOrders) {
|
||||
getWrapper().bucketOrder(condition, bucketOrders);
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children select(String... columns) {
|
||||
getWrapper().select(columns);
|
||||
|
||||
@ -17,6 +17,7 @@ import org.elasticsearch.common.unit.DistanceUnit;
|
||||
import org.elasticsearch.geometry.Geometry;
|
||||
import org.elasticsearch.index.query.Operator;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.search.aggregations.BucketOrder;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.elasticsearch.search.sort.SortBuilder;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
@ -567,6 +568,14 @@ public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T,
|
||||
return addParam(condition, queryBuilder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children bucketOrder(boolean condition, List<BucketOrder> bucketOrders) {
|
||||
if (condition) {
|
||||
this.bucketOrders = bucketOrders;
|
||||
}
|
||||
return typedThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Children select(String... columns) {
|
||||
this.include = columns;
|
||||
|
||||
@ -224,11 +224,21 @@ public interface BaseEsMapper<T> {
|
||||
/**
|
||||
* 插入一条记录 可指定路由
|
||||
*
|
||||
* @param entity 插入的数据对象
|
||||
* @param routing 路由
|
||||
* @param entity 插入的数据对象
|
||||
* @return 成功条数
|
||||
*/
|
||||
Integer insert(T entity, String routing);
|
||||
Integer insert(String routing, T entity);
|
||||
|
||||
/**
|
||||
* 父子类型 插入一条记录 可指定路由, 父id
|
||||
*
|
||||
* @param routing 路由
|
||||
* @param parentId 父id
|
||||
* @param entity 插入的数据对象
|
||||
* @return 成功条数
|
||||
*/
|
||||
Integer insert(String routing, String parentId, T entity);
|
||||
|
||||
/**
|
||||
* 插入一条记录,可指定多索引插入
|
||||
@ -240,7 +250,7 @@ public interface BaseEsMapper<T> {
|
||||
Integer insert(T entity, String... indexNames);
|
||||
|
||||
/**
|
||||
* 插入一条记录,可指定路由及多索引插入
|
||||
* 插入数据,可指定路由及多索引插入
|
||||
*
|
||||
* @param routing 路由
|
||||
* @param entity 插入的数据对象
|
||||
@ -249,6 +259,16 @@ public interface BaseEsMapper<T> {
|
||||
*/
|
||||
Integer insert(String routing, T entity, String... indexNames);
|
||||
|
||||
/**
|
||||
* 父子类型 插入数据,可指定路由,父id及多索引插入
|
||||
*
|
||||
* @param routing 路由
|
||||
* @param parentId 父id
|
||||
* @param entity 插入的数据对象
|
||||
* @param indexNames 指定插入的索引名数组
|
||||
* @return 总成功条数
|
||||
*/
|
||||
Integer insert(String routing, String parentId, T entity, String... indexNames);
|
||||
|
||||
/**
|
||||
* 批量插入
|
||||
@ -261,11 +281,21 @@ public interface BaseEsMapper<T> {
|
||||
/**
|
||||
* 批量插入 可指定路由
|
||||
*
|
||||
* @param entityList 插入的数据对象列表
|
||||
* @param routing 路由
|
||||
* @param entityList 插入的数据对象列表
|
||||
* @return 总成功条数
|
||||
*/
|
||||
Integer insertBatch(Collection<T> entityList, String routing);
|
||||
Integer insertBatch(String routing, Collection<T> entityList);
|
||||
|
||||
/**
|
||||
* 父子类型 批量插入 可指定路由, 父id
|
||||
*
|
||||
* @param routing 路由
|
||||
* @param parentId 父id
|
||||
* @param entityList 插入的数据对象列表
|
||||
* @return 总成功条数
|
||||
*/
|
||||
Integer insertBatch(String routing, String parentId, Collection<T> entityList);
|
||||
|
||||
/**
|
||||
* 批量插入 可指定多索引
|
||||
@ -286,6 +316,17 @@ public interface BaseEsMapper<T> {
|
||||
*/
|
||||
Integer insertBatch(String routing, Collection<T> entityList, String... indexNames);
|
||||
|
||||
/**
|
||||
* 父子类型 批量插入 可指定路由,父id及多索引
|
||||
*
|
||||
* @param routing 路由
|
||||
* @param parentId 父id
|
||||
* @param entityList 插入的数据对象列表
|
||||
* @param indexNames 指定插入的索引名数组
|
||||
* @return 总成功条数
|
||||
*/
|
||||
Integer insertBatch(String routing, String parentId, Collection<T> entityList, String... indexNames);
|
||||
|
||||
/**
|
||||
* 根据 ID 删除
|
||||
*
|
||||
@ -297,11 +338,11 @@ public interface BaseEsMapper<T> {
|
||||
/**
|
||||
* 根据 ID 删除 可指定路由
|
||||
*
|
||||
* @param id 主键
|
||||
* @param routing 路由
|
||||
* @param id 主键
|
||||
* @return 成功条数
|
||||
*/
|
||||
Integer deleteById(Serializable id, String routing);
|
||||
Integer deleteById(String routing, Serializable id);
|
||||
|
||||
/**
|
||||
* 根据 ID 删除 可指定多索引
|
||||
@ -334,11 +375,11 @@ public interface BaseEsMapper<T> {
|
||||
/**
|
||||
* 删除(根据ID 批量删除)可指定路由
|
||||
*
|
||||
* @param idList 主键列表
|
||||
* @param routing 路由
|
||||
* @param idList 主键列表
|
||||
* @return 总成功条数
|
||||
*/
|
||||
Integer deleteBatchIds(Collection<? extends Serializable> idList, String routing);
|
||||
Integer deleteBatchIds(String routing, Collection<? extends Serializable> idList);
|
||||
|
||||
/**
|
||||
* 删除(根据ID 批量删除)
|
||||
@ -378,11 +419,11 @@ public interface BaseEsMapper<T> {
|
||||
/**
|
||||
* 根据 ID 更新 可指定路由
|
||||
*
|
||||
* @param entity 更新对象
|
||||
* @param routing 路由
|
||||
* @param entity 更新对象
|
||||
* @return 总成功条数
|
||||
*/
|
||||
Integer updateById(T entity, String routing);
|
||||
Integer updateById(String routing, T entity);
|
||||
|
||||
/**
|
||||
* 根据 ID 更新 可指定多索引
|
||||
@ -414,11 +455,11 @@ public interface BaseEsMapper<T> {
|
||||
/**
|
||||
* 根据ID 批量更新 可指定路由
|
||||
*
|
||||
* @param entityList 更新对象列表
|
||||
* @param routing 路由
|
||||
* @param entityList 更新对象列表
|
||||
* @return 总成功条数
|
||||
*/
|
||||
Integer updateBatchByIds(Collection<T> entityList, String routing);
|
||||
Integer updateBatchByIds(String routing, Collection<T> entityList);
|
||||
|
||||
/**
|
||||
* 根据ID 批量更新 可指定多索引
|
||||
@ -459,11 +500,11 @@ public interface BaseEsMapper<T> {
|
||||
/**
|
||||
* 根据 ID 查询 可指定路由
|
||||
*
|
||||
* @param id 主键
|
||||
* @param routing 路由
|
||||
* @param id 主键
|
||||
* @return 指定的返回对象
|
||||
*/
|
||||
T selectById(Serializable id, String routing);
|
||||
T selectById(String routing, Serializable id);
|
||||
|
||||
/**
|
||||
* 根据 ID 查询 可指定多索引
|
||||
@ -493,13 +534,13 @@ public interface BaseEsMapper<T> {
|
||||
List<T> selectBatchIds(Collection<? extends Serializable> idList);
|
||||
|
||||
/**
|
||||
* 查询(根据ID 批量查询)
|
||||
* 查询(根据ID 批量查询) 可指定路由
|
||||
*
|
||||
* @param idList 主键列表
|
||||
* @param routing 路由
|
||||
* @param idList 主键列表
|
||||
* @return 指定的返回对象列表
|
||||
*/
|
||||
List<T> selectBatchIds(Collection<? extends Serializable> idList, String routing);
|
||||
List<T> selectBatchIds(String routing, Collection<? extends Serializable> idList);
|
||||
|
||||
/**
|
||||
* 查询(根据ID 批量查询) 可指定多索引
|
||||
|
||||
@ -330,48 +330,66 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
|
||||
@Override
|
||||
public Integer insert(T entity) {
|
||||
Assert.notNull(entity, "insert entity must not be null");
|
||||
return insert(null, entity, EntityInfoHelper.getEntityInfo(entityClass).getIndexName());
|
||||
return insert(null, null, entity, EntityInfoHelper.getEntityInfo(entityClass).getIndexName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer insert(T entity, String routing) {
|
||||
Assert.notNull(entity, "insert entity must not be null");
|
||||
return insert(routing, entity, EntityInfoHelper.getEntityInfo(entityClass).getIndexName());
|
||||
public Integer insert(String routing, T entity) {
|
||||
return insert(routing, null, entity, EntityInfoHelper.getEntityInfo(entityClass).getIndexName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer insert(String routing, String parentId, T entity) {
|
||||
return insert(routing, parentId, entity, EntityInfoHelper.getEntityInfo(entityClass).getIndexName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer insert(T entity, String... indexNames) {
|
||||
return insert(null, entity, indexNames);
|
||||
return insert(null, null, entity, indexNames);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer insert(String routing, T entity, String... indexNames) {
|
||||
return insert(routing, null, entity, indexNames);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer insert(String routing, String parentId, T entity, String... indexNames) {
|
||||
Assert.notNull(entity, "insert entity must not be null");
|
||||
|
||||
// 执行插入
|
||||
return Arrays.stream(getIndexNames(indexNames))
|
||||
.mapToInt(indexName -> doInsert(entity, routing, indexName))
|
||||
.mapToInt(indexName -> doInsert(entity, routing, parentId, indexName))
|
||||
.sum();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer insertBatch(Collection<T> entityList) {
|
||||
return insertBatch(null, entityList, EntityInfoHelper.getEntityInfo(entityClass).getIndexName());
|
||||
return insertBatch(null, null, entityList, EntityInfoHelper.getEntityInfo(entityClass).getIndexName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer insertBatch(Collection<T> entityList, String routing) {
|
||||
public Integer insertBatch(String routing, Collection<T> entityList) {
|
||||
return insertBatch(routing, entityList, EntityInfoHelper.getEntityInfo(entityClass).getIndexName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer insertBatch(String routing, String parentId, Collection<T> entityList) {
|
||||
return insertBatch(routing, parentId, entityList, EntityInfoHelper.getEntityInfo(entityClass).getIndexName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer insertBatch(Collection<T> entityList, String... indexNames) {
|
||||
return insertBatch(null, entityList, indexNames);
|
||||
return insertBatch(null, null, entityList, indexNames);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer insertBatch(String routing, Collection<T> entityList, String... indexNames) {
|
||||
return insertBatch(routing, null, entityList, indexNames);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer insertBatch(String routing, String parentId, Collection<T> entityList, String... indexNames) {
|
||||
// 老汉裤子都脱了 你告诉我没有数据 怎么*入?
|
||||
if (CollectionUtils.isEmpty(entityList)) {
|
||||
return BaseEsConstants.ZERO;
|
||||
@ -379,7 +397,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
|
||||
// 在每条指定的索引上批量执行数据插入
|
||||
return Arrays.stream(getIndexNames(indexNames))
|
||||
.mapToInt(indexName -> doInsertBatch(entityList, routing, indexName))
|
||||
.mapToInt(indexName -> doInsertBatch(entityList, routing, parentId, indexName))
|
||||
.sum();
|
||||
}
|
||||
|
||||
@ -389,7 +407,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer deleteById(Serializable id, String routing) {
|
||||
public Integer deleteById(String routing, Serializable id) {
|
||||
return deleteById(routing, id, EntityInfoHelper.getEntityInfo(entityClass).getIndexName());
|
||||
}
|
||||
|
||||
@ -411,7 +429,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer deleteBatchIds(Collection<? extends Serializable> idList, String routing) {
|
||||
public Integer deleteBatchIds(String routing, Collection<? extends Serializable> idList) {
|
||||
return deleteBatchIds(routing, idList, EntityInfoHelper.getEntityInfo(entityClass).getIndexName());
|
||||
}
|
||||
|
||||
@ -457,7 +475,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer updateById(T entity, String routing) {
|
||||
public Integer updateById(String routing, T entity) {
|
||||
return updateById(routing, entity, EntityInfoHelper.getEntityInfo(entityClass).getIndexName());
|
||||
}
|
||||
|
||||
@ -485,7 +503,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer updateBatchByIds(Collection<T> entityList, String routing) {
|
||||
public Integer updateBatchByIds(String routing, Collection<T> entityList) {
|
||||
return updateBatchByIds(routing, entityList, EntityInfoHelper.getEntityInfo(entityClass).getIndexName());
|
||||
}
|
||||
|
||||
@ -524,7 +542,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public T selectById(Serializable id, String routing) {
|
||||
public T selectById(String routing, Serializable id) {
|
||||
return selectById(routing, id, EntityInfoHelper.getEntityInfo(entityClass).getIndexName());
|
||||
}
|
||||
|
||||
@ -553,7 +571,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> selectBatchIds(Collection<? extends Serializable> idList, String routing) {
|
||||
public List<T> selectBatchIds(String routing, Collection<? extends Serializable> idList) {
|
||||
return selectBatchIds(routing, idList, EntityInfoHelper.getEntityInfo(entityClass).getIndexName());
|
||||
}
|
||||
|
||||
@ -686,12 +704,14 @@ 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 indexName) {
|
||||
private Integer doInsert(T entity, String routing, String parentId, String indexName) {
|
||||
// 构建请求入参
|
||||
IndexRequest indexRequest = buildIndexRequest(entity, routing, indexName);
|
||||
IndexRequest indexRequest = buildIndexRequest(entity, routing, parentId, indexName);
|
||||
|
||||
Optional.ofNullable(routing).ifPresent(indexRequest::routing);
|
||||
indexRequest.setRefreshPolicy(getRefreshPolicy());
|
||||
|
||||
@ -716,16 +736,17 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
*
|
||||
* @param entityList 数据列表
|
||||
* @param routing 路由
|
||||
* @param parentId 父id
|
||||
* @param indexName 索引名
|
||||
* @return 总成功条数
|
||||
*/
|
||||
private Integer doInsertBatch(Collection<T> entityList, String routing, String indexName) {
|
||||
private Integer doInsertBatch(Collection<T> entityList, String routing, String parentId, String indexName) {
|
||||
// 构建批量请求参数
|
||||
BulkRequest bulkRequest = new BulkRequest();
|
||||
Optional.ofNullable(routing).ifPresent(bulkRequest::routing);
|
||||
bulkRequest.setRefreshPolicy(getRefreshPolicy());
|
||||
entityList.forEach(entity -> {
|
||||
IndexRequest indexRequest = buildIndexRequest(entity, routing, indexName);
|
||||
IndexRequest indexRequest = buildIndexRequest(entity, routing, parentId, indexName);
|
||||
bulkRequest.add(indexRequest);
|
||||
});
|
||||
|
||||
@ -1033,10 +1054,11 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
*
|
||||
* @param entity 实体
|
||||
* @param routing 路由
|
||||
* @param parentId 父id
|
||||
* @param indexName 索引名
|
||||
* @return es请求参数
|
||||
*/
|
||||
private IndexRequest buildIndexRequest(T entity, String routing, String indexName) {
|
||||
private IndexRequest buildIndexRequest(T entity, String routing, String parentId, String indexName) {
|
||||
IndexRequest indexRequest = new IndexRequest();
|
||||
|
||||
// id预处理,除下述情况,其它情况使用es默认的id
|
||||
@ -1058,7 +1080,7 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
|
||||
joinField.setName(entityInfo.getJoinAlias());
|
||||
if (entityInfo.isChild()) {
|
||||
// 子类型,需要追加父
|
||||
joinField.setParent(routing);
|
||||
joinField.setParent(parentId);
|
||||
}
|
||||
jsonObject.put(entityInfo.getJoinFieldName(), joinField);
|
||||
jsonData = jsonObject.toJSONString();
|
||||
|
||||
@ -4,6 +4,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.aggregations.BucketOrder;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
|
||||
import java.util.LinkedList;
|
||||
@ -78,6 +79,11 @@ public abstract class Wrapper<T> implements Cloneable {
|
||||
*/
|
||||
protected List<AggregationParam> aggregationParamList;
|
||||
|
||||
/**
|
||||
* 聚合桶排序规则列表
|
||||
*/
|
||||
List<BucketOrder> bucketOrders;
|
||||
|
||||
/**
|
||||
* 排序参数列表
|
||||
*/
|
||||
|
||||
@ -21,6 +21,7 @@ import org.elasticsearch.join.query.HasParentQueryBuilder;
|
||||
import org.elasticsearch.join.query.ParentIdQueryBuilder;
|
||||
import org.elasticsearch.search.aggregations.AggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.AggregationBuilders;
|
||||
import org.elasticsearch.search.aggregations.BucketOrder;
|
||||
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.elasticsearch.search.collapse.CollapseBuilder;
|
||||
@ -246,7 +247,9 @@ public class WrapperProcessor {
|
||||
setBool(bool, nestedQueryBuilder, param.getPrevQueryType());
|
||||
break;
|
||||
case HAS_PARENT:
|
||||
realField = getRealField(param.getColumn(), mappingColumnMap);
|
||||
// 如果用户没指定type框架可根据entityInfo上下文自行推断出其父type
|
||||
String column = Optional.ofNullable(param.getColumn()).orElse(entityInfo.getParentJoinAlias());
|
||||
realField = getRealField(column, mappingColumnMap);
|
||||
queryBuilder = getBool(children, QueryBuilders.boolQuery(), entityInfo, param.getColumn());
|
||||
HasParentQueryBuilder hasParentQueryBuilder = new HasParentQueryBuilder(realField, queryBuilder, (boolean) param.getVal());
|
||||
setBool(bool, hasParentQueryBuilder, param.getPrevQueryType());
|
||||
@ -555,7 +558,7 @@ public class WrapperProcessor {
|
||||
AggregationBuilder cursor = null;
|
||||
for (AggregationParam aggParam : aggregationParamList) {
|
||||
String realField = getRealField(aggParam.getField(), mappingColumnMap);
|
||||
AggregationBuilder builder = getRealAggregationBuilder(aggParam.getAggregationType(), aggParam.getName(), realField);
|
||||
AggregationBuilder builder = getRealAggregationBuilder(aggParam.getAggregationType(), aggParam.getName(), realField, wrapper.size, wrapper.bucketOrders);
|
||||
if (aggParam.isEnablePipeline()) {
|
||||
// 管道聚合, 构造聚合树
|
||||
if (root == null) {
|
||||
@ -588,9 +591,10 @@ public class WrapperProcessor {
|
||||
* @param aggType 聚合类型
|
||||
* @param name 聚合返回桶的名称 保持原字段名称
|
||||
* @param realField 原字段名称
|
||||
* @param size 聚合桶大小
|
||||
* @return 聚合建造者
|
||||
*/
|
||||
private static AggregationBuilder getRealAggregationBuilder(AggregationTypeEnum aggType, String name, String realField) {
|
||||
private static AggregationBuilder getRealAggregationBuilder(AggregationTypeEnum aggType, String name, String realField, Integer size, List<BucketOrder> bucketOrders) {
|
||||
AggregationBuilder aggregationBuilder;
|
||||
// 解决同一个字段聚合多次,如min(starNum), max(starNum) 字段名重复问题
|
||||
name += aggType.getValue();
|
||||
@ -608,7 +612,10 @@ public class WrapperProcessor {
|
||||
aggregationBuilder = AggregationBuilders.sum(name).field(realField);
|
||||
break;
|
||||
case TERMS:
|
||||
aggregationBuilder = AggregationBuilders.terms(name).field(realField);
|
||||
TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms(name).field(realField);
|
||||
Optional.ofNullable(size).ifPresent(termsAggregationBuilder::size);
|
||||
Optional.ofNullable(bucketOrders).ifPresent(termsAggregationBuilder::order);
|
||||
aggregationBuilder = termsAggregationBuilder;
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("不支持的聚合类型,参见AggregationTypeEnum");
|
||||
|
||||
@ -107,7 +107,7 @@ public class EntityInfoHelper {
|
||||
*/
|
||||
private static void initJoin(Class<?> clazz, GlobalConfig globalConfig, EntityInfo entityInfo) {
|
||||
Join join = clazz.getAnnotation(Join.class);
|
||||
if (join == null || ArrayUtils.isEmpty(join.children())) {
|
||||
if (join == null || ArrayUtils.isEmpty(join.nodes())) {
|
||||
return;
|
||||
}
|
||||
boolean camelCase = globalConfig.getDbConfig().isMapUnderscoreToCamelCase();
|
||||
@ -119,7 +119,7 @@ public class EntityInfoHelper {
|
||||
entityInfo.setJoinAlias(underlineJoinAlias);
|
||||
|
||||
Map<String, List<String>> relationMap = entityInfo.getRelationMap();
|
||||
Arrays.stream(join.children())
|
||||
Arrays.stream(join.nodes())
|
||||
.forEach(child -> {
|
||||
String parentAlias = StringUtils.isBlank(child.parentAlias()) ? child.parentClass().getSimpleName().toLowerCase() : child.parentAlias();
|
||||
String underlineParentAlias = camelToUnderline(parentAlias, camelCase);
|
||||
|
||||
@ -2,10 +2,7 @@ package org.dromara.easyes.sample.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.dromara.easyes.annotation.HighLight;
|
||||
import org.dromara.easyes.annotation.IndexField;
|
||||
import org.dromara.easyes.annotation.IndexId;
|
||||
import org.dromara.easyes.annotation.IndexName;
|
||||
import org.dromara.easyes.annotation.*;
|
||||
import org.dromara.easyes.annotation.rely.Analyzer;
|
||||
import org.dromara.easyes.annotation.rely.FieldStrategy;
|
||||
import org.dromara.easyes.annotation.rely.FieldType;
|
||||
@ -18,7 +15,8 @@ import org.dromara.easyes.annotation.rely.IdType;
|
||||
**/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@IndexName(value = "easyes_document", shardsNum = 3, replicasNum = 2, keepGlobalPrefix = true, maxResultWindow = 100)
|
||||
@Settings(shardsNum = 3, replicasNum = 2, maxResultWindow = 1000)
|
||||
@IndexName(value = "easyes_document", keepGlobalPrefix = true)
|
||||
public class Document {
|
||||
/**
|
||||
* es中的唯一id,如果你想自定义es中的id为你提供的id,比如MySQL中的id,请将注解中的type指定为customize或直接在全局配置文件中指定,如此id便支持任意数据类型)
|
||||
|
||||
@ -3,26 +3,25 @@ package org.dromara.easyes.test.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import org.dromara.easyes.annotation.IndexField;
|
||||
import org.dromara.easyes.annotation.IndexName;
|
||||
import org.dromara.easyes.annotation.rely.Analyzer;
|
||||
import org.dromara.easyes.annotation.IndexId;
|
||||
import org.dromara.easyes.annotation.rely.FieldType;
|
||||
|
||||
|
||||
/**
|
||||
* es 作者 数据模型 Document的子文档,Document是其父文档
|
||||
* 作者 数据模型 Document的子文档,Document是其父文档
|
||||
* <p>
|
||||
* Copyright © 2021 xpc1024 All Rights Reserved
|
||||
* Copyright © 2024 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@Data
|
||||
public class Author {
|
||||
/**
|
||||
* 作者id
|
||||
*/
|
||||
@IndexField(fieldType = FieldType.KEYWORD)
|
||||
@IndexId
|
||||
private String authorId;
|
||||
/**
|
||||
* 作者姓名
|
||||
*/
|
||||
@IndexField(fieldType = FieldType.TEXT, analyzer = Analyzer.IK_SMART, searchAnalyzer = Analyzer.IK_SMART)
|
||||
@IndexField(fieldType = FieldType.KEYWORD)
|
||||
private String authorName;
|
||||
}
|
||||
|
||||
@ -3,25 +3,25 @@ package org.dromara.easyes.test.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import org.dromara.easyes.annotation.IndexField;
|
||||
import org.dromara.easyes.annotation.IndexName;
|
||||
import org.dromara.easyes.annotation.IndexId;
|
||||
import org.dromara.easyes.annotation.rely.FieldType;
|
||||
|
||||
|
||||
/**
|
||||
* es 联系方式 数据模型 Author的子文档,Author是其父文档
|
||||
* 联系方式 数据模型 Author的子文档,Author是其父文档,Document是其爷文档
|
||||
* <p>
|
||||
* Copyright © 2021 xpc1024 All Rights Reserved
|
||||
* Copyright © 2024 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@Data
|
||||
public class Contact {
|
||||
/**
|
||||
* 手机号
|
||||
* 联系人id
|
||||
*/
|
||||
@IndexField(fieldType = FieldType.KEYWORD)
|
||||
private String phone;
|
||||
@IndexId
|
||||
private String contactId;
|
||||
/**
|
||||
* 邮箱
|
||||
* 地址
|
||||
*/
|
||||
@IndexField(fieldType = FieldType.TEXT)
|
||||
private String email;
|
||||
private String address;
|
||||
}
|
||||
|
||||
@ -11,7 +11,14 @@ import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* es 数据模型
|
||||
* es 数据模型 其中Join父子类型结构如下所示
|
||||
* <pre>
|
||||
* Document
|
||||
* / \
|
||||
* Comment Author
|
||||
* \
|
||||
* Contact
|
||||
* </pre>
|
||||
* <p>
|
||||
* Copyright © 2021 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@ -19,7 +26,7 @@ import java.util.List;
|
||||
@Accessors(chain = true)
|
||||
@Settings(shardsNum = 3, replicasNum = 2, settingsProvider = MySettingsProvider.class)
|
||||
@IndexName(value = "easyes_document", keepGlobalPrefix = true, refreshPolicy = RefreshPolicy.IMMEDIATE)
|
||||
@Join(children = {@Child(parentClass = Document.class, childClasses = {Author.class, Comment.class}), @Child(parentClass = Author.class, childClasses = Contact.class)})
|
||||
@Join(nodes = {@Node(parentClass = Document.class, childClasses = {Author.class, Comment.class}), @Node(parentClass = Author.class, childClasses = Contact.class)})
|
||||
public class Document {
|
||||
/**
|
||||
* es中的唯一id,字段名随便起,我这里演示用esId,你也可以用id(推荐),bizId等.
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package org.dromara.easyes.test.mapper;
|
||||
|
||||
|
||||
import org.dromara.easyes.annotation.EsDS;
|
||||
import org.dromara.easyes.core.core.BaseEsMapper;
|
||||
import org.dromara.easyes.test.entity.Author;
|
||||
|
||||
@ -9,5 +10,6 @@ import org.dromara.easyes.test.entity.Author;
|
||||
* <p>
|
||||
* Copyright © 2024 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@EsDS("ds1")
|
||||
public interface AuthorMapper extends BaseEsMapper<Author> {
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package org.dromara.easyes.test.mapper;
|
||||
|
||||
|
||||
import org.dromara.easyes.annotation.EsDS;
|
||||
import org.dromara.easyes.core.core.BaseEsMapper;
|
||||
import org.dromara.easyes.test.entity.Contact;
|
||||
|
||||
@ -9,5 +10,6 @@ import org.dromara.easyes.test.entity.Contact;
|
||||
* <p>
|
||||
* Copyright © 2024 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@EsDS("ds1")
|
||||
public interface ContactMapper extends BaseEsMapper<Contact> {
|
||||
}
|
||||
|
||||
@ -6,9 +6,13 @@ import org.dromara.easyes.core.conditions.update.LambdaEsUpdateWrapper;
|
||||
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.Author;
|
||||
import org.dromara.easyes.test.entity.Comment;
|
||||
import org.dromara.easyes.test.entity.Contact;
|
||||
import org.dromara.easyes.test.entity.Document;
|
||||
import org.dromara.easyes.test.mapper.AuthorMapper;
|
||||
import org.dromara.easyes.test.mapper.CommentMapper;
|
||||
import org.dromara.easyes.test.mapper.ContactMapper;
|
||||
import org.dromara.easyes.test.mapper.DocumentMapper;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
@ -17,7 +21,16 @@ import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 父子类型测试
|
||||
* 父子类型测试 其结构如下所示,Document文档有子文档Author(作者)和Comment(评论),其中Author还有个子文档Contact(联系方式)
|
||||
* 下述结构可参考加在Document上的自定义注解@Join和@Node来表达
|
||||
* <pre>
|
||||
* Document
|
||||
* / \
|
||||
* Comment Author
|
||||
* \
|
||||
* Contact
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* Copyright © 2022 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@ -29,6 +42,16 @@ public class JoinTest {
|
||||
private DocumentMapper documentMapper;
|
||||
@Resource
|
||||
private CommentMapper commentMapper;
|
||||
@Resource
|
||||
private AuthorMapper authorMapper;
|
||||
@Resource
|
||||
private ContactMapper contactMapper;
|
||||
|
||||
/**
|
||||
* 固定路由,确保后续CRUD中所有父子文档均在统一分片上
|
||||
*/
|
||||
private final static String FIXED_ROUTING = "testRouting";
|
||||
|
||||
|
||||
@Test
|
||||
@Order(0)
|
||||
@ -41,29 +64,59 @@ public class JoinTest {
|
||||
@Test
|
||||
@Order(1)
|
||||
public void testInsert() throws InterruptedException {
|
||||
// 测试新增父子文档,此处开启自动挡模式,父子类型索引已被自动处理
|
||||
// 新新增父文档,然后再插入子文档
|
||||
String parentId = "doc-1";
|
||||
Document document = new Document();
|
||||
// 此处id为自定义id,也可去掉注解@IndexId(type = IdType.CUSTOMIZE),让es自行生成id(推荐), insert完成后 es生成的id直接从document中取获取
|
||||
document.setEsId(parentId);
|
||||
document.setTitle("我是父文档的标题");
|
||||
document.setContent("我是父文档的内容 father content ");
|
||||
documentMapper.insert(document);
|
||||
Document root = new Document();
|
||||
root.setEsId(parentId);
|
||||
root.setTitle("我是父文档的标题");
|
||||
root.setContent("father doc");
|
||||
documentMapper.insert(FIXED_ROUTING, root);
|
||||
Thread.sleep(2000);
|
||||
|
||||
// 插入子文档
|
||||
Comment comment = new Comment();
|
||||
comment.setId("comment-1");
|
||||
comment.setCommentContent("test1");
|
||||
|
||||
// 这里特别注意,子文档必须指定其路由为父亲的id,否则傻儿子找不到爹别怪我没提醒 (es语法如此,非框架限制)
|
||||
commentMapper.insert(comment, parentId);
|
||||
// 插入子文档1
|
||||
Comment nodeA1 = new Comment();
|
||||
nodeA1.setId("comment-1");
|
||||
nodeA1.setCommentContent("test1");
|
||||
// 这里特别注意,子文档必须指定其路由和父亲文档相同,否则傻儿子找不到爹别怪我没提醒 (es语法如此,非框架限制)
|
||||
commentMapper.insert(FIXED_ROUTING, parentId, nodeA1);
|
||||
|
||||
// 插入子文档2
|
||||
Comment comment1 = new Comment();
|
||||
comment1.setId("comment-2");
|
||||
comment1.setCommentContent("test2");
|
||||
commentMapper.insert(comment1, parentId);
|
||||
Comment nodeA2 = new Comment();
|
||||
nodeA2.setId("comment-2");
|
||||
nodeA2.setCommentContent("test2");
|
||||
commentMapper.insert(FIXED_ROUTING, parentId, nodeA2);
|
||||
|
||||
// 插入子文档3
|
||||
Author nodeB1 = new Author();
|
||||
nodeB1.setAuthorId("author-1");
|
||||
nodeB1.setAuthorName("tom");
|
||||
authorMapper.insert(FIXED_ROUTING, parentId, nodeB1);
|
||||
|
||||
// 插入子文档4
|
||||
Author nodeB2 = new Author();
|
||||
nodeB2.setAuthorId("author-2");
|
||||
nodeB2.setAuthorName("cat");
|
||||
authorMapper.insert(FIXED_ROUTING, parentId, nodeB2);
|
||||
Thread.sleep(2000);
|
||||
|
||||
// 插入孙子文档1(把孙子1挂在子文档3上)
|
||||
Contact child1 = new Contact();
|
||||
child1.setContactId("contact-1");
|
||||
child1.setAddress("zhejiang province");
|
||||
contactMapper.insert(FIXED_ROUTING, nodeB1.getAuthorId(), child1);
|
||||
|
||||
// 插入孙子文档2(把孙子2挂在子文档3上)
|
||||
Contact child2 = new Contact();
|
||||
child2.setContactId("contact-2");
|
||||
child2.setAddress("hangzhou city");
|
||||
contactMapper.insert(FIXED_ROUTING, nodeB1.getAuthorId(), child2);
|
||||
|
||||
// 插入孙子文档3(把孙子3挂在子文档4上)
|
||||
Contact child3 = new Contact();
|
||||
child3.setContactId("contact-3");
|
||||
child3.setAddress("binjiang region");
|
||||
contactMapper.insert(FIXED_ROUTING, nodeB2.getAuthorId(), child3);
|
||||
|
||||
// es写入数据有延迟 适当休眠 保证后续查询结果正确
|
||||
Thread.sleep(2000);
|
||||
@ -72,25 +125,49 @@ public class JoinTest {
|
||||
@Test
|
||||
@Order(2)
|
||||
public void testSelect() {
|
||||
// 温馨提示,下面wrapper中的type实际上就是JoinField字段注解@TableField中指定的parentName和childName,与原生语法是一致的
|
||||
// 温馨提示,下面wrapper中的type实际上就是索引JoinField中指定的父子名称,与原生语法是一致的
|
||||
// case1: hasChild查询,返回的是相关的父文档 所以查询用父文档实体及其mapper
|
||||
LambdaEsQueryWrapper<Document> documentWrapper = new LambdaEsQueryWrapper<>();
|
||||
documentWrapper.hasChild("comment", w -> w.eq(FieldUtils.val(Comment::getCommentContent), "test1"));
|
||||
List<Document> documents = documentMapper.selectList(documentWrapper);
|
||||
System.out.println(documents);
|
||||
|
||||
LambdaEsQueryWrapper<Author> authorWrapper = new LambdaEsQueryWrapper<>();
|
||||
authorWrapper.hasChild("contact", w -> w.match(FieldUtils.val(Contact::getAddress), "city"));
|
||||
List<Author> authors = authorMapper.selectList(authorWrapper);
|
||||
System.out.println(authors);
|
||||
|
||||
// case2: hasParent查询,返回的是相关的子文档 所以查询用子文档实体及其mapper
|
||||
LambdaEsQueryWrapper<Comment> commentWrapper = new LambdaEsQueryWrapper<>();
|
||||
commentWrapper.like(Comment::getCommentContent, "test");
|
||||
// 字段名称你也可以不用FieldUtils.val,直接传入字符串也行
|
||||
commentWrapper.hasParent("document", w -> w.match("content", "father").or().match("content", "content"));
|
||||
commentWrapper.hasParent("document", w -> w.match("content", "father"));
|
||||
List<Comment> comments = commentMapper.selectList(commentWrapper);
|
||||
System.out.println(comments);
|
||||
|
||||
// case2.1: 孙子查爹的情况
|
||||
LambdaEsQueryWrapper<Contact> contactWrapper = new LambdaEsQueryWrapper<>();
|
||||
contactWrapper.hasParent("author", w -> w.eq(FieldUtils.val(Author::getAuthorName), "cat"));
|
||||
List<Contact> contacts = contactMapper.selectList(contactWrapper);
|
||||
System.out.println(contacts);
|
||||
|
||||
// case2.2: 2.1的简写
|
||||
LambdaEsQueryWrapper<Contact> contactWrapper1 = new LambdaEsQueryWrapper<>();
|
||||
// hasParent之所以可以不指定parentType简写是因为框架可以通过@Join注解中指定的父子关系自动推断出其父type,因此用户可以不指定父type直接查询,但hasChild不能简写,因为一个父亲可能有多个孩子,但一个孩子只能有一个亲爹
|
||||
contactWrapper1.hasParent(w -> w.eq(FieldUtils.val(Author::getAuthorName), "cat"));
|
||||
List<Contact> contacts1 = contactMapper.selectList(contactWrapper1);
|
||||
System.out.println(contacts1);
|
||||
|
||||
// case3: parentId查询,返回的是相关的子文档,与case2类似,所以查询用子文档实体及其mapper
|
||||
commentWrapper = new LambdaEsQueryWrapper<>();
|
||||
commentWrapper.parentId("doc-1", "comment");
|
||||
List<Comment> commentList = commentMapper.selectList(commentWrapper);
|
||||
System.out.println(commentList);
|
||||
|
||||
contactWrapper = new LambdaEsQueryWrapper<>();
|
||||
contactWrapper.parentId("author-2", "contact");
|
||||
List<Contact> contactList = contactMapper.selectList(contactWrapper);
|
||||
System.out.println(contactList);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -100,13 +177,19 @@ public class JoinTest {
|
||||
Document document = new Document();
|
||||
document.setEsId("doc-1");
|
||||
document.setTitle("我是隔壁老王标题");
|
||||
documentMapper.updateById(document);
|
||||
documentMapper.updateById(FIXED_ROUTING, document);
|
||||
|
||||
Contact contact = new Contact();
|
||||
contact.setContactId("contact-2");
|
||||
contact.setAddress("update address");
|
||||
contactMapper.updateById(FIXED_ROUTING, contact);
|
||||
|
||||
// case2: 父文档/子文档 根据各自条件更新
|
||||
Comment comment = new Comment();
|
||||
comment.setCommentContent("我是隔壁老王的评论");
|
||||
comment.setCommentContent("update comment content");
|
||||
LambdaEsUpdateWrapper<Comment> wrapper = new LambdaEsUpdateWrapper<>();
|
||||
wrapper.match(Comment::getCommentContent, "comment");
|
||||
wrapper.eq(Comment::getCommentContent, "test1");
|
||||
wrapper.routing(FIXED_ROUTING);
|
||||
commentMapper.update(comment, wrapper);
|
||||
}
|
||||
|
||||
@ -114,11 +197,12 @@ public class JoinTest {
|
||||
@Order(4)
|
||||
public void testDelete() {
|
||||
// case1: 父文档/子文档 根据各自的id删除
|
||||
documentMapper.deleteById("doc-1");
|
||||
documentMapper.deleteById(FIXED_ROUTING, "doc-1");
|
||||
|
||||
//case2: 父文档/子文档 根据各自条件删除
|
||||
LambdaEsQueryWrapper<Comment> wrapper = new LambdaEsQueryWrapper<>();
|
||||
wrapper.match(Comment::getCommentContent, "comment");
|
||||
wrapper.like(Comment::getCommentContent, "test")
|
||||
.routing(FIXED_ROUTING);
|
||||
commentMapper.delete(wrapper);
|
||||
}
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ easy-es:
|
||||
field-strategy: not_empty
|
||||
refresh-policy: immediate
|
||||
enable-track-total-hits: true
|
||||
# index-prefix: dev_
|
||||
# index-prefix: dev_
|
||||
dynamic:
|
||||
datasource:
|
||||
ds1:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user