Elasticsearch8.10 java 示例

1. SpringBoot 版本:3.2.3

    elasticsearch-java 版本:8.10.4

    jdk: 17

    elasticsearch 数据库版本:7.6.2

2.. pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         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>

    <groupId>com.wjh</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <java.version>17</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-cloud.version>2023.0.0</spring-cloud.version>
        <spring.cloud.alibaba.version>2022.0.0.0</spring.cloud.alibaba.version>
        <jackson.version>2.16.1</jackson.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring.cloud.alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-commons</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 请求参数校验 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <!-- 单元测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>3.0.3</version>
        </dependency>
        <!-- mybatis-plus 分页插件 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.5</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.21</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>

        <!-- Redis -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.27.1</version>
        </dependency>

        <!-- ElasticSearch -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>

        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.12.0</version>
        </dependency>
        <!-- Http -->
        <dependency>
            <groupId>org.apache.httpcomponents.client5</groupId>
            <artifactId>httpclient5</artifactId>
            <version>5.3.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>${jackson.version}</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.47</version>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.26</version>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.13.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.13.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.4</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
        </dependency>

        <!-- 接口文档 -->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
            <version>4.1.0</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!--<version>2.6.7</version>-->
                <configuration>
                    <!--<fork>true</fork>-->
                    <classifier>exec</classifier>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-clean-plugin</artifactId>
                <version>3.1.0</version>
            </plugin>
            <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.0.2</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.1</version>
                <configuration>
                    <!-- 跳过单元测试 -->
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.0.2</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-install-plugin</artifactId>
                <version>2.5.2</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>2.8.2</version>
            </plugin>
            <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-site-plugin</artifactId>
                <version>3.7.1</version>
            </plugin>
        </plugins>
    </build>
    
</project>

3. application.yml

server:
  port: 8056
  servlet:
    context-path: /
spring:
  application:
    name: elasticsearch
  profiles:
    active: dev  # 环境设置:dev、test、prod

mybatis:
  mapper-locations: classpath*:mapper/*Mapper.xml
  type-aliases-package: com.wjh.entity
  configuration:
    map-underscore-to-camel-case: true  # 开启驼峰命名法
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

springdoc:
  swagger-ui:
    enabled: true  # 开启Swagger UI界面
    display-request-duration: true  # 展示请求所耗时间ms
    operationsSorter: method  # api排序方式(alpha:字母, method:http方法)
    path: /swagger-ui  # Swagger UI路径
  #    paths-to-match: /public/**,/admin/**  # 配置需要生成接口文档的接口路径
  packages-to-scan: com.wjh.web # 配置需要生成接口文档的接口路径

#knife4j相关配置 可以不用改
knife4j:
  enable: true
  setting:
    language: zh_cn
    swagger-model-name: 实体类

logging:
  config: classpath:logback.xml
  level:
    com.wjh: debug

http:
  maxTotal: 100         #最大连接数
  defaultMaxPerRoute: 20  #并发数
  connectTimeout: 1000   #创建连接的最长时间
  connectionRequestTimeout: 500  #从连接池中获取到连接的最长时间
  socketTimeout: 10000 #数据传输的最长时间
  staleConnectionCheckEnabled: true  #提交请求前测试连接是否可用
  validateAfterInactivity: 3000000   #可用空闲连接过期时间,重用空闲连接时会先检查是否空闲时间超过这个时间,如果超过,释放socket重新建立


4. application-dev.yml

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/flink?serverTimezone=UTC
    username: root
    password: root
    initial-size: 8
    max-active: 16
    min-idle: 8
    max-wait: 60000
    test-while-idle: true
    test-on-borrow: false
    test-on-return: false
  redis:
    host: 192.168.59.144
    port: 6379
    password: WTsGpUzM5mug5f
    database: 2
    timeout: 60          #连接超时时间(毫秒)
    jedis:
      pool:
        max_total: 500   #控制一个pool可分配多少个jedis实例,用来替换max-active,如果是jedis 2.4以后用该属性
        #max-active: 10   #连接池最大连接数(负值表示没有限制)
        max-wait: 3000   #连接池最大阻塞等待时间(负值表示没有限制)
        max-idle: 10     #连接池最大空闲连接数
        min-idle: 1      #连接汉最小空闲连接数
        max_wait_millis: 1000 #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制
        min_evictable_idle_time_millis: 300000 #连接的最小空闲时间 默认1800000毫秒(30分钟)
        num_tests_per_eviction_run: 3    #每次释放连接的最大数目,默认3
        time_between_eviction_runs_millis: 30000  #逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
        test_on_borrow: true  #是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
        test_while_idle: true #在空闲时检查有效性, 默认false
  elasticsearch:
    rest:
      url: 127.0.0.1
      port: 9200
      uris: 127.0.0.1:9200
      scheme: http
      connection-timeout: 1000
      read-timeout: 3000
      username:
      password:
  data:
    elasticsearch:
      cluster-name: my-application
      cluster-nodes: 127.0.0.1:9300
md5:  # md5加密
  key: 76e7ac9d7134a81381af18b626c23088  # md5秘钥



snow:  # 雪花算法
  work:
    id: 20
  data:
    id: 20

5. ElasticsearchConfig.java

import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.message.BasicHeader;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import lombok.extern.slf4j.Slf4j;

/**
 * @author 
 * @date 2024/3/12
 * @since JDK 17
 */
