0


Elasticsearch8搭建及Springboot中集成使用

1.搭建

1.1.下载地址

Elasticsearch:https://www.elastic.co/cn/downloads/elasticsearch
Kibana:https://www.elastic.co/cn/downloads/kibana

1.2.具体过程

下载安装包:访问上述链接,下载适合你操作系统的Elasticsearch和Kibana安装包。

1.3.安装Elasticsearch

解压下载的安装包。
进入解压后的目录。
如果是Windows系统,直接进入bin目录,双击elasticsearch.bat文件。看到命令行中打印日志中出现“started”,说明Elasticsearch启动完成。

linux中进入bin目录,然后执行./elasticsearch命令

详情参见linux系统安装elasticsearch教程_linux安装es-CSDN博客

1.4.配置Elasticsearch集群

修改elasticsearch.yml文件,设置集群名称、节点名称、网络主机和种子节点等。
对于集群中的其他节点,重复上述步骤,并确保每个节点的配置文件中都有所有节点的IP地址。

启动其他节点:在每个节点上重复上述安装步骤,并启动Elasticsearch服务。

检查集群健康状态:通过访问Elasticsearch的API或使用Kibana界面,查看集群的健康状态。

请注意,这只是一个基本的搭建指南。在生产环境中,你可能需要更详细的配置和优化。此外,确保你的网络设置允许Elasticsearch集群通信所需的端口。

1.5.注意点

1.不能用root权限启动,需要新建用户,如:

更改文件夹的用户为user1 chown -R user1:user1 /local
修改user1对文件夹的权限 chmod 777 /local

2.获取账号密码

elasticsearch的bin目录下,输入命令行:elasticsearch-reset-password -u elastic

2.springboot中集成ES8

2.1.依赖

  1. <dependency>
  2. <groupId>co.elastic.clients</groupId>
  3. <artifactId>elasticsearch-java</artifactId>
  4. <version>8.1.0</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.fasterxml.jackson.core</groupId>
  8. <artifactId>jackson-databind</artifactId>
  9. <version>2.12.3</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>jakarta.json</groupId>
  13. <artifactId>jakarta.json-api</artifactId>
  14. <version>2.0.1</version>
  15. </dependency>

2.2.elasticsearch.properties

  1. spring.elasticsearch.uris = IP:port
  2. spring.elasticsearch.username = 用户名
  3. spring.elasticsearch.password = 密码

2.3.ElasticSearchConfig

  1. @Configuration
  2. public class ElasticSearchConfig {
  3. @Value("${spring.elasticsearch.uris}")
  4. private String hosts;
  5. @Value("${spring.elasticsearch.username}")
  6. private String userName;
  7. @Value("${spring.elasticsearch.password}")
  8. private String passWord;
  9. @Bean(name="elasticsearchClient")
  10. public ElasticsearchClient elasticsearchClient(){
  11. HttpHost[] httpHosts = toHttpHost();
  12. final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
  13. credentialsProvider.setCredentials(
  14. AuthScope.ANY, new UsernamePasswordCredentials(userName, passWord));
  15. RestClientBuilder builder = RestClient.builder(httpHosts);
  16. builder.setRequestConfigCallback(
  17. new RestClientBuilder.RequestConfigCallback() {
  18. @Override
  19. public RequestConfig.Builder customizeRequestConfig(
  20. RequestConfig.Builder requestConfigBuilder) {
  21. return requestConfigBuilder.setSocketTimeout(60000).setConnectTimeout(5000);
  22. }
  23. });
  24. builder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
  25. @Override
  26. public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpAsyncClientBuilder) {
  27. return httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
  28. }
  29. });
  30. RestClient restClient = builder.build();
  31. ElasticsearchTransport transport = new RestClientTransport(restClient,new JacksonJsonpMapper());
  32. return new ElasticsearchClient(transport);
  33. }
  34. private HttpHost[] toHttpHost() {
  35. if (!StringUtils.hasLength(hosts)) {
  36. throw new RuntimeException("invalid elasticsearch configuration. elasticsearch.hosts不能为空!");
  37. }
  38. // 多个IP逗号隔开
  39. String[] hostArray = hosts.split(",");
  40. HttpHost[] httpHosts = new HttpHost[hostArray.length];
  41. HttpHost httpHost;
  42. for (int i = 0; i < hostArray.length; i++) {
  43. String[] strings = hostArray[i].split(":");
  44. httpHost = new HttpHost(strings[0], Integer.parseInt(strings[1]), "http");
  45. httpHosts[i] = httpHost;
  46. }
  47. return httpHosts;
  48. }
  49. }

