mirror of https://github.com/dunwu/db-tutorial.git
ES 示例和文档
parent
ad820baf2b
commit
a471749179
|
@ -0,0 +1,95 @@
|
|||
version: '2.2'
|
||||
services:
|
||||
cerebro:
|
||||
image: lmenezes/cerebro:0.8.3
|
||||
container_name: hwc_cerebro
|
||||
ports:
|
||||
- "9000:9000"
|
||||
command:
|
||||
- -Dhosts.0.host=http://elasticsearch:9200
|
||||
networks:
|
||||
- hwc_es7net
|
||||
kibana:
|
||||
image: docker.elastic.co/kibana/kibana:7.1.0
|
||||
container_name: hwc_kibana7
|
||||
environment:
|
||||
#- I18N_LOCALE=zh-CN
|
||||
- XPACK_GRAPH_ENABLED=true
|
||||
- TIMELION_ENABLED=true
|
||||
- XPACK_MONITORING_COLLECTION_ENABLED="true"
|
||||
ports:
|
||||
- "5601:5601"
|
||||
networks:
|
||||
- hwc_es7net
|
||||
elasticsearch:
|
||||
image: docker.elastic.co/elasticsearch/elasticsearch:7.1.0
|
||||
container_name: es7_hot
|
||||
environment:
|
||||
- cluster.name=geektime-hwc
|
||||
- node.name=es7_hot
|
||||
- node.attr.box_type=hot
|
||||
- bootstrap.memory_lock=true
|
||||
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
|
||||
- discovery.seed_hosts=es7_hot,es7_warm,es7_cold
|
||||
- cluster.initial_master_nodes=es7_hot,es7_warm,es7_cold
|
||||
ulimits:
|
||||
memlock:
|
||||
soft: -1
|
||||
hard: -1
|
||||
volumes:
|
||||
- hwc_es7data_hot:/usr/share/elasticsearch/data
|
||||
ports:
|
||||
- 9200:9200
|
||||
networks:
|
||||
- hwc_es7net
|
||||
elasticsearch2:
|
||||
image: docker.elastic.co/elasticsearch/elasticsearch:7.1.0
|
||||
container_name: es7_warm
|
||||
environment:
|
||||
- cluster.name=geektime-hwc
|
||||
- node.name=es7_warm
|
||||
- node.attr.box_type=warm
|
||||
- bootstrap.memory_lock=true
|
||||
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
|
||||
- discovery.seed_hosts=es7_hot,es7_warm,es7_cold
|
||||
- cluster.initial_master_nodes=es7_hot,es7_warm,es7_cold
|
||||
ulimits:
|
||||
memlock:
|
||||
soft: -1
|
||||
hard: -1
|
||||
volumes:
|
||||
- hwc_es7data_warm:/usr/share/elasticsearch/data
|
||||
networks:
|
||||
- hwc_es7net
|
||||
elasticsearch3:
|
||||
image: docker.elastic.co/elasticsearch/elasticsearch:7.1.0
|
||||
container_name: es7_cold
|
||||
environment:
|
||||
- cluster.name=geektime-hwc
|
||||
- node.name=es7_cold
|
||||
- node.attr.box_type=cold
|
||||
- bootstrap.memory_lock=true
|
||||
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
|
||||
- discovery.seed_hosts=es7_hot,es7_warm,es7_cold
|
||||
- cluster.initial_master_nodes=es7_hot,es7_warm,es7_cold
|
||||
ulimits:
|
||||
memlock:
|
||||
soft: -1
|
||||
hard: -1
|
||||
volumes:
|
||||
- hwc_es7data_cold:/usr/share/elasticsearch/data
|
||||
networks:
|
||||
- hwc_es7net
|
||||
|
||||
|
||||
volumes:
|
||||
hwc_es7data_hot:
|
||||
driver: local
|
||||
hwc_es7data_warm:
|
||||
driver: local
|
||||
hwc_es7data_cold:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
hwc_es7net:
|
||||
driver: bridge
|
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.6.3</version>
|
||||
</parent>
|
||||
|
||||
<groupId>io.github.dunwu</groupId>
|
||||
<artifactId>javadb-elasticsearch</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<elasticsearch.version>7.16.3</elasticsearch.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-json</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.7.20</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>co.elastic.clients</groupId>
|
||||
<artifactId>elasticsearch-java</artifactId>
|
||||
<version>7.16.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.elasticsearch.client</groupId>
|
||||
<artifactId>elasticsearch-rest-client</artifactId>
|
||||
<version>${elasticsearch.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.elasticsearch.client</groupId>
|
||||
<artifactId>elasticsearch-rest-high-level-client</artifactId>
|
||||
<version>${elasticsearch.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.12.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>2.12.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,34 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot;
|
||||
|
||||
import io.github.dunwu.javadb.elasticsearch.springboot.repositories.UserRepository;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:forbreak@163.com">Zhang Peng</a>
|
||||
* @date 2022-02-23
|
||||
*/
|
||||
@Slf4j
|
||||
@SpringBootApplication
|
||||
public class SpringBootDataElasticsearchApplication implements CommandLineRunner {
|
||||
|
||||
@Autowired
|
||||
private RestHighLevelClient restHighLevelClient;
|
||||
@Autowired
|
||||
private UserRepository repository;
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringBootDataElasticsearchApplication.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) {
|
||||
System.out.println("[index = user] 的文档数:" + repository.count());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.constant;
|
||||
|
||||
/**
|
||||
* 关键字命名策略枚举
|
||||
* @author <a href="mailto:forbreak@163.com">Zhang Peng</a>
|
||||
* @since 2019-12-18
|
||||
*/
|
||||
public enum NamingStrategy {
|
||||
/**
|
||||
* 默认命名
|
||||
*/
|
||||
DEFAULT,
|
||||
/**
|
||||
* 驼峰命名。例:namingStrategy
|
||||
*/
|
||||
CAMEL,
|
||||
/**
|
||||
* 全小写字母用下划线拼接。例:naming_strategy
|
||||
*/
|
||||
LOWER_UNDERLINE,
|
||||
/**
|
||||
* 全大写字母用下划线拼接。例:NAMING_STRATEGY
|
||||
*/
|
||||
UPPER_UNDERLINE,
|
||||
/**
|
||||
* 全小写字母用分割线拼接。例:naming-strategy
|
||||
*/
|
||||
LOWER_DASHED,
|
||||
/**
|
||||
* 全小写字母用分割线拼接。例:NAMING-STRATEGY
|
||||
*/
|
||||
UPPER_DASHED,
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.constant;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:forbreak@163.com">Zhang Peng</a>
|
||||
* @since 2019-12-17
|
||||
*/
|
||||
public enum OrderType {
|
||||
|
||||
ASC,
|
||||
DESC;
|
||||
|
||||
/**
|
||||
* Returns the {@link OrderType} enum for the given {@link String} or null if it cannot be parsed into an enum
|
||||
* value.
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static Optional<OrderType> fromOptionalString(String value) {
|
||||
|
||||
try {
|
||||
return Optional.of(fromString(value));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link OrderType} enum for the given {@link String} value.
|
||||
* @param value
|
||||
* @return
|
||||
* @throws IllegalArgumentException in case the given value cannot be parsed into an enum value.
|
||||
*/
|
||||
public static OrderType fromString(String value) {
|
||||
|
||||
try {
|
||||
return OrderType.valueOf(value.toUpperCase(Locale.US));
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Invalid value '%s' for orders given! Has to be either 'desc' or 'asc' (case insensitive).", value), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the direction is ascending.
|
||||
* @return
|
||||
* @since 1.13
|
||||
*/
|
||||
public boolean isAscending() {
|
||||
return this.equals(ASC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the direction is descending.
|
||||
* @return
|
||||
* @since 1.13
|
||||
*/
|
||||
public boolean isDescending() {
|
||||
return this.equals(DESC);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.constant;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:forbreak@163.com">Zhang Peng</a>
|
||||
* @since 2019-12-17
|
||||
*/
|
||||
public enum QueryJudgeType {
|
||||
Equals,
|
||||
NotEquals,
|
||||
Like,
|
||||
NotLike,
|
||||
In,
|
||||
NotIn,
|
||||
IsNull,
|
||||
IsNotNull,
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.constant;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:forbreak@163.com">Zhang Peng</a>
|
||||
* @since 2019-12-17
|
||||
*/
|
||||
public enum QueryLogicType {
|
||||
AND,
|
||||
OR,
|
||||
NOT
|
||||
}
|
|
@ -0,0 +1,301 @@
|
|||
// package io.github.dunwu.javadb.elasticsearch.springboot.elasticsearch;
|
||||
//
|
||||
// import cn.hutool.core.collection.CollectionUtil;
|
||||
// import cn.hutool.core.comparator.ComparatorChain;
|
||||
// import cn.hutool.core.comparator.PropertyComparator;
|
||||
// import cn.hutool.core.util.ArrayUtil;
|
||||
// import cn.hutool.core.util.CharUtil;
|
||||
// import cn.hutool.core.util.ReflectUtil;
|
||||
// import cn.hutool.core.util.StrUtil;
|
||||
// import io.github.dunwu.javadb.elasticsearch.springboot.constant.NamingStrategy;
|
||||
// import io.github.dunwu.javadb.elasticsearch.springboot.constant.OrderType;
|
||||
// import io.github.dunwu.javadb.elasticsearch.springboot.constant.QueryJudgeType;
|
||||
// import io.github.dunwu.javadb.elasticsearch.springboot.constant.QueryLogicType;
|
||||
// import org.elasticsearch.index.query.BoolQueryBuilder;
|
||||
// import org.elasticsearch.index.query.QueryBuilder;
|
||||
// import org.elasticsearch.index.query.RegexpQueryBuilder;
|
||||
// import org.elasticsearch.index.query.TermQueryBuilder;
|
||||
// import org.elasticsearch.search.sort.FieldSortBuilder;
|
||||
// import org.elasticsearch.search.sort.SortOrder;
|
||||
// import org.springframework.data.domain.Page;
|
||||
// import org.springframework.data.domain.PageRequest;
|
||||
// import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
||||
// import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
|
||||
//
|
||||
// import java.io.Serializable;
|
||||
// import java.lang.reflect.Field;
|
||||
// import java.util.ArrayList;
|
||||
// import java.util.Comparator;
|
||||
// import java.util.List;
|
||||
//
|
||||
// /**
|
||||
// * {@link QueryDocument} 和 {@link QueryField}
|
||||
// * @author <a href="mailto:forbreak@163.com">Zhang Peng</a>
|
||||
// * @since 2019-12-18
|
||||
// */
|
||||
// public class ElasticSearchUtil {
|
||||
//
|
||||
// private static final String LIKE_REGEX_TEMPLATE = ".*%s.*";
|
||||
//
|
||||
// private ElasticSearchUtil() {}
|
||||
//
|
||||
// public static NativeSearchQueryBuilder getNativeSearchQueryBuilder(final Object queryBean)
|
||||
// throws IllegalAccessException, NoSuchFieldException {
|
||||
// return getNativeSearchQueryBuilder(queryBean, null);
|
||||
// }
|
||||
//
|
||||
// public static List<FieldSortBuilder> getSortBuilders(Object queryBean) {
|
||||
// QueryDocument document = queryBean.getClass().getAnnotation(QueryDocument.class);
|
||||
// if (null == document) {
|
||||
// throw new IllegalArgumentException("查询条件类定义必须使用 @QueryDocument 注解");
|
||||
// }
|
||||
//
|
||||
// return getSortBuildersByDocument(document);
|
||||
// }
|
||||
//
|
||||
// public static <T, ID extends Serializable> Page<T> pageSearch(final ElasticsearchRepository<T, ID> repository,
|
||||
// final Object queryBean, final QueryLogicType logicType) throws IllegalAccessException, NoSuchFieldException {
|
||||
//
|
||||
// if (queryBean == null || repository == null) {
|
||||
// throw new NullPointerException("repository and queryBean must not be null");
|
||||
// }
|
||||
//
|
||||
// NativeSearchQueryBuilder nativeSearchQueryBuilder =
|
||||
// ElasticSearchUtil.getNativeSearchQueryBuilder(queryBean, logicType);
|
||||
// if (nativeSearchQueryBuilder == null) {
|
||||
// System.out.println("查询条件为空");
|
||||
// }
|
||||
//
|
||||
// return repository.search(nativeSearchQueryBuilder.build());
|
||||
// }
|
||||
//
|
||||
// public static NativeSearchQueryBuilder getNativeSearchQueryBuilder(final Object queryBean, QueryLogicType logicType)
|
||||
// throws IllegalAccessException, NoSuchFieldException {
|
||||
//
|
||||
// if (queryBean == null) {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// QueryDocument document = queryBean.getClass().getAnnotation(QueryDocument.class);
|
||||
// if (null == document) {
|
||||
// throw new IllegalArgumentException("查询条件类定义必须使用 @QueryDocument 注解");
|
||||
// }
|
||||
//
|
||||
// // 分页信息
|
||||
// // Map<String, Field> fieldMap = ReflectUtil.getFieldMap(queryBean.getClass());
|
||||
// Object currentField = ReflectUtil.getFieldValue(queryBean, "current");
|
||||
// if (currentField == null) {
|
||||
// throw new IllegalArgumentException("未设置 current");
|
||||
// }
|
||||
//
|
||||
// Object sizeField = ReflectUtil.getFieldValue(queryBean, "size");
|
||||
// if (sizeField == null) {
|
||||
// throw new IllegalArgumentException("未设置 size");
|
||||
// }
|
||||
//
|
||||
// long current = (long) currentField;
|
||||
// long size = (long) sizeField;
|
||||
//
|
||||
// PageRequest pageRequest = PageRequest.of((int) current, (int) size);
|
||||
// if (pageRequest == null) {
|
||||
// throw new IllegalAccessException("获取分页信息失败");
|
||||
// }
|
||||
// NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
|
||||
// nativeSearchQueryBuilder.withPageable(pageRequest);
|
||||
//
|
||||
// // 提取查询条件
|
||||
// List<QueryBuilder> queryBuilders = getQueryBuildersByDocument(queryBean, document);
|
||||
// if (CollectionUtil.isNotEmpty(queryBuilders)) {
|
||||
// if (logicType == null) {
|
||||
// logicType = document.logicType();
|
||||
// }
|
||||
// BoolQueryBuilder boolQueryBuilder = getBoolQueryBuilder(logicType, queryBuilders);
|
||||
// nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
|
||||
// } else {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// // 提取排序条件
|
||||
// List<FieldSortBuilder> sortBuilders = ElasticSearchUtil.getSortBuildersByDocument(document);
|
||||
// if (CollectionUtil.isNotEmpty(sortBuilders)) {
|
||||
// for (FieldSortBuilder sortBuilder : sortBuilders) {
|
||||
// nativeSearchQueryBuilder.withSort(sortBuilder);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return nativeSearchQueryBuilder;
|
||||
// }
|
||||
//
|
||||
// private static List<FieldSortBuilder> getSortBuildersByDocument(QueryDocument document) {
|
||||
// List<FieldSortBuilder> sortBuilders = new ArrayList<>();
|
||||
// QueryDocument.Order[] orders = document.orders();
|
||||
// if (ArrayUtil.isNotEmpty(orders)) {
|
||||
// for (QueryDocument.Order order : orders) {
|
||||
// SortOrder sortOrder = SortOrder.fromString(order.type().name());
|
||||
// FieldSortBuilder sortBuilder = new FieldSortBuilder(order.value()).order(sortOrder);
|
||||
// sortBuilders.add(sortBuilder);
|
||||
// }
|
||||
// }
|
||||
// return sortBuilders;
|
||||
// }
|
||||
//
|
||||
// public static <T, ID extends Serializable> List<T> search(final ElasticsearchRepository<T, ID> repository,
|
||||
// final Object queryBean, final QueryLogicType logicType) throws IllegalAccessException {
|
||||
//
|
||||
// if (queryBean == null || repository == null) {
|
||||
// throw new NullPointerException("repository and queryBean must not be null");
|
||||
// }
|
||||
//
|
||||
// QueryDocument document = queryBean.getClass().getAnnotation(QueryDocument.class);
|
||||
// if (null == document) {
|
||||
// throw new IllegalArgumentException("查询条件类定义必须使用 @QueryDocument 注解");
|
||||
// }
|
||||
//
|
||||
// List<QueryBuilder> queryBuilders = ElasticSearchUtil.getQueryBuilders(queryBean);
|
||||
// if (CollectionUtil.isEmpty(queryBuilders)) {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// QueryLogicType realLogicType;
|
||||
// if (logicType == null) {
|
||||
// realLogicType = document.logicType();
|
||||
// } else {
|
||||
// realLogicType = logicType;
|
||||
// }
|
||||
// BoolQueryBuilder boolQueryBuilder = getBoolQueryBuilder(realLogicType, queryBuilders);
|
||||
// Iterable<T> iterable = repository.search(boolQueryBuilder);
|
||||
// repository.fin
|
||||
// List<T> list = CollectionUtil.newArrayList(iterable);
|
||||
//
|
||||
// QueryDocument.Order[] orders = document.orders();
|
||||
// ComparatorChain<T> comparatorChain = new ComparatorChain<>();
|
||||
// for (QueryDocument.Order order : orders) {
|
||||
// Comparator<T> propertyComparator = new PropertyComparator<>(order.value());
|
||||
// if (order.type() == OrderType.ASC) {
|
||||
// comparatorChain.addComparator(propertyComparator);
|
||||
// } else {
|
||||
// comparatorChain.addComparator(propertyComparator, true);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return CollectionUtil.sort(list, comparatorChain);
|
||||
// }
|
||||
//
|
||||
// private static BoolQueryBuilder getBoolQueryBuilder(QueryLogicType logicType, List<QueryBuilder> queryBuilders) {
|
||||
// BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
|
||||
// for (QueryBuilder queryBuilder : queryBuilders) {
|
||||
//
|
||||
// switch (logicType) {
|
||||
// case AND:
|
||||
// boolQueryBuilder.must(queryBuilder);
|
||||
// break;
|
||||
// case OR:
|
||||
// boolQueryBuilder.should(queryBuilder);
|
||||
// break;
|
||||
// case NOT:
|
||||
// boolQueryBuilder.mustNot(queryBuilder);
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// return boolQueryBuilder;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 将 {@link QueryDocument} 和 {@link QueryField} 修饰的查询实体转化为 ElasticSearch Client 包所识别的查询条件
|
||||
// * @param queryBean 被 {@link QueryDocument} 和 {@link QueryField} 修饰的 Bean
|
||||
// * @return List<QueryBuilder>
|
||||
// * @throws IllegalAccessException
|
||||
// */
|
||||
// public static List<QueryBuilder> getQueryBuilders(final Object queryBean) throws IllegalAccessException {
|
||||
//
|
||||
// QueryDocument document = queryBean.getClass().getAnnotation(QueryDocument.class);
|
||||
// if (null == document) {
|
||||
// throw new IllegalArgumentException("查询条件类定义必须使用 @QueryDocument 注解");
|
||||
// }
|
||||
// return getQueryBuildersByDocument(queryBean, document);
|
||||
// }
|
||||
//
|
||||
// private static List<QueryBuilder> getQueryBuildersByDocument(Object queryBean, QueryDocument document)
|
||||
// throws IllegalAccessException {
|
||||
// // 处理查询字段和字段值
|
||||
// Field[] fields = queryBean.getClass().getDeclaredFields();
|
||||
// NamingStrategy namingStrategy = document.namingStrategy();
|
||||
// List<QueryBuilder> queryBuilders = new ArrayList<>();
|
||||
// for (Field field : fields) {
|
||||
// field.setAccessible(true);
|
||||
// Object value = field.get(queryBean);
|
||||
//
|
||||
// if (value != null) {
|
||||
// // 如果字段没有被 QueryField 修饰,直接跳过
|
||||
// QueryField queryField = field.getAnnotation(QueryField.class);
|
||||
// if (null == queryField) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// // 获取查询字段实际 key
|
||||
// String fieldName = getFieldName(namingStrategy, field, queryField);
|
||||
// if (StrUtil.isBlank(fieldName)) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// QueryBuilder queryBuilder = getQueryBuilder(queryField.judgeType(), fieldName, value);
|
||||
// queryBuilders.add(queryBuilder);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return queryBuilders;
|
||||
// }
|
||||
//
|
||||
// public static QueryBuilder getQueryBuilder(QueryJudgeType judgeType, String fieldName, Object value) {
|
||||
// QueryBuilder queryBuilder = null;
|
||||
//
|
||||
// switch (judgeType) {
|
||||
// case Equals:
|
||||
// queryBuilder = new TermQueryBuilder(fieldName, value);
|
||||
// break;
|
||||
// case Like:
|
||||
// String regexp = String.format(LIKE_REGEX_TEMPLATE, value);
|
||||
// queryBuilder = new RegexpQueryBuilder(fieldName, regexp);
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
// return queryBuilder;
|
||||
// }
|
||||
//
|
||||
// private static String getFieldName(NamingStrategy namingStrategy, Field field, QueryField queryField) {
|
||||
// if (StrUtil.isNotBlank(queryField.value())) {
|
||||
// return queryField.value();
|
||||
// } else {
|
||||
// return getFieldName(namingStrategy, field);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private static String getFieldName(NamingStrategy namingStrategy, Field field) {
|
||||
// String fieldName;
|
||||
// switch (namingStrategy) {
|
||||
// case CAMEL:
|
||||
// fieldName = StrUtil.toCamelCase(field.getName());
|
||||
// break;
|
||||
// case LOWER_UNDERLINE:
|
||||
// fieldName = StrUtil.toUnderlineCase(field.getName()).toLowerCase();
|
||||
// break;
|
||||
// case UPPER_UNDERLINE:
|
||||
// fieldName = StrUtil.toUnderlineCase(field.getName()).toUpperCase();
|
||||
// break;
|
||||
// case LOWER_DASHED:
|
||||
// fieldName = StrUtil.toSymbolCase(field.getName(), CharUtil.DASHED).toLowerCase();
|
||||
// break;
|
||||
// case UPPER_DASHED:
|
||||
// fieldName = StrUtil.toSymbolCase(field.getName(), CharUtil.DASHED).toUpperCase();
|
||||
// break;
|
||||
// default:
|
||||
// fieldName = field.getName();
|
||||
// break;
|
||||
// }
|
||||
// return fieldName;
|
||||
// }
|
||||
//
|
||||
// }
|
|
@ -0,0 +1,37 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.elasticsearch;
|
||||
|
||||
import io.github.dunwu.javadb.elasticsearch.springboot.constant.NamingStrategy;
|
||||
import io.github.dunwu.javadb.elasticsearch.springboot.constant.OrderType;
|
||||
import io.github.dunwu.javadb.elasticsearch.springboot.constant.QueryLogicType;
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* ElasticSearch 查询注解
|
||||
* @author <a href="mailto:forbreak@163.com">Zhang Peng</a>
|
||||
* @since 2019-12-17
|
||||
*/
|
||||
@Persistent
|
||||
@Inherited
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE})
|
||||
public @interface QueryDocument {
|
||||
|
||||
NamingStrategy namingStrategy() default NamingStrategy.DEFAULT;
|
||||
|
||||
QueryLogicType logicType() default QueryLogicType.AND;
|
||||
|
||||
Order[] orders() default {};
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({})
|
||||
@interface Order {
|
||||
|
||||
String value() default "";
|
||||
|
||||
OrderType type() default OrderType.ASC;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.elasticsearch;
|
||||
|
||||
|
||||
import io.github.dunwu.javadb.elasticsearch.springboot.constant.QueryJudgeType;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:forbreak@163.com">Zhang Peng</a>
|
||||
* @since 2019-12-17
|
||||
*/
|
||||
@Documented
|
||||
@Inherited
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface QueryField {
|
||||
|
||||
String value() default "";
|
||||
|
||||
QueryJudgeType judgeType() default QueryJudgeType.Equals;
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.entities;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.elasticsearch.annotations.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
@Document(indexName = "article")
|
||||
public class Article {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
private String title;
|
||||
|
||||
@MultiField(mainField = @Field(type = FieldType.Text), otherFields = {
|
||||
@InnerField(suffix = "untouched", type = FieldType.Text, store = true, index = false),
|
||||
@InnerField(suffix = "sort", type = FieldType.Text, store = true, analyzer = "keyword")})
|
||||
private List<String> authors = new ArrayList<>();
|
||||
|
||||
@Field(type = FieldType.Integer, store = true)
|
||||
private List<Integer> publishedYears = new ArrayList<>();
|
||||
|
||||
@Field(type = FieldType.Text, store = true)
|
||||
private Collection<String> tags = new ArrayList<>();
|
||||
|
||||
private int score;
|
||||
|
||||
public Article() {}
|
||||
|
||||
public Article(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.entities;
|
||||
|
||||
import org.springframework.data.elasticsearch.core.query.IndexQuery;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ArticleBuilder {
|
||||
|
||||
private Article result;
|
||||
|
||||
public ArticleBuilder(String id) {
|
||||
result = new Article(id);
|
||||
}
|
||||
|
||||
public ArticleBuilder title(String title) {
|
||||
result.setTitle(title);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ArticleBuilder addAuthor(String author) {
|
||||
result.getAuthors().add(author);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ArticleBuilder addPublishedYear(Integer year) {
|
||||
result.getPublishedYears().add(year);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ArticleBuilder score(int score) {
|
||||
result.setScore(score);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Article build() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public ArticleBuilder addTag(String tag) {
|
||||
List<String> tagsTmp = new ArrayList<String>();
|
||||
if (result.getTags() == null) {
|
||||
result.setTags(tagsTmp);
|
||||
} else {
|
||||
tagsTmp = (List<String>) result.getTags();
|
||||
}
|
||||
tagsTmp.add(tag);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IndexQuery buildIndex() {
|
||||
IndexQuery indexQuery = new IndexQuery();
|
||||
indexQuery.setId(result.getId());
|
||||
indexQuery.setObject(result);
|
||||
return indexQuery;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.entities;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
public class Author {
|
||||
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.entities;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.annotations.Field;
|
||||
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
@Document(indexName = "book")
|
||||
public class Book {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
private Long price;
|
||||
|
||||
@Version
|
||||
private Long version;
|
||||
|
||||
@Field(type = FieldType.Nested)
|
||||
private Map<Integer, Collection<String>> buckets = new HashMap<>();
|
||||
|
||||
public Book() {}
|
||||
|
||||
public Book(String id, String name, Long version) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.entities;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
public class Car {
|
||||
|
||||
private String name;
|
||||
|
||||
private String model;
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.entities;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
import org.springframework.data.elasticsearch.annotations.Field;
|
||||
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
public class GirlFriend {
|
||||
|
||||
private String name;
|
||||
|
||||
private String type;
|
||||
|
||||
@Field(type = FieldType.Nested)
|
||||
private List<Car> cars;
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.entities;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.elasticsearch.annotations.DateFormat;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.annotations.Field;
|
||||
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Document(indexName = "operation")
|
||||
public class Operation {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@Field(
|
||||
type = FieldType.Text,
|
||||
searchAnalyzer = "standard",
|
||||
analyzer = "standard",
|
||||
store = true
|
||||
)
|
||||
private String operationName;
|
||||
|
||||
@Field(
|
||||
type = FieldType.Date,
|
||||
index = false,
|
||||
store = true,
|
||||
format = DateFormat.custom,
|
||||
pattern = "yyyy-MM-dd hh:mm:ss"
|
||||
)
|
||||
private String dateUp;
|
||||
|
||||
@Field(
|
||||
type = FieldType.Text,
|
||||
index = false,
|
||||
store = false
|
||||
)
|
||||
private String someTransientData;
|
||||
|
||||
@Field(type = FieldType.Nested)
|
||||
private List<Sector> sectors;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.entities;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.annotations.Field;
|
||||
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
@Document(indexName = "person")
|
||||
public class Person {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
@Field(type = FieldType.Nested)
|
||||
private List<Car> car;
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.entities;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.annotations.Field;
|
||||
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
@Document(indexName = "person-nested")
|
||||
public class PersonMultipleLevelNested {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
@Field(type = FieldType.Nested)
|
||||
private List<GirlFriend> girlFriends;
|
||||
|
||||
@Field(type = FieldType.Nested)
|
||||
private List<Car> cars;
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.entities;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
@Document(indexName = "product")
|
||||
public class Product {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String description;
|
||||
|
||||
private boolean enabled;
|
||||
|
||||
public Product(String id, String name, String description, boolean enabled) {
|
||||
this();
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public Product() {}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.entities;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class Sector {
|
||||
|
||||
private int id;
|
||||
|
||||
private String sectorName;
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.entities;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.annotations.Field;
|
||||
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
@Document(indexName = "user")
|
||||
public class User {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
private String userName;
|
||||
|
||||
private int age;
|
||||
|
||||
private String password;
|
||||
|
||||
@Field(type = FieldType.Text, fielddata = true)
|
||||
private String email;
|
||||
|
||||
public User() {}
|
||||
|
||||
public User(String userName, int age, String password, String email) {
|
||||
this.userName = userName;
|
||||
this.age = age;
|
||||
this.password = password;
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public User(String id, String userName, int age, String password, String email) {
|
||||
this.id = id;
|
||||
this.userName = userName;
|
||||
this.age = age;
|
||||
this.password = password;
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.entities;
|
||||
|
||||
import io.github.dunwu.javadb.elasticsearch.springboot.constant.OrderType;
|
||||
import io.github.dunwu.javadb.elasticsearch.springboot.constant.QueryJudgeType;
|
||||
import io.github.dunwu.javadb.elasticsearch.springboot.elasticsearch.QueryDocument;
|
||||
import io.github.dunwu.javadb.elasticsearch.springboot.elasticsearch.QueryField;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
import org.springframework.data.annotation.Id;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:forbreak@163.com">Zhang Peng</a>
|
||||
* @since 2019-12-17
|
||||
*/
|
||||
@Data
|
||||
@ToString
|
||||
@QueryDocument(orders = {@QueryDocument.Order(value = "age", type = OrderType.ASC),
|
||||
@QueryDocument.Order(value = "email", type = OrderType.DESC)})
|
||||
public class UserQuery {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
@QueryField(judgeType = QueryJudgeType.Like)
|
||||
private String userName;
|
||||
|
||||
@QueryField(judgeType = QueryJudgeType.Equals)
|
||||
private Integer age;
|
||||
|
||||
@QueryField(judgeType = QueryJudgeType.Equals)
|
||||
private String email;
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.repositories;
|
||||
|
||||
import io.github.dunwu.javadb.elasticsearch.springboot.entities.Article;
|
||||
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
|
||||
|
||||
public interface ArticleRepository extends ElasticsearchRepository<Article, String> {}
|
|
@ -0,0 +1,16 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.repositories;
|
||||
|
||||
import io.github.dunwu.javadb.elasticsearch.springboot.entities.Book;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
|
||||
|
||||
public interface BookRepository extends ElasticsearchRepository<Book, String> {
|
||||
|
||||
Page<Book> findByNameAndPrice(String name, Integer price, Pageable pageable);
|
||||
|
||||
Page<Book> findByNameOrPrice(String name, Integer price, Pageable pageable);
|
||||
|
||||
Page<Book> findByName(String name, Pageable pageable);
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.repositories;
|
||||
|
||||
import io.github.dunwu.javadb.elasticsearch.springboot.entities.Operation;
|
||||
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
|
||||
|
||||
public interface OperationRepository extends ElasticsearchRepository<Operation, Long> {
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.repositories;
|
||||
|
||||
import io.github.dunwu.javadb.elasticsearch.springboot.entities.Product;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ProductRepository extends ElasticsearchRepository<Product, String> {
|
||||
|
||||
List<Product> findByName(String name);
|
||||
|
||||
List<Product> findByName(String name, Pageable pageable);
|
||||
|
||||
List<Product> findByNameAndId(String name, String id);
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot.repositories;
|
||||
|
||||
import io.github.dunwu.javadb.elasticsearch.springboot.entities.User;
|
||||
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UserRepository extends ElasticsearchRepository<User, String> {
|
||||
|
||||
List<User> findByUserName(String UserName);
|
||||
|
||||
User findByEmail(String email);
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
spring.elasticsearch.uris = http://localhost:9200
|
||||
spring.elasticsearch.socket-timeout = 10s
|
||||
#spring.elasticsearch.username =
|
||||
#spring.elasticsearch.password =
|
|
@ -0,0 +1,12 @@
|
|||
${AnsiColor.BRIGHT_YELLOW}${AnsiStyle.BOLD}
|
||||
________ ___ ___ ________ ___ __ ___ ___
|
||||
|\ ___ \|\ \|\ \|\ ___ \|\ \ |\ \|\ \|\ \
|
||||
\ \ \_|\ \ \ \\\ \ \ \\ \ \ \ \ \ \ \ \ \\\ \
|
||||
\ \ \ \\ \ \ \\\ \ \ \\ \ \ \ \ __\ \ \ \ \\\ \
|
||||
\ \ \_\\ \ \ \\\ \ \ \\ \ \ \ \|\__\_\ \ \ \\\ \
|
||||
\ \_______\ \_______\ \__\\ \__\ \____________\ \_______\
|
||||
\|_______|\|_______|\|__| \|__|\|____________|\|_______|
|
||||
${AnsiColor.CYAN}${AnsiStyle.BOLD}
|
||||
:: Java :: (v${java.version})
|
||||
:: Spring Boot :: (v${spring-boot.version})
|
||||
${AnsiStyle.NORMAL}
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<configuration scan="true" scanPeriod="60 seconds" debug="false">
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%boldYellow(%thread)] [%highlight(%-5level)] %boldGreen(%c{36}.%M) -
|
||||
%boldBlue(%m%n)
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="io.github.dunwu.springboot" level="INFO"/>
|
||||
|
||||
<root level="WARN">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
</root>
|
||||
</configuration>
|
|
@ -0,0 +1,170 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot;
|
||||
|
||||
import io.github.dunwu.javadb.elasticsearch.springboot.entities.User;
|
||||
import org.elasticsearch.action.admin.indices.alias.Alias;
|
||||
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
|
||||
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
|
||||
import org.elasticsearch.action.index.IndexRequest;
|
||||
import org.elasticsearch.action.index.IndexResponse;
|
||||
import org.elasticsearch.action.support.master.AcknowledgedResponse;
|
||||
import org.elasticsearch.client.GetAliasesResponse;
|
||||
import org.elasticsearch.client.RequestOptions;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.elasticsearch.client.indices.CreateIndexRequest;
|
||||
import org.elasticsearch.client.indices.GetIndexRequest;
|
||||
import org.elasticsearch.cluster.metadata.AliasMetadata;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.xcontent.XContentType;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:forbreak@163.com">Zhang Peng</a>
|
||||
* @since 2022-02-25
|
||||
*/
|
||||
@SpringBootTest
|
||||
public class RestHighLevelClientDocumentApiTest {
|
||||
|
||||
public static final String INDEX = "mytest";
|
||||
public static final String INDEX_ALIAS = "mytest_alias";
|
||||
/**
|
||||
* {@link User} 的 mapping 结构(json形式)
|
||||
*/
|
||||
public static final String MAPPING_JSON = "{\n"
|
||||
+ " \"properties\": {\n"
|
||||
+ " \"age\": {\n"
|
||||
+ " \"type\": \"long\"\n"
|
||||
+ " },\n"
|
||||
+ " \"desc\": {\n"
|
||||
+ " \"type\": \"text\",\n"
|
||||
+ " \"fields\": {\n"
|
||||
+ " \"keyword\": {\n"
|
||||
+ " \"type\": \"keyword\",\n"
|
||||
+ " \"ignore_above\": 256\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " },\n"
|
||||
+ " \"email\": {\n"
|
||||
+ " \"type\": \"text\",\n"
|
||||
+ " \"fielddata\": true\n"
|
||||
+ " },\n"
|
||||
+ " \"id\": {\n"
|
||||
+ " \"type\": \"text\",\n"
|
||||
+ " \"fields\": {\n"
|
||||
+ " \"keyword\": {\n"
|
||||
+ " \"type\": \"keyword\",\n"
|
||||
+ " \"ignore_above\": 256\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " },\n"
|
||||
+ " \"password\": {\n"
|
||||
+ " \"type\": \"text\",\n"
|
||||
+ " \"fields\": {\n"
|
||||
+ " \"keyword\": {\n"
|
||||
+ " \"type\": \"keyword\",\n"
|
||||
+ " \"ignore_above\": 256\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " },\n"
|
||||
+ " \"title\": {\n"
|
||||
+ " \"type\": \"text\",\n"
|
||||
+ " \"fields\": {\n"
|
||||
+ " \"keyword\": {\n"
|
||||
+ " \"type\": \"keyword\",\n"
|
||||
+ " \"ignore_above\": 256\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " },\n"
|
||||
+ " \"user\": {\n"
|
||||
+ " \"type\": \"text\",\n"
|
||||
+ " \"fields\": {\n"
|
||||
+ " \"keyword\": {\n"
|
||||
+ " \"type\": \"keyword\",\n"
|
||||
+ " \"ignore_above\": 256\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " },\n"
|
||||
+ " \"username\": {\n"
|
||||
+ " \"type\": \"text\",\n"
|
||||
+ " \"fields\": {\n"
|
||||
+ " \"keyword\": {\n"
|
||||
+ " \"type\": \"keyword\",\n"
|
||||
+ " \"ignore_above\": 256\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ "}";
|
||||
|
||||
@Autowired
|
||||
private RestHighLevelClient client;
|
||||
|
||||
@BeforeEach
|
||||
public void init() throws IOException {
|
||||
|
||||
// 创建索引
|
||||
CreateIndexRequest createIndexRequest = new CreateIndexRequest(INDEX);
|
||||
|
||||
// 设置索引的 settings
|
||||
createIndexRequest.settings(Settings.builder()
|
||||
.put("index.number_of_shards", 3)
|
||||
.put("index.number_of_replicas", 2)
|
||||
);
|
||||
|
||||
// 设置索引的 mapping
|
||||
createIndexRequest.mapping(MAPPING_JSON, XContentType.JSON);
|
||||
|
||||
// 设置索引的别名
|
||||
createIndexRequest.alias(new Alias(INDEX_ALIAS));
|
||||
|
||||
AcknowledgedResponse response =
|
||||
client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
|
||||
Assertions.assertTrue(response.isAcknowledged());
|
||||
|
||||
// 判断索引是否存在
|
||||
GetIndexRequest getIndexRequest = new GetIndexRequest(INDEX);
|
||||
Assertions.assertTrue(client.indices().exists(getIndexRequest, RequestOptions.DEFAULT));
|
||||
GetIndexRequest getIndexAliasRequest = new GetIndexRequest(INDEX_ALIAS);
|
||||
Assertions.assertTrue(client.indices().exists(getIndexAliasRequest, RequestOptions.DEFAULT));
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void destroy() throws IOException {
|
||||
// 删除索引
|
||||
DeleteIndexRequest request = new DeleteIndexRequest(INDEX);
|
||||
AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
|
||||
Assertions.assertTrue(response.isAcknowledged());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("列出所有索引")
|
||||
public void listAllIndex() throws IOException {
|
||||
GetAliasesRequest request = new GetAliasesRequest();
|
||||
GetAliasesResponse getAliasesResponse = client.indices().getAlias(request, RequestOptions.DEFAULT);
|
||||
Map<String, Set<AliasMetadata>> map = getAliasesResponse.getAliases();
|
||||
Set<String> indices = map.keySet();
|
||||
indices.forEach(System.out::println);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void method() throws IOException {
|
||||
IndexRequest request = new IndexRequest(INDEX);
|
||||
request.id("1");
|
||||
String jsonString = "{\n"
|
||||
+ " \"id\": \"1\",\n"
|
||||
+ " \"userName\": \"Jack\",\n"
|
||||
+ " \"age\": 12,\n"
|
||||
+ " \"password\": \"123456\",\n"
|
||||
+ " \"email\": \"jack@xxx.com\"\n"
|
||||
+ "}";
|
||||
request.source(jsonString, XContentType.JSON);
|
||||
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
|
||||
System.out.println("indexResponse: " + indexResponse.getResult());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot;
|
||||
|
||||
import io.github.dunwu.javadb.elasticsearch.springboot.entities.User;
|
||||
import org.elasticsearch.action.admin.indices.alias.Alias;
|
||||
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
|
||||
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
|
||||
import org.elasticsearch.action.index.IndexRequest;
|
||||
import org.elasticsearch.action.support.master.AcknowledgedResponse;
|
||||
import org.elasticsearch.client.GetAliasesResponse;
|
||||
import org.elasticsearch.client.RequestOptions;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.elasticsearch.client.indices.CreateIndexRequest;
|
||||
import org.elasticsearch.client.indices.GetIndexRequest;
|
||||
import org.elasticsearch.cluster.metadata.AliasMetadata;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.xcontent.XContentType;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:forbreak@163.com">Zhang Peng</a>
|
||||
* @date 2022-02-23
|
||||
*/
|
||||
@SpringBootTest
|
||||
public class RestHighLevelClientIndexApiTest {
|
||||
|
||||
public static final String INDEX = "mytest";
|
||||
public static final String INDEX_ALIAS = "mytest_alias";
|
||||
/**
|
||||
* {@link User} 的 mapping 结构(json形式)
|
||||
*/
|
||||
public static final String MAPPING_JSON = "{\n"
|
||||
+ " \"properties\": {\n"
|
||||
+ " \"age\": {\n"
|
||||
+ " \"type\": \"long\"\n"
|
||||
+ " },\n"
|
||||
+ " \"desc\": {\n"
|
||||
+ " \"type\": \"text\",\n"
|
||||
+ " \"fields\": {\n"
|
||||
+ " \"keyword\": {\n"
|
||||
+ " \"type\": \"keyword\",\n"
|
||||
+ " \"ignore_above\": 256\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " },\n"
|
||||
+ " \"email\": {\n"
|
||||
+ " \"type\": \"text\",\n"
|
||||
+ " \"fielddata\": true\n"
|
||||
+ " },\n"
|
||||
+ " \"id\": {\n"
|
||||
+ " \"type\": \"text\",\n"
|
||||
+ " \"fields\": {\n"
|
||||
+ " \"keyword\": {\n"
|
||||
+ " \"type\": \"keyword\",\n"
|
||||
+ " \"ignore_above\": 256\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " },\n"
|
||||
+ " \"password\": {\n"
|
||||
+ " \"type\": \"text\",\n"
|
||||
+ " \"fields\": {\n"
|
||||
+ " \"keyword\": {\n"
|
||||
+ " \"type\": \"keyword\",\n"
|
||||
+ " \"ignore_above\": 256\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " },\n"
|
||||
+ " \"title\": {\n"
|
||||
+ " \"type\": \"text\",\n"
|
||||
+ " \"fields\": {\n"
|
||||
+ " \"keyword\": {\n"
|
||||
+ " \"type\": \"keyword\",\n"
|
||||
+ " \"ignore_above\": 256\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " },\n"
|
||||
+ " \"user\": {\n"
|
||||
+ " \"type\": \"text\",\n"
|
||||
+ " \"fields\": {\n"
|
||||
+ " \"keyword\": {\n"
|
||||
+ " \"type\": \"keyword\",\n"
|
||||
+ " \"ignore_above\": 256\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " },\n"
|
||||
+ " \"username\": {\n"
|
||||
+ " \"type\": \"text\",\n"
|
||||
+ " \"fields\": {\n"
|
||||
+ " \"keyword\": {\n"
|
||||
+ " \"type\": \"keyword\",\n"
|
||||
+ " \"ignore_above\": 256\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ "}";
|
||||
|
||||
@Autowired
|
||||
private RestHighLevelClient restHighLevelClient;
|
||||
|
||||
@Test
|
||||
@DisplayName("创建、删除索引测试")
|
||||
public void createAndDeleteIndex() throws IOException {
|
||||
|
||||
// 创建索引
|
||||
CreateIndexRequest createIndexRequest = new CreateIndexRequest(INDEX);
|
||||
|
||||
// 设置索引的 settings
|
||||
createIndexRequest.settings(Settings.builder()
|
||||
.put("index.number_of_shards", 3)
|
||||
.put("index.number_of_replicas", 2)
|
||||
);
|
||||
|
||||
// 设置索引的 mapping
|
||||
createIndexRequest.mapping(MAPPING_JSON, XContentType.JSON);
|
||||
|
||||
// 设置索引的别名
|
||||
createIndexRequest.alias(new Alias(INDEX_ALIAS));
|
||||
|
||||
AcknowledgedResponse response =
|
||||
restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
|
||||
Assertions.assertTrue(response.isAcknowledged());
|
||||
|
||||
// 判断索引是否存在
|
||||
GetIndexRequest getIndexRequest = new GetIndexRequest(INDEX);
|
||||
Assertions.assertTrue(restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT));
|
||||
GetIndexRequest getIndexAliasRequest = new GetIndexRequest(INDEX_ALIAS);
|
||||
Assertions.assertTrue(restHighLevelClient.indices().exists(getIndexAliasRequest, RequestOptions.DEFAULT));
|
||||
|
||||
// 删除索引
|
||||
DeleteIndexRequest request = new DeleteIndexRequest(INDEX);
|
||||
response = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
|
||||
Assertions.assertTrue(response.isAcknowledged());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("列出所有索引")
|
||||
public void listAllIndex() throws IOException {
|
||||
GetAliasesRequest request = new GetAliasesRequest();
|
||||
GetAliasesResponse getAliasesResponse = restHighLevelClient.indices().getAlias(request, RequestOptions.DEFAULT);
|
||||
Map<String, Set<AliasMetadata>> map = getAliasesResponse.getAliases();
|
||||
Set<String> indices = map.keySet();
|
||||
indices.forEach(System.out::println);
|
||||
}
|
||||
|
||||
public void method() {
|
||||
IndexRequest request = new IndexRequest("posts");
|
||||
request.id("1");
|
||||
String jsonString = "{" +
|
||||
"\"user\":\"kimchy\"," +
|
||||
"\"postDate\":\"2013-01-30\"," +
|
||||
"\"message\":\"trying out Elasticsearch\"" +
|
||||
"}";
|
||||
request.source(jsonString, XContentType.JSON);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package io.github.dunwu.javadb.elasticsearch.springboot;
|
||||
|
||||
import co.elastic.clients.elasticsearch.ElasticsearchClient;
|
||||
import co.elastic.clients.elasticsearch.core.SearchResponse;
|
||||
import co.elastic.clients.elasticsearch.core.search.Hit;
|
||||
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
|
||||
import co.elastic.clients.transport.ElasticsearchTransport;
|
||||
import co.elastic.clients.transport.rest_client.RestClientTransport;
|
||||
import io.github.dunwu.javadb.elasticsearch.springboot.entities.Product;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.elasticsearch.client.RestClient;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:forbreak@163.com">Zhang Peng</a>
|
||||
* @since 2022-02-25
|
||||
*/
|
||||
public class RestLowLevelClientTest {
|
||||
|
||||
@Test
|
||||
public void method() throws IOException {
|
||||
// Create the low-level client
|
||||
RestClient restClient = RestClient.builder(
|
||||
new HttpHost("localhost", 9200)).build();
|
||||
|
||||
// Create the transport with a Jackson mapper
|
||||
ElasticsearchTransport transport = new RestClientTransport(
|
||||
restClient, new JacksonJsonpMapper());
|
||||
|
||||
// And create the API client
|
||||
ElasticsearchClient client = new ElasticsearchClient(transport);
|
||||
SearchResponse<Product> search = client.search(s -> s
|
||||
.index("products")
|
||||
.query(q -> q
|
||||
.term(t -> t
|
||||
.field("name")
|
||||
.value(v -> v.stringValue("bicycle"))
|
||||
)),
|
||||
Product.class);
|
||||
|
||||
for (Hit<Product> hit : search.hits().hits()) {
|
||||
System.out.println(hit.score());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -15,5 +15,6 @@
|
|||
<module>javadb-redis</module>
|
||||
<module>javadb-sqlite</module>
|
||||
<module>javadb-mongodb</module>
|
||||
<module>javadb-elasticsearch</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
# ElasticSearch Java API
|
||||
|
||||
> **[Elasticsearch](https://github.com/elastic/elasticsearch) 是一个分布式、RESTful 风格的搜索和数据分析引擎**,能够解决不断涌现出的各种用例。 作为 Elastic Stack 的核心,它集中存储您的数据,帮助您发现意料之中以及意料之外的情况。
|
||||
>
|
||||
> [Elasticsearch](https://github.com/elastic/elasticsearch) 基于搜索库 [Lucene](https://github.com/apache/lucene-solr) 开发。ElasticSearch 隐藏了 Lucene 的复杂性,提供了简单易用的 REST API / Java API 接口(另外还有其他语言的 API 接口)。
|
||||
>
|
||||
> _以下简称 ES_。
|
||||
>
|
||||
> REST API 最详尽的文档应该参考:[ES 官方 REST API](https://www.elastic.co/guide/en/elasticsearch/reference/current/rest-apis.html)
|
||||
|
||||
<!-- TOC depthFrom:2 depthTo:3 -->
|
||||
|
||||
- [1. ElasticSearch Rest API 语法格式](#1-elasticsearch-rest-api-语法格式)
|
||||
- [2. 索引 API](#2-索引-api)
|
||||
- [2.1. 创建索引](#21-创建索引)
|
||||
- [2.2. 删除索引](#22-删除索引)
|
||||
- [2.3. 查看索引](#23-查看索引)
|
||||
- [2.4. 索引别名](#24-索引别名)
|
||||
- [2.5. 打开/关闭索引](#25-打开关闭索引)
|
||||
- [3. 文档](#3-文档)
|
||||
- [3.1. 创建文档](#31-创建文档)
|
||||
- [3.2. 删除文档](#32-删除文档)
|
||||
- [3.3. 更新文档](#33-更新文档)
|
||||
- [3.4. 查询文档](#34-查询文档)
|
||||
- [3.5. 全文搜索](#35-全文搜索)
|
||||
- [3.6. 逻辑运算](#36-逻辑运算)
|
||||
- [3.7. 批量执行](#37-批量执行)
|
||||
- [3.8. 批量读取](#38-批量读取)
|
||||
- [3.9. 批量查询](#39-批量查询)
|
||||
- [3.10. URI Search 查询语义](#310-uri-search-查询语义)
|
||||
- [3.11. Request Body & DSL](#311-request-body--dsl)
|
||||
- [4. 集群 API](#4-集群-api)
|
||||
- [4.1. 集群健康 API](#41-集群健康-api)
|
||||
- [4.2. 集群状态 API](#42-集群状态-api)
|
||||
- [5. 节点 API](#5-节点-api)
|
||||
- [6. 分片 API](#6-分片-api)
|
||||
- [7. 监控 API](#7-监控-api)
|
||||
- [8. 参考资料](#8-参考资料)
|
||||
|
||||
<!-- /TOC -->
|
||||
|
||||
## 索引 API
|
||||
|
||||
- [Create Index API](https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-create-index.html)
|
||||
- [Delete Index API](https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-delete-index.html)
|
||||
- [Index Exists API](https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-indices-exists.html)
|
||||
|
||||
## 8. 参考资料
|
||||
|
||||
- **官方**
|
||||
- [Java High Level REST Client](https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html)
|
Loading…
Reference in New Issue