@Slf4j
@Configuration
public class ElasticsearchConfig {
	@Value("${spring.elasticsearch.rest.url}")
	private String url;

	@Value("${spring.elasticsearch.rest.port}")
	private int port;

	@Value("${spring.elasticsearch.rest.username}")
	private String userName;

	@Value("${spring.elasticsearch.rest.password}")
	private String password;

	@Value("${spring.elasticsearch.rest.scheme}")
	private String scheme;

	@Bean
	public ElasticsearchClient getClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
		Header[] defaultHeaders = { new BasicHeader("charset", "utf-8"),
				new BasicHeader("content-type", "application/json") };

		RestClientBuilder clientBuilder = RestClient.builder(new HttpHost(url, port, scheme));
		clientBuilder.setHttpClientConfigCallback(
				httpClientBuilder -> httpClientBuilder.setDefaultHeaders(Arrays.asList(defaultHeaders))
						.addInterceptorLast((HttpResponseInterceptor) (response, context) -> response
								.addHeader("X-Elastic-Product", "Elasticsearch")));

		RestClient restClient = clientBuilder.build();

		ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());

		return new ElasticsearchClient(transport);
	}
}

6. ElasticsearchController.java

import com.wjh.request.FilePageRequest;
import io.swagger.v3.oas.annotations.Parameter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson2.JSON;
import com.wjh.base.ResponseApiData;
import com.wjh.entity.FileInfo;
import com.wjh.request.KeyPageRequest;
import com.wjh.service.IFileService;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;

/**
 * @author 
 * @date 2024/3/12
 * @since JDK 17
 */
@Slf4j
@Tag(name = "Elasticsearch AIP接口", description = "Elasticsearch AIP接口")
@RestController
@RequestMapping("/api/es")
public class ElasticsearchController {

    @Autowired
    private IFileService fileService;

    @Operation(summary = "保存文件信息", description = "保存文件信息")
    @PostMapping("/save/file")
    public ResponseApiData<?> saveFile(@RequestBody FileInfo fileInfo) {
        log.info("保存文件信息-开始.请求参数:{}", JSON.toJSONString(fileInfo));
        try {
            fileService.save(fileInfo);

            return ResponseApiData.success();
        } catch (Exception e) {
            log.error(String.format("保存文件信息-失败.请求参数:%s", JSON.toJSONString(fileInfo)), e);
            return ResponseApiData.systemFail("保存文件信息失败");
        }
    }

    @Operation(summary = "根据关键字分页查询", description = "根据关键字分页查询")
    @PostMapping("/file/keyPage")
    public ResponseApiData<Page<FileInfo>> keyPage(@RequestBody KeyPageRequest request) {
        log.info("根据关键字分页查询-开始.请求参数:{}", JSON.toJSONString(request));
        try {
            return ResponseApiData.success(fileService.keyPage(request));
        } catch (Exception e) {
            log.error(String.format("根据关键字分页查询-失败.请求参数:%s", JSON.toJSONString(request)), e);
            return ResponseApiData.systemFail("根据关键字分页查询失败");
        }
    }