2.4.通用类

2.4.1.枚举类,ES实体类注解

  1. @Target({ElemantType.METHOD, ElementType.TYPE})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. public @interface ElasticSearchDocument {
  4. String index() default "";
  5. int shards() default 0;
  6. int replicas() default 0;
  7. }

2.4.2.查询实体类

  1. @Data
  2. public class EsQueryDTO {
  3. private String indexName;//索引名称
  4. private String field;//关键字属性
  5. private String word;//关键字值
  6. private List<String> words;//关键字值数组
  7. private Integer from;//起始行
  8. private Integer index;//当前页
  9. private Integer size;//分页条数
  10. private String order;//排序字段
  11. private String orderType;//排序方式 Asc/Desc
  12. private String dateField;//时间字段
  13. private String startTime;//时间范围-开始时间
  14. private String endTime;//时间范围-开始时间
  15. public String getOrderType() {
  16. if (StringUtils.isBlank(orderType)) {
  17. orderType = SortOrder.Desc.name();
  18. }
  19. return orderType;
  20. }
  21. public Integer getSize() {
  22. return size == 0 ? 30 : size;
  23. }
  24. public Integer getFrom() {
  25. return getIndex() != 0 ? ((getIndex() - 1) * getSize()) : 0;
  26. }
  27. public Integer getIndex() {
  28. return null == index ? 0 : index;
  29. }
  30. public String getStartTime(int offset) {
  31. if (StringUtils.isBlank(startTime)) {
  32. startTime = DateUtil.format(DateUtil.offsetDay(new Date(), offset), "yyyy-MM-dd 00:00:00");
  33. return String.valueOf(DateUtil.parse(startTime, "yyyy-MM-dd 00:00:00").getTime());
  34. }
  35. return startTime;
  36. }
  37. public String getEndTime() {
  38. if (StringUtils.isBlank(endTime)) {
  39. endTime = String.valueOf(System.currentTimeMillis());
  40. }
  41. return endTime;
  42. }
  43. }