    @Operation(summary = "分页查询文件信息", description = "分页查询文件信息")
    @PostMapping("/file/page")
    public ResponseApiData<Page<FileInfo>> filePage(@RequestBody FilePageRequest request) {
        log.info("分页查询文件信息-开始.请求参数:{}", JSON.toJSONString(request));
        try {
            return ResponseApiData.success(fileService.page(request));
        } catch (Exception e) {
            log.error(String.format("分页查询文件信息-失败.请求参数:%s", JSON.toJSONString(request)), e);
            return ResponseApiData.systemFail("分页查询文件信息失败");
        }
    }

    @Operation(summary = "查询文件详情", description = "查询文件详情",
            parameters = {@Parameter(name = "id", description = "id")}
    )
    @GetMapping("/file/detail/{id}")
    public ResponseApiData<FileInfo> fileDetail(@PathVariable String id) {
        log.info("查询文件详情-开始.id:{}", id);

        if (StringUtils.isBlank(id)) {
            return ResponseApiData.parameterFail("id不能为空");
        }
        try {
            return ResponseApiData.success(fileService.detail(id));
        } catch (Exception e) {
            log.error(String.format("查询文件详情-失败.id:%s", id), e);
            return ResponseApiData.systemFail("查询文件详情失败");
        }
    }
}

7. IFileService.java

/**
 * @author 
 * @date 2024/3/12
 * @since JDK 17
 */
public interface IFileService {
	void save(FileInfo fileInfo);

	FileInfo detail(String id);

	/**
	 * 根据关键字分页查询
	 *
	 * @date 2024-03-13
	 * @param request 请求参数
	 * @return Page
	 * @since JDK 17
	 * @author 
	 */
	Page<FileInfo> keyPage(KeyPageRequest request);

	/**
	 * 分页查询文件信息
	 *
	 * @date 2024-03-13
	 * @param request 查询条件
	 * @return Page
	 * @since JDK 17
	 * @author 
	 */
	Page<FileInfo> page(FilePageRequest request);
}

8. FileServiceImpl.java

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
import org.springframework.data.elasticsearch.client.elc.NativeQueryBuilder;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.Order;
import org.springframework.stereotype.Service;

import com.wjh.common.CommonMethods;
import com.wjh.common.Constants;
import com.wjh.entity.FileInfo;
import com.wjh.mapper.IFileRepository;
import com.wjh.request.FilePageRequest;
import com.wjh.request.KeyPageRequest;
import com.wjh.service.IFileService;
import com.wjh.utils.DateUtil;
import com.wjh.utils.JsonUtils;

import co.elastic.clients.elasticsearch._types.query_dsl.BoolQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders;
import co.elastic.clients.json.JsonData;
import lombok.extern.slf4j.Slf4j;

/**
 * @author 
 * @date 2024/3/12
 * @since JDK 17
 */
@Slf4j
@Service
public class FileServiceImpl implements IFileService {

	@Autowired
	private ElasticsearchTemplate elasticsearchTemplate;

	@Autowired
	private IFileRepository fileRepository;

	@Override
	public void save(FileInfo fileInfo) {
		if (fileInfo.getId() == null || StringUtils.isBlank(fileInfo.getId())) {
			fileInfo.setId(CommonMethods.getMeUUID());
		}
		if (fileInfo.getCreateTime() == null) {
			fileInfo.setCreateTime(new Date());
		}
		if (fileInfo.getUpdateTime() == null) {
			fileInfo.setUpdateTime(new Date());
		}
		fileRepository.save(fileInfo);
	}

	@Override
	public FileInfo detail(String id) {
		if (StringUtils.isBlank(id)) {
			return null;
		}
		Optional<FileInfo> opt = fileRepository.findById(id.trim());
		return opt.orElse(null);
	}

	/**
	 * 根据关键字分页查询
	 *
	 * @date 2024-03-13
	 * @param request  请求参数
	 * @return Page
	 * @since JDK 17
	 * @author 
	 */
	@Override
	public Page<FileInfo> keyPage(KeyPageRequest request) {

		if (request.getPageNo() == null || request.getPageNo().intValue() <= 0) {
			request.setPageNo(Constants.DEFAULT_PAGE_NUM);
		}
		if (request.getPageSize() == null || request.getPageSize() <= 0) {
			request.setPageSize(Constants.DEFAULT_PAGE_SIZE);
		}
		int offset = (request.getPageNo() - 1) * request.getPageSize();

		Sort sort = Sort.by(new Order(Sort.Direction.DESC, "create_time")/*,new Order(Sort.Direction.DESC, "_score")*/);

		Pageable pageable = PageRequest.of(offset, request.getPageSize(), sort);

		BoolQuery.Builder bqb = QueryBuilders.bool();

		if (StringUtils.isNotBlank(request.getKeyword())) {
			// 模糊查询
			bqb.must(m -> m.match(ma -> ma.field("content").query(request.getKeyword().trim())));
		}
		NativeQueryBuilder nativeQueryBuilder = new NativeQueryBuilder();
		nativeQueryBuilder.withQuery(bqb.build()._toQuery()).withPageable(pageable);

		NativeQuery nativeQuery = nativeQueryBuilder.build();

		SearchHits<FileInfo> searchHits = elasticsearchTemplate.search(nativeQuery, FileInfo.class);

        long totalCount = searchHits.getTotalHits();

        List<SearchHit<FileInfo>> searchHitList = searchHits.getSearchHits();

		Page<FileInfo> page = new PageImpl<>(new ArrayList<>(), pageable, totalCount);

        if (CollectionUtils.isNotEmpty(searchHitList)) {
            List<FileInfo> fileList = new ArrayList<>(searchHitList.size());

            for (SearchHit<FileInfo> searchHit : searchHitList) {
                fileList.add(searchHit.getContent());
            }
            page = new PageImpl<>(fileList, pageable, totalCount);
        }
        return page;
	}

	/**
	 * 分页查询文件信息
	 *
	 * @param request 查询条件
	 * @return Page
	 * @date 2024-03-13
	 * @author 
	 * @since JDK 17
	 */
	@Override
	public Page<FileInfo> page(FilePageRequest request) {
		// 去除前后空格
		request = CommonMethods.beanStrim(request);

		if (request.getPageNo() == null || request.getPageNo().intValue() <= 0) {
			request.setPageNo(Constants.DEFAULT_PAGE_NUM);
		}
		if (request.getPageSize() == null || request.getPageSize() <= 0) {
			request.setPageSize(Constants.DEFAULT_PAGE_SIZE);
		}
		// 查询起始日期(yyyy-MM-dd)
		String beginDate = request.getBeginDate();
		// 查询截止日期(yyyy-MM-dd)
		String endDate = request.getEndDate();

		if (StringUtils.isNotBlank(beginDate) && beginDate.length() == Constants.DATE_LENGTH) {
			request.setBeginDate(beginDate + " 00:00:00");
		}
		if (StringUtils.isNotBlank(endDate) && endDate.length() == Constants.DATE_LENGTH) {
			request.setEndDate(endDate + " 23:59:59");
		}
		final FilePageRequest filePageRequest = JsonUtils.parse(JsonUtils.toJSONBytes(request), FilePageRequest.class);

		BoolQuery.Builder bqb = QueryBuilders.bool();

		if (StringUtils.isNotBlank(filePageRequest.getFileName())) {
			// 模糊查询
			bqb.must(m -> m.match(ma -> ma.field("file_name").query(filePageRequest.getFileName())));
		}
		if (StringUtils.isNotBlank(filePageRequest.getFileType())) {
			// 模糊查询
			bqb.must(m -> m.match(ma -> ma.field("file_type").query(filePageRequest.getFileType())));
		}
		if (StringUtils.isNotBlank(filePageRequest.getBeginDate())) {
			// RangeQuery rangeQuery = QueryBuilders.range().field("create_time").gte(JsonData.of(filePageRequest.getBeginDate())).build();
			Query query =
					Query.of(q -> q
							.range(r -> {
										r.field("create_time");
										r.gte(JsonData.of(DateUtil.parseDate(filePageRequest.getBeginDate(), DateUtil.formatPattern)));
										return r;
									}
							)
					);
			bqb.must(query);
		}
		if (StringUtils.isNotBlank(filePageRequest.getEndDate())) {
			Query query =
					Query.of(q -> q
							.range(r -> {
										r.field("create_time");
										r.lte(JsonData.of(DateUtil.parseDate(filePageRequest.getEndDate(), DateUtil.formatPattern)));
										return r;
									}
							)
					);
			bqb.must(query);
		}
		int offset = (filePageRequest.getPageNo() - 1) * filePageRequest.getPageSize();

		Sort sort = Sort.by(new Order(Sort.Direction.DESC, "create_time")/*,new Order(Sort.Direction.DESC, "_score")*/);

		Pageable pageable = PageRequest.of(offset, filePageRequest.getPageSize(), sort);

		NativeQueryBuilder nativeQueryBuilder = new NativeQueryBuilder();
		nativeQueryBuilder.withQuery(bqb.build()._toQuery()).withPageable(pageable);

		NativeQuery nativeQuery = nativeQueryBuilder.build();

		SearchHits<FileInfo> searchHits = elasticsearchTemplate.search(nativeQuery, FileInfo.class);

		long totalCount = searchHits.getTotalHits();

		List<SearchHit<FileInfo>> searchHitList = searchHits.getSearchHits();

		Page<FileInfo> page = new PageImpl<>(new ArrayList<>(), pageable, totalCount);

		if (CollectionUtils.isNotEmpty(searchHitList)) {
			List<FileInfo> fileList = new ArrayList<>(searchHitList.size());

			for (SearchHit<FileInfo> searchHit : searchHitList) {
				fileList.add(searchHit.getContent());
			}
			page = new PageImpl<>(fileList, pageable, totalCount);
		}
		return page;
	}
}