2.4.3.查询工具类

  1. @Component
  2. public class ElasticClientUtils<T> {
  3. /**
  4. * @param
  5. * @param client
  6. * @param dto
  7. * @param target
  8. * @return java.util.List<T>
  9. * @author liuch
  10. * @description 根据关键字查询
  11. * @date 2022/4/2 17:15
  12. */
  13. public List<T> queryByFiled(ElasticsearchClient client, EsQueryDTO dto, Class<T> target) throws Exception {
  14. List<T> result = new ArrayList<>();
  15. List<SortOptions> sorts = new ArrayList<>();
  16. if (StringUtils.isNotBlank(dto.getOrder())) {
  17. SortOptions sortOptions = SortOptions.of(s -> s.field(f -> f.field(dto.getOrder()).order(SortOrder.valueOf(dto.getOrderType()))));
  18. sorts.add(sortOptions);
  19. }
  20. SearchResponse<HashMap> search = client.search(s -> s
  21. .index(dto.getIndexName())
  22. .query(q -> q.term(t -> t
  23. .field(dto.getField())
  24. .value(dto.getWord())
  25. )).sort(sorts),
  26. HashMap.class);
  27. return getResult(target, result, search);
  28. }
  29. /**
  30. * @param
  31. * @param client
  32. * @param dto
  33. * @param target
  34. * @return java.util.List<T>
  35. * @author liuch
  36. * @description 根据关键字查询,基于游标查询scroll
  37. * @date 2022/4/2 17:15
  38. */
  39. public List<T> queryByFileds(ElasticsearchClient client, EsQueryDTO dto, List<Query> queries, Class<T> target) throws Exception {
  40. List<T> result = new ArrayList<>();
  41. List<SortOptions> sorts = new ArrayList<>();
  42. if (StringUtils.isNotBlank(dto.getOrder())) {
  43. SortOptions sortOptions = SortOptions.of(s -> s.field(f -> f.field(dto.getOrder()).order(SortOrder.valueOf(dto.getOrderType()))));
  44. sorts.add(sortOptions);
  45. }
  46. getFieldValues(dto, queries);
  47. //使用scroll深度分页查询
  48. SearchResponse<HashMap> search = client.search(s -> s
  49. .index(dto.getIndexName()).query(q -> q.bool(b -> b.must(queries))).size(5000).scroll(t -> t.time("5s"))
  50. .sort(sorts),
  51. HashMap.class);
  52. StringBuffer scrollId = new StringBuffer(search.scrollId());
  53. //循环查询,直到查不到数据
  54. do {
  55. getResult(target, result, search);
  56. StringBuffer finalScrollId = scrollId;
  57. search = client.scroll(s -> s.scrollId(finalScrollId.toString()).scroll(t -> t.time("5s")), HashMap.class);
  58. scrollId = new StringBuffer(search.scrollId());
  59. } while (!search.hits().hits().isEmpty());
  60. //getResult(target, result, search)
  61. return result;
  62. }
  63. /**
  64. * @param
  65. * @param client
  66. * @param dto
  67. * @param target
  68. * @return java.util.List<T>
  69. * @author liuch
  70. * @description 根据关键字分页查询
  71. * @date 2022/4/2 17:15
  72. */
  73. public List<T> queryByFiledWithPage(ElasticsearchClient client, EsQueryDTO dto, Class<T> target) throws Exception {
  74. List<T> result = new ArrayList<>();
  75. List<SortOptions> sorts = new ArrayList<>();
  76. if (StringUtils.isNotBlank(dto.getOrder())) {
  77. SortOptions sortOptions = SortOptions.of(s -> s.field(f -> f.field(dto.getOrder()).order(SortOrder.valueOf(dto.getOrderType()))));
  78. sorts.add(sortOptions);
  79. }
  80. SearchResponse<HashMap> search = client.search(s -> s
  81. .index(dto.getIndexName())
  82. .query(q -> q.term(t -> t
  83. .field(dto.getField())
  84. .value(dto.getWord())
  85. )).sort(sorts).from(dto.getFrom()).size(dto.getSize()),
  86. HashMap.class);
  87. return getResult(target, result, search);
  88. }
  89. private List<T> getResult(Class<T> target, List<T> result, SearchResponse<HashMap> search) {
  90. List<Hit<HashMap>> hits = search.hits().hits();
  91. Iterator<Hit<HashMap>> iterator = hits.iterator();
  92. while (iterator.hasNext()) {
  93. Hit<HashMap> decodeBeanHit = iterator.next();
  94. Map<String, Object> docMap = decodeBeanHit.source();
  95. docMap.put("id", decodeBeanHit.id());
  96. String json = JSON.toJSONString(docMap);
  97. T obj = JSON.parseObject(json, target);
  98. result.add(obj);
  99. }
  100. return result;
  101. }
  102. /**
  103. * @param
  104. * @param client
  105. * @param dto
  106. * @return long
  107. * @author liuch
  108. * @description 根据关键字查询总条数
  109. * @date 2022/4/2 17:15
  110. */
  111. public static long queryCountByFiled(ElasticsearchClient client, EsQueryDTO dto) throws Exception {
  112. CountResponse count = client.count(c -> c.index(dto.getIndexName()).query(q -> q.term(t -> t
  113. .field(dto.getField())
  114. .value(dto.getWord())
  115. )));
  116. long total = count.count();
  117. return total;
  118. }
  119. /**
  120. * @param
  121. * @param client
  122. * @param dto
  123. * @return long
  124. * @author liuch
  125. * @description 根据关键字查询总条数-复合查询
  126. * @date 2022/4/2 17:15
  127. */
  128. public static long queryCountByFileds(ElasticsearchClient client, List<Query> queries, EsQueryDTO dto) throws Exception {
  129. getFieldValues(dto, queries);
  130. CountResponse count = client.count(c -> c.index(dto.getIndexName()).query(q -> q.bool(b -> b.must(queries))));
  131. long total = count.count();
  132. return total;
  133. }
  134. /**
  135. * @param client
  136. * @param dto
  137. * @param target
  138. * @return java.util.List<T>
  139. * @author liuch
  140. * @description 根据关键字分页查询- 复合查询 must
  141. * @date 2022/4/2 17:15
  142. */
  143. public List<T> queryMustByFiledsWithPage(ElasticsearchClient client, EsQueryDTO dto, List<Query> queries, Class<T> target) throws Exception {
  144. List<T> result = new ArrayList<>();
  145. List<SortOptions> sorts = new ArrayList<>();
  146. if (StringUtils.isNotBlank(dto.getOrder())) {
  147. SortOptions sortOptions = SortOptions.of(s -> s
  148. .field(f -> f.field(dto.getOrder()).order(SortOrder.valueOf(dto.getOrderType()))));
  149. sorts.add(sortOptions);
  150. }
  151. SearchResponse<HashMap> search = client.search(s -> s
  152. .index(dto.getIndexName())
  153. .query(q -> q.bool(b -> b.must(queries)))
  154. .sort(sorts).from(dto.getFrom()).size(dto.getSize()),
  155. HashMap.class);
  156. return getResult(target, result, search);
  157. }
  158. /**
  159. * @param client
  160. * @param dto
  161. * @param target
  162. * @return java.util.List<T>
  163. * @author liuch
  164. * @description 根据关键字分页查询- 复合查询 must 过滤
  165. * @date 2022/4/2 17:15
  166. */
  167. public List<T> queryMustByFiledsWithPage(ElasticsearchClient client, EsQueryDTO dto, List<Query> queries, List<Query> filters, Class<T> target) throws Exception {
  168. List<T> result = new ArrayList<>();
  169. List<SortOptions> sorts = new ArrayList<>();
  170. if (StringUtils.isNotBlank(dto.getOrder())) {
  171. SortOptions sortOptions = SortOptions.of(s -> s
  172. .field(f -> f.field(dto.getOrder()).order(SortOrder.valueOf(dto.getOrderType()))));
  173. sorts.add(sortOptions);
  174. }
  175. SearchResponse<HashMap> search = client.search(s -> s
  176. .index(dto.getIndexName())
  177. .query(q -> q.bool(b -> b.must(queries).filter(filters)))
  178. .sort(sorts).from(dto.getFrom()).size(dto.getSize()),
  179. HashMap.class);
  180. return getResult(target, result, search);
  181. }
  182. /**
  183. * @param client
  184. * @param dto
  185. * @param target
  186. * @return java.util.List<T>
  187. * @author liuch
  188. * @description 根据关键字分页查询- 复合查询 should
  189. * @date 2022/4/2 17:15
  190. */
  191. public List<T> queryShouldByFiledsWithPage(ElasticsearchClient client, EsQueryDTO dto, List<Query> queries, Class<T> target) throws Exception {
  192. List<T> result = new ArrayList<>();
  193. List<SortOptions> sorts = new ArrayList<>();
  194. if (StringUtils.isNotBlank(dto.getOrder())) {
  195. SortOptions sortOptions = SortOptions.of(s -> s
  196. .field(f -> f.field(dto.getOrder()).order(SortOrder.valueOf(dto.getOrderType()))));
  197. sorts.add(sortOptions);
  198. }
  199. SearchResponse<HashMap> search = client.search(s -> s
  200. .index(dto.getIndexName())
  201. .query(q -> q.bool(b -> b.should(queries)))
  202. .sort(sorts).from(dto.getFrom()).size(dto.getSize()),
  203. HashMap.class);
  204. return getResult(target, result, search);
  205. }
  206. /**
  207. * 构件复合查询条件
  208. *
  209. * @param dto
  210. * @param queries
  211. */
  212. private static void getFieldValues(EsQueryDTO dto, List<Query> queries) {
  213. List<FieldValue> fieldValues = new ArrayList<>();
  214. //根据关键字列表构件复合查询的值
  215. dto.getWords().stream().forEach(word -> fieldValues.add(FieldValue.of(word)));
  216. //查询条件列表
  217. queries.add(Query.of(q -> q.terms(t -> t.field(dto.getField()).terms(v -> v.value(fieldValues)))));
  218. }
  219. /**
  220. * @param
  221. * @param client
  222. * @param dto
  223. * @param target
  224. * @return java.lang.Object
  225. * @author liuch
  226. * @description 根据文档id查询
  227. * @date 2022/4/2 17:16
  228. */
  229. public Object queryByDocumentId(ElasticsearchClient client, EsQueryDTO dto, Class<T> target) throws Exception {
  230. GetResponse<HashMap> getResponse = client.get(s -> s
  231. .index(dto.getIndexName()).id(dto.getWord()),
  232. HashMap.class);
  233. getResponse.source();
  234. Map<String, Object> docMap = getResponse.source();
  235. String json = JSON.toJSONString(docMap);
  236. T obj = JSON.parseObject(json, target);
  237. return obj;
  238. }
  239. }