9. IFileRepository.java

import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

import com.wjh.entity.FileInfo;

/**
 * @author 
 * @date 2024/3/12
 * @since JDK 17
 */
//@Repository
public interface IFileRepository extends ElasticsearchRepository<FileInfo, String> {
}

10. FileInfo.java

import java.io.Serial;
import java.io.Serializable;
import java.util.Date;

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 com.baomidou.mybatisplus.annotation.TableField;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

/**
 * Elasticsearch 实体类
 * 
 * @author 
 * @date 2024/3/12
 * @since JDK 17
 */
@Data
@EqualsAndHashCode(callSuper = false)
@ToString(callSuper = true)
@Document(indexName = "file_info", createIndex = false)
public class FileInfo implements Serializable {
	@Serial
	private static final long serialVersionUID = 4651439852938664760L;

	/** 主键 */
	@Field(name = "id", type = FieldType.Long)
	@Id
	private String id;

	/** 文件名称 */
	@Field(name = "file_name", type = FieldType.Text, analyzer = "jieba_index", searchAnalyzer = "jieba_index")
	private String fileName;

	/**
	 * 文件类型
	 */
	@Field(name = "file_type", type = FieldType.Keyword)
	private String fileType;

	/**
	 * 内容类型
	 */
	@Field(name = "content_type", type = FieldType.Text)
	private String contentType;

	/**
	 * 附件内容
	 */
	@Field(name = "content", type = FieldType.Text, analyzer = "jieba_index", searchAnalyzer = "jieba_index")
	@TableField(exist = false)
	private String content;

	/**
	 * 文件地址
	 */
	@Field(name = "file_url", type = FieldType.Text)
	private String fileUrl;

	/**
	 * 创建时间
	 */
	@Field(name = "create_time", type = FieldType.Date)
	private Date createTime;

	/**
	 * 更新时间
	 */
	@Field(name = "update_time", type = FieldType.Date)
	private Date updateTime;
}

11. JsonUtils.java

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;

/**
 * @author 
 * @date 2022/5/29
 * @since JDK 17
 */
public final class JsonUtils {

	private JsonUtils() {
	}

	/**
	 * 根据JSON字符串解析出java对象
	 * <p>
	 * 需要提供java对象类型
	 *
	 * @param text  JSON字符串,不能为<code>NULL</code>
	 * @param clazz java对象类型
	 * @return java对象
	 */
	public static final <T> T parse(String text, Class<T> clazz) {
		return JSON.parseObject(text, clazz);
	}

	/**
	 * 根据字节数组解析出java对象
	 * <p>
	 * 需要提供java对象类型
	 *
	 * @param input 字节数组
	 * @param clazz java对象类型
	 * @return java对象
	 */
	public static final <T> T parse(byte[] input, Class<T> clazz) {
		return JSON.parseObject(input, clazz, new Feature[0]);
	}