2.4.4.基础操作接口

  1. /**
  2. * 基础操作---接口
  3. */
  4. public interface IElasticSearchIRepository<T, V> {
  5. int delete(V id);
  6. int update(T entity);
  7. T getById(V id);
  8. List<T> getAll();
  9. long count();
  10. PageInfo<T> getListByPage(int pageIndex, int pageSize);
  11. /**
  12. * 新增一个文档
  13. *
  14. * @param entity 实体类
  15. * @return
  16. */
  17. IndexResponse createByFluentDSL(T entity);
  18. /**
  19. * 新增一个文档
  20. *
  21. * @param entity 实体类
  22. * @return
  23. */
  24. IndexResponse createByBuilderPattern(T entity);
  25. /**
  26. * 批量增加文档
  27. *
  28. * @param list 对象集合
  29. * @return 批量操作的结果
  30. */
  31. BulkResponse bulkCreate(List<T> list);
  32. /**
  33. * 根据文档id查找文档,返回类型是ObjectNode
  34. *
  35. * @param id 文档id
  36. * @return ObjectNode类型的查找结果
  37. */
  38. ObjectNode getObjectNodeById(V id);
  39. /**
  40. * 批量删除文档
  41. *
  42. * @param docIds 要删除的文档id集合
  43. * @return
  44. * @throws Exception
  45. */
  46. BulkResponse bulkDeleteByIds(List<V> docIds);
  47. /**
  48. * 根据文档id删除文档
  49. *
  50. * @param idxName 索引名
  51. * @param docId 文档id
  52. * @return Object类型的查找结果
  53. * @throws Exception
  54. */
  55. Boolean deleteById(String idxName, String docId) throws IOException;
  56. /**
  57. * 新建索引,指定索引名称
  58. *
  59. */
  60. Boolean createIndex();
  61. /**
  62. * 创建索引,指定索引名称和setting和mapping
  63. *
  64. * @param settingFn - 索引参数
  65. * @param mappingFn - 索引结构
  66. */
  67. Boolean createIndex(Function<IndexSettings.Builder, ObjectBuilder<IndexSettings>> settingFn,
  68. Function<TypeMapping.Builder, ObjectBuilder<TypeMapping>> mappingFn);
  69. /**
  70. * 删除索引
  71. * @throws IOException
  72. */
  73. Boolean deleteIndex();
  74. /**
  75. * 修改索引字段信息 <br/>
  76. * 字段可以新增,已有的字段只能修改字段的 search_analyzer 属性。
  77. *
  78. * @param propertyMap - 索引字段,每个字段都有自己的property
  79. * @throws IOException
  80. */
  81. Boolean updateIndexProperty(HashMap<String, Property> propertyMap);
  82. /**
  83. * 查询索引列表
  84. *
  85. * @return
  86. * @throws IOException
  87. */
  88. GetIndexResponse getIndexList();
  89. /**
  90. * 查询索引详情
  91. *
  92. * @return
  93. * @throws IOException
  94. */
  95. GetIndexResponse getIndexDetail();
  96. /**
  97. * 检查指定名称的索引是否存在
  98. *
  99. * @return - true:存在
  100. * @throws IOException
  101. */
  102. boolean indexExists();
  103. }

2.4.5.基础操作接口实现类

  1. public abstract class ElasticSearchIRepository<T,V> implements IElasticSearchIRepository<T,V> {
  2. @Autowired(required =false)
  3. @Qualifier("elasticsearchClient")
  4. private ElasticsearchClient elasticsearchClient;
  5. protected ElasticSearchDocument getEntityProperties() {
  6. Class<T> cls = getEntityClass();
  7. ElasticSearchDocument esDoc = cls.getAnnotation(ElasticSearchDocument .calss);
  8. return esDoc;
  9. }
  10. /**设置索引全局配置*/
  11. protected abstract Function<IndexSettings.builder, ObjectBuilder<IndexSettings>> getIndexSettings();
  12. /**手动设置映射(不手动设置会自动创建映射,同时在插入时若手动映射时没有的字段也会自动创建)*/
  13. protected abstract Function<TypeMapping.builder, ObjectBuilder<TypeMapping>> getIndexMappings();
  14. protected abstract Class<T> getEntityClass();
  15. @Override
  16. public int update(T entity) {
  17. try {
  18. ElasticSearchDocument doc = getEntityProperties();
  19. UpdateRequest updateRequest = new UpdateRequest.Builder()
  20. .index(doc.index())
  21. .id(entity.getId().toString())
  22. .doc(entity)
  23. .build();
  24. UpdateResponse updateResponse = elasticsearchClient.update(updateRequest, entity.getClass());
  25. return updateResponse != null && StringUtils.isNotEmpty(updateResponse.id()) ? 1 : 0;
  26. }
  27. catch (IOException e) {
  28. log.error(e);
  29. }
  30. return 0;
  31. }
  32. @Override
  33. public PageInfo<T> getListByPage(int pageIndex, int pageSize) {
  34. List<T> list = new ArrayList<>();
  35. try {
  36. ElasticSearchDocument doc = getEntityProperties();
  37. ElasticClientUtils elasticClientUtils = new ElasticClientUtils();
  38. EsQueryDTO dto = new EsQueryDTO();
  39. dto.setIndex(paeIndex);
  40. dto.setSize(pageSize);
  41. dto.setIndexName(doc.index());
  42. list = elasticClientUtils.queryPage(elasticsearchClient, dto, getEntityClass());
  43. return new PageInde<T>(pageIndex, pageSize, (long)list.size(), list);
  44. }
  45. catch (IOException e) {
  46. log.error(e);
  47. }
  48. return new PageInde<T>(pageIndex, pageSize, 0L, list);
  49. }
  50. @Override
  51. public int delete(V id) {
  52. try {
  53. ElasticSearchDocument doc = getEntityProperties();
  54. DeleteResponse delete = elasticsearchClient.delete(d -> d
  55. .index(doc.index())
  56. .id(id.toString()));
  57. return delete.forcedRefresh() ? 1 : 0;
  58. }
  59. catch (IOException e) {
  60. log.error(e);
  61. }
  62. return 0;
  63. }
  64. @Override
  65. public List<T> getAll() {
  66. try {
  67. ElasticSearchDocument doc = getEntityProperties();
  68. ElasticClientUtils elasticClientUtils = new ElasticClientUtils();
  69. EsQueryDTO dto = new EsQueryDTO();
  70. dto.setIndexName(doc.index());
  71. return elasticClientUtils.queryAll(elasticsearchClient, dto, getEntityClass());
  72. }
  73. catch (IOException e) {
  74. log.error(e);
  75. }
  76. return null;
  77. }
  78. @Override
  79. public long count() {
  80. try {
  81. ElasticSearchDocument doc = getEntityProperties();
  82. EsQueryDTO dto = new EsQueryDTO();
  83. dto.setIndexName(doc.index());
  84. return ElasticClientUtils.queryCountByFiled(elasticsearchClient, dto);
  85. }
  86. catch (IOException e) {
  87. log.error(e);
  88. }
  89. return 0;
  90. }
  91. @Override
  92. public IndexResponse createByFluentDSL(T entity) {
  93. try {
  94. ElasticSearchDocument doc = getEntityProperties();
  95. IndexResponse response = elasticsearchClient.index(index -> idx
  96. .index(doc.index())
  97. .id(entity.getId().toString())
  98. .document(entity));
  99. return response;
  100. }
  101. catch (IOException e) {
  102. log.error(e);
  103. }
  104. return null;
  105. }
  106. @Override
  107. public IndexResponse createByBuilderPattern(T entity) {
  108. try {
  109. ElasticSearchDocument doc = getEntityProperties();
  110. IndexRequest.Builder<Object> indexReqBuilder = new IndexRequest.Builder<>();
  111. indexReqBuilder.index(doc.index());
  112. indexReqBuilder.id(entity.getId().toString());
  113. indexReqBuilder.document(entity);
  114. return elasticsearchClient.index(indexReqBuilder.build());
  115. }
  116. catch (IOException e) {
  117. log.error(e);
  118. }
  119. return null;
  120. }
  121. @Override
  122. public BulkResponse bulkCreate(List<T> documents) {
  123. try {
  124. ElasticSearchDocument doc = getEntityProperties();
  125. BulkRequest.Builder br = new BulkRequest.Builder();
  126. documents.stream()
  127. .forEach(esDocument -> br
  128. .operations(op -> op
  129. .index(idx -> idx
  130. .index(doc.index())
  131. .id(esDocument.getId().toString())
  132. .document(esDocument))));
  133. return elasticsearchClient.bulk(br.build());
  134. }
  135. catch (IOException e) {
  136. log.error(e);
  137. }
  138. return null;
  139. }
  140. @Override
  141. public T getById(V id) {
  142. try {
  143. ElasticSearchDocument doc = getEntityProperties();
  144. GetResponse<Object> response = elasticsearchClient.get(g -> g
  145. .index(doc.index())
  146. .id(id.toString()),
  147. Object.class);
  148. return response.found() ? FastJsonUtil.fromJson(response.source().toString(), getEntityClass()) : null;
  149. }
  150. catch (IOException e) {
  151. log.error(e);
  152. }
  153. return null;
  154. }
  155. @Override
  156. public ObjectNode getObjectNodeById(V id) {
  157. try {
  158. ElasticSearchDocument doc = getEntityProperties();
  159. GetResponse<ObjectNode> response = elasticsearchClient.get(g -> g
  160. .index(doc.index())
  161. .id(id.toString()),
  162. ObjectNode.class);
  163. return response.found() ? response.source() : null;
  164. }
  165. catch (IOException e) {
  166. log.error(e);
  167. }
  168. return null;
  169. }
  170. @Override
  171. public BulkResponse bulkDeleteByIds(List<V> docIds) {
  172. try {
  173. ElasticSearchDocument doc = getEntityProperties();
  174. BulkRequest.Builder br = new BulkRequest.Builder();
  175. // 将每一个对象都放入builder中
  176. docIds.stream().forEach(id -> br
  177. .operations(op -> op
  178. .delete(d -> d
  179. .index(doc.index())
  180. .id(id.toString()))));
  181. return elasticsearchClient.bulk(br.build());
  182. }
  183. catch (IOException e) {
  184. log.error(e);
  185. }
  186. return null;
  187. }
  188. /**自动创建映射*/
  189. @Override
  190. public Boolean createIndex() {
  191. try {
  192. ElasticSearchDocument doc = getEntityProperties();
  193. CreateIndexResponse response = elasticsearchClient.indices().create(c -> c.index(doc.index()));
  194. log.info("createIndex方法,acknowledged={}", response.acknowledged());
  195. return response.acknowledged();
  196. }
  197. catch (IOException e) {
  198. log.error(e);
  199. }
  200. return false;
  201. }
  202. /**手动创建映射*/
  203. @Override
  204. public Boolean createIndex(Function<IndexSettings.Builder, ObjectBuilder<IndexSettings>> settingFn,
  205. Function<TypeMapping.Builder, ObjectBuilder<TypeMapping>> mappingFn) {
  206. try {
  207. ElasticSearchDocument doc = getEntityProperties();
  208. CreateIndexResponse response = elasticsearchClient
  209. .indices()
  210. .create(c -> c
  211. .index(doc.index())
  212. .settings(settingFn)
  213. .mappings(mappingFn)
  214. );
  215. log.info("createIndex方法,acknowledged={}", response.acknowledged());
  216. return response.acknowledged();
  217. }
  218. catch (IOException e) {
  219. log.error(e);
  220. }
  221. return false;
  222. }
  223. @Override
  224. public Boolean deleteIndex() {
  225. try {
  226. ElasticSearchDocument doc = getEntityProperties();
  227. DeleteIndexResponse response = elasticsearchClient.indices().delete(c -> c.index(doc.index()));
  228. log.info("deleteIndex方法,acknowledged={}", response.acknowledged());
  229. return response.acknowledged();
  230. }
  231. catch (IOException e) {
  232. log.error(e);
  233. }
  234. return false;
  235. }
  236. @Override
  237. public Boolean updateIndexProperty(HashMap<String, Property> propertyMap) {
  238. try {
  239. ElasticSearchDocument doc = getEntityProperties();
  240. PutMappingResponse response = elasticsearchClient.indices()
  241. .putMapping(typeMappingBuilder ->
  242. typeMappingBuilder
  243. .index(doc.index())
  244. .properties(propertyMap)
  245. );
  246. log.info("updateIndexMapping方法,acknowledged={}", response.acknowledged());
  247. return response.acknowledged();
  248. }
  249. catch (IOException e) {
  250. log.error(e);
  251. }
  252. return false;
  253. }
  254. @Override
  255. public GetIndexResponse getIndexList() {
  256. try {
  257. ElasticSearchDocument doc = getEntityProperties();
  258. //使用 * 或者 _all都可以
  259. GetIndexResponse response = elasticsearchClient.indices().get(builder -> builder.index("_all"));
  260. log.info("getIndexList方法,response.result()={}", response.result().toString());
  261. return response;
  262. }
  263. catch (IOException e) {
  264. log.error(e);
  265. }
  266. return null;
  267. }
  268. @Override
  269. public GetIndexResponse getIndexDetail() {
  270. try {
  271. ElasticSearchDocument doc = getEntityProperties();
  272. GetIndexResponse response = elasticsearchClient.indices().get(builder -> builder.index(doc.index()));
  273. log.info("getIndexDetail方法,response.result()={}", response.result().toString());
  274. return response;
  275. }
  276. catch (IOException e) {
  277. log.error(e);
  278. }
  279. return null;
  280. }
  281. @Override
  282. public boolean indexExists() {
  283. try {
  284. ElasticSearchDocument doc = getEntityProperties();
  285. return elasticsearchClient.indices().exists(b -> b.index(doc.index())).value();
  286. }
  287. catch (IOException e) {
  288. log.error(e);
  289. }
  290. return null;
  291. }
  292. }