	/**
	 * 根据java对象转换成字节数组
	 * <p>
	 * 按照默认方式转换,只输出属性和属性值信息,不加入任何其他类型信息
	 *
	 * @param object java对象
	 * @return 字节数组
	 */
	public static final byte[] toJSONBytes(Object object) {
		return JSON.toJSONBytes(object, new SerializerFeature[0]);
	}

	/**
	 * 获取JSON串中指定的key对应的值
	 *
	 * @param json
	 * @param key
	 * @return String
	 * @author 
	 * @date 2018年11月12日
	 * @since JDK 1.7
	 */
	public static String getJsonValue(String json, String key) {
		if (StringUtils.isBlank(json) || StringUtils.isBlank(key)) {
			return null;
		}
		JSONObject jsonObj = JSONObject.parseObject(json);
		return jsonObj.getString(key);
	}

	/**
	 * 获取JSON串中指定的key对应的值
	 *
	 * @param json 数组
	 * @param key
	 * @return String
	 * @author 
	 * @date 2018年12月12日
	 * @since JDK 1.7
	 */
	public static List<String> getJsonArrayValue(String json, String key) {

		if (StringUtils.isBlank(json) || StringUtils.isBlank(key)) {
			return null;
		}

		List<String> list = new ArrayList<>();

		JSONArray jsonArray = JSON.parseArray(json);

		if (jsonArray != null) {

			for (int i = 0; i < jsonArray.size(); i++) {

				JSONObject jsonObj = jsonArray.getJSONObject(i);

				list.add(jsonObj.getString(key));
			}
		}
		return list;
	}

	public static String toJsonStringFormat(Object obj) {
		// 自定义时间格式
		JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

		return JSON.toJSONString(obj, //
				// SerializerFeature.PrettyFormat, // 格式化结果
				SerializerFeature.WriteMapNullValue, // 输出值为null的字段
				SerializerFeature.WriteNullStringAsEmpty, // 字符类型字段如果为null,输出为”“,而非null
				// SerializerFeature.WriteNullNumberAsZero, // 数值字段如果为null,输出为0,而非null
				// SerializerFeature.DisableCircularReferenceDetect, // 消除对同一对象循环引用的问题
				SerializerFeature.WriteNullListAsEmpty, // List字段如果为null,输出为[],而非null
				SerializerFeature.WriteDateUseDateFormat, // 自定义时间格式
				SerializerFeature.DisableCircularReferenceDetect // 消除循环引用
		);
	}
}

12. DateUtil.java

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期工具类
 * @author zsq
 */
public class DateUtil {

    public static final String formatPattern = "yyyy-MM-dd HH:mm:ss";


    public static final String formatPattern2 = "HH:mm:ss";

    public static final String formatPattern3 = "yyyy-MM-dd";

    public static final String formatPattern4 = "yyyy-MM-dd HH:mm";

    public static final String formatPattern5 = "HH:mm";