2.5.业务

2.5.1.接口

  1. pulbic interface testRepo extends IElasticSearchIRepository<TestESDO, Long> {
  2. }

2.5.2. 实现类

  1. @component
  2. pulbic calss testRepo extends ElasticSearchIRepository<TestESDO, Long> implements testRepo{
  3. /**设置索引全局配置*/
  4. @Override
  5. protected Function<IndexSettings.builder, ObjectBuilder<IndexSettings>> getIndexSettings() {
  6. return builder -> builder.numberOfShards("3").numberOfReplicas("1");
  7. }
  8. /**手动设置映射(不手动设置会自动创建映射,同时在插入时若手动映射时没有的字段也会自动创建)*/
  9. @Override
  10. protected Function<TypeMapping.builder, ObjectBuilder<TypeMapping>> getIndexMappings() {
  11. return builder -> {
  12. HashMap<String, Property> propertiesMap = new HashMap<>();
  13. propertiesMap.put("id", new Property.Builder().Long_(new LongNumberProperty.Builder().build()).build());
  14. return builder.properties(propertiesMap);
  15. }
  16. }
  17. @Override
  18. protected Class<T> getEntityClass() {
  19. return TestESDO.clas;
  20. }
  21. }

2.5.3. 实体类

  1. @Data
  2. @ElasticSearchCocument(index="test")
  3. public class TestESDO {
  4. private Long id;
  5. }