    /**
     * 避免高并发下,多线程引发的时间错误,报错问题,SimpleDateFormat是线程不安全的
     */
    public static ThreadLocal<DateFormat> DATE_FORMAT = new ThreadLocal<DateFormat>(){
        @Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat(formatPattern);
        }
    };

    /**
     * 避免高并发下,多线程引发的时间错误,报错问题,SimpleDateFormat是线程不安全的
     */
    public static ThreadLocal<DateFormat> DATE_FORMAT_3 = new ThreadLocal<DateFormat>(){
        @Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat(formatPattern3);
        }
    };

    /**
     * 避免高并发下,多线程引发的时间错误,报错问题,SimpleDateFormat是线程不安全的
     */
    public static ThreadLocal<DateFormat> DATE_FORMAT_4 = new ThreadLocal<DateFormat>(){
        @Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat(formatPattern4);
        }
    };

    /**
     * 避免高并发下,多线程引发的时间错误,报错问题,SimpleDateFormat是线程不安全的
     */
    public static ThreadLocal<DateFormat> DATE_FORMAT_5 = new ThreadLocal<DateFormat>(){
        @Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat(formatPattern5);
        }
    };

    /**
     * 获取当前时间字符串
     * @return
     */
    public static String getNowTimeStr(){
        Date nowTime = Calendar.getInstance().getTime();
        String nowTimeStr = DATE_FORMAT.get().format(nowTime);
        return nowTimeStr;
    }

    /**
     * 格式化日期对象
     * @param time
     * @return
     */
    public static String format(Date time){
        return format(time, formatPattern);
    }

    /**
     * 格式化日期对象
     * @param time
     * @param pattern
     * @return
     */
    public static String format(Date time, String pattern){
        DateFormat dateFormat = new SimpleDateFormat(pattern);
        String str = dateFormat.format(time);
        return str;
    }

    /**
     * 格式化日期对象
     * @param time
     * @return
     */
    public static String format(Date time, DateFormat dateFormat){
        String str = dateFormat.format(time);
        return str;
    }

    /**
     * 字符串转日期对象
     * @param timeStr
     * @param pattern
     * @return
     */
    public static Date parseDate(String timeStr, String pattern) {
        try {
            DateFormat dateFormat = new SimpleDateFormat(pattern);
            Date parseDate = dateFormat.parse(timeStr);
            return parseDate;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 字符串转日期对象
     * @param timeStr
     * @param dateFormat
     * @return
     */
    public static Date parseDate(String timeStr, DateFormat dateFormat) throws ParseException {
        Date parseDate = dateFormat.parse(timeStr);
        return parseDate;
    }

    /**
     * 字符串转日期对象
     * @param timeStr
     * @return
     */
    public static Date parseDate(String timeStr) throws ParseException {
        return parseDate(timeStr, formatPattern);
    }

    /**
     * 两个日期对象相差秒
     * @return
     */
    public static long diffSecond(Date begin, Date end){
        long diffMillisecond = end.getTime() - begin.getTime();
        return diffMillisecond / 1000L;
    }

    /**
     * 判断日期在两个日期之间
     * @param begin 开始日期
     * @param mid 判断的日期
     * @param end 结束日期
     * @return 是否存在俩日期之间
     */
    public static boolean betweenDays(Date begin, Date mid, Date end){
        if(mid.getTime() >= begin.getTime() && mid.getTime() < end.getTime()){
            return true;
        }

        return false;
    }

    /**
     * 获取当前日期之前或之后的指定天数的日期
     * @param num 指定天数
     * @return 指定天数之前或之后的日期
     */
    public static Date getBeforeOrAfterDay(int num) {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, num);
        return c.getTime();
    }

}

13. EsPageRequest.java

import java.io.Serial;
import java.io.Serializable;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

/**
 * 分页查询 公共请求参数
 * 
 * @author 
 * @date 2024/3/13
 * @since JDK 17
 */
@Data
@EqualsAndHashCode(callSuper = false)
@ToString(callSuper = true)
public class EsPageRequest implements Serializable {
	@Serial
	private static final long serialVersionUID = 2403543093430201749L;

	/** 第几页 */
	@Schema(description = "第几页", example = "1")
	private Integer pageNo;

	/** 每页数量 */
	@Schema(description = "每页数量", example = "10")
	private Integer pageSize;

	/** 查询起始日期(yyyy-MM-dd) */
	@Schema(description = "查询起始日期(yyyy-MM-dd)", example = "2024-01-01")
	private String beginDate;

	/** 查询截止日期(yyyy-MM-dd) */
	@Schema(description = "查询截止日期(yyyy-MM-dd)", example = "2024-12-31")
	private String endDate;
}

14. KeyPageRequest.java

import java.io.Serial;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

/**
 * 根据关键字分页查询 请求参数
 * 
 * @author 
 * @date 2024/3/13
 * @since JDK 17
 */
@Data
@EqualsAndHashCode(callSuper = false)
@ToString(callSuper = true)
public class KeyPageRequest extends EsPageRequest {
	@Serial
	private static final long serialVersionUID = 6781615780605296835L;

	/** 关键字 */
	@Schema(description = "关键字")
	private String keyword;
}

15. FilePageRequest.java

import java.io.Serial;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

/**
 * 分页查询文件信息 请求参数
 * 
 * @author 
 * @date 2024/3/13
 * @since JDK 17
 */
@Data
@EqualsAndHashCode(callSuper = false)
@ToString(callSuper = true)
public class FilePageRequest extends EsPageRequest {
	@Serial
	private static final long serialVersionUID = 4370781146647964020L;

	/** 文件名称 */
	@Schema(description = "文件名称")
	private String fileName;

	/** 文件类型 */
	@Schema(description = "文件类型")
	private String fileType;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值