2.5.4. 常见查询方法

1.使用MultiMatch可以多字段,如果想要把搜索词当成一个整体来匹配查询还需要增加TextQueryType.Phrase,如

  1. //must复合查询
  2. List<Query> queries = new ArrayLict<>();
  3. MultiMatchQuery multiMatchQuery = new MultiMatchQuery.Builder()
  4. .query("搜索词")
  5. .type(TextQueryType.Phrase)
  6. .fields("字段1", "字段2")
  7. .build();
  8. Query query = new Query.Builder()
  9. .multiMatch(multiMatchQuery).build();
  10. queries.add(multiMatchQuery);

2.使用TermsQuery进行数组过滤,如对某个字段[1,2,3,4]进行过滤,要求只有搜索词中包含这些数字就进行匹配,如4,5或者1,2,3或者1,代码如下

  1. //过滤
  2. List<Query> filters = new ArrayLict<>();
  3. List<FieldValue> fieldValueList = new ArrayList<>();
  4. fieldValueList.add(new FieldValue.Builder().longValue(1).buld());
  5. TermsQuery termsQuery = new TermsQuery .Builder()
  6. .field("字段1")
  7. .terms(new TermsQueryField.Builder().value(fieldValueList).build())
  8. .build();
  9. Query filter = new Query.Builder()
  10. .terms(termsQuery).build();
  11. filters.add(filter);

3.更多查询参见:ElasticSearch使用教程、设计到实战-CSDN博客


本文转载自: https://blog.csdn.net/qq_42217201/article/details/136843356
版权归原作者 浮生%未歇 所有, 如有侵权,请联系我们删除。

“Elasticsearch8搭建及Springboot中集成使用”的评论:

还没有评论