Home  >  Article  >  Java  >  How SpringBoot+Elasticsearch implements data search

How SpringBoot+Elasticsearch implements data search

WBOY
WBOYforward
2023-05-12 21:04:041080browse

    1. Introduction

    SpringBoot connects to ElasticSearch. There are four mainstream ways:

    • Method 1 : Connect to the es server through the Elastic Transport Client. The underlying layer is based on the TCP protocol and communicates with the remote ES server through the transport module. However, it is officially not recommended to use it starting from V7.0 and will be officially removed starting from V8.0.

    • Method 2: Connect to the ES server through the Elastic Java Low Level Rest Client. The underlying layer communicates with the remote ES server through the restful API based on the HTTP protocol. Only the simplest and most basic The API is similar to the API operation logic introduced to you in the previous article.

    • Method 3: Connect to the es server through the Elastic Java High Level Rest Client. The bottom layer is encapsulated based on the Elastic Java Low Level Rest Client to provide a more advanced API. And it is consistent with the Elastic Transport Client interface and parameters. It is the officially recommended es client.

    • Method 4: Connect to the es server through the JestClient client. This is an es client developed by the open source community based on the HTTP protocol. The official claims that the interface and code design are better than the Rest officially provided by ES The client is simpler, more reasonable, and easier to use. It has certain compatibility with the ES server version, but the update speed is not very fast. The current ES version has been released to V7.9, but JestClient only supports V1.0~V6.X version of ES.

    There is another thing that everyone needs to pay attention to, that is the compatibility of version numbers!

    During the development process, everyone needs to pay special attention to the version numbers of the client and the server, and keep them as consistent as possible. For example, the version number of the server es is 6.8.2, then the version number of the client connected to es , preferably 6.8.2. Even if it cannot be consistent due to project reasons, the client version number must be between 6.0.0 and 6.8.2, and should not exceed the server version number, so that the client can maintain normal operation, otherwise many problems will occur. Unexpected problem, if the client is version 7.0.4, the program will report various errors at this time, and even cannot be used!

    Why do you do this? The main reason is the es server. Higher versions are not compatible with lower versions; some API request parameter structures of es6 and es7 are very different, so the client and server version numbers should be kept consistent as much as possible.

    No more nonsense, let’s go straight to the code!

    2. Code practice

    The SpringBoot version number used in this article is 2.1.0.RELEASE, the server side es The version number is 6.8.2, and the client uses the officially recommended Elastic Java High Level Rest Client version number 6.4.2, which is conveniently compatible with the SpringBoot version.

    2.1. Import dependencies

    
    
        org.elasticsearch
        elasticsearch
        6.4.2
    
    
        org.elasticsearch.client
        elasticsearch-rest-client
        6.4.2
    
    
        org.elasticsearch.client
        elasticsearch-rest-high-level-client
        6.4.2
    

    2.2. Configure environment variables

    In the application.properties global configuration file, configure elasticsearch custom environment variables.

    elasticsearch.scheme=http
    elasticsearch.address=127.0.0.1:9200
    elasticsearch.userName=
    elasticsearch.userPwd=
    elasticsearch.socketTimeout=5000
    elasticsearch.connectTimeout=5000
    elasticsearch.connectionRequestTimeout=5000

    2.3. Create the config class of elasticsearch

    @Configuration
    public class ElasticsearchConfiguration {
    
        private static final Logger log = LoggerFactory.getLogger(ElasticsearchConfiguration.class);
    
    
        private static final int ADDRESS_LENGTH = 2;
    
        @Value("${elasticsearch.scheme:http}")
        private String scheme;
    
        @Value("${elasticsearch.address}")
        private String address;
    
        @Value("${elasticsearch.userName}")
        private String userName;
    
        @Value("${elasticsearch.userPwd}")
        private String userPwd;
    
        @Value("${elasticsearch.socketTimeout:5000}")
        private Integer socketTimeout;
    
        @Value("${elasticsearch.connectTimeout:5000}")
        private Integer connectTimeout;
    
        @Value("${elasticsearch.connectionRequestTimeout:5000}")
        private Integer connectionRequestTimeout;
    
        /**
         * 初始化客户端
         * @return
         */
        @Bean(name = "restHighLevelClient")
        public RestHighLevelClient restClientBuilder() {
            HttpHost[] hosts = Arrays.stream(address.split(","))
                    .map(this::buildHttpHost)
                    .filter(Objects::nonNull)
                    .toArray(HttpHost[]::new);
            RestClientBuilder restClientBuilder = RestClient.builder(hosts);
            // 异步参数配置
            restClientBuilder.setHttpClientConfigCallback(httpClientBuilder -> {
                httpClientBuilder.setDefaultCredentialsProvider(buildCredentialsProvider());
                return httpClientBuilder;
            });
    
            // 异步连接延时配置
            restClientBuilder.setRequestConfigCallback(requestConfigBuilder -> {
                requestConfigBuilder.setConnectionRequestTimeout(connectionRequestTimeout);
                requestConfigBuilder.setSocketTimeout(socketTimeout);
                requestConfigBuilder.setConnectTimeout(connectTimeout);
                return requestConfigBuilder;
            });
    
            return new RestHighLevelClient(restClientBuilder);
        }
    
    
        /**
         * 根据配置创建HttpHost
         * @param s
         * @return
         */
        private HttpHost buildHttpHost(String s) {
            String[] address = s.split(":");
            if (address.length == ADDRESS_LENGTH) {
                String ip = address[0];
                int port = Integer.parseInt(address[1]);
                return new HttpHost(ip, port, scheme);
            } else {
                return null;
            }
        }
    
        /**
         * 构建认证服务
         * @return
         */
        private CredentialsProvider buildCredentialsProvider(){
            final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName,
                    userPwd));
            return credentialsProvider;
        }
    }

    At this point, the client configuration is completed, and when the project is started, it will be automatically injected into the Spring ioc container.

    2.4. Index management

    The most important thing in es is the index library. How to create it on the client side? Please see below!

    Create index

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = ElasticSearchApplication.class)
    public class IndexJunit {
    
    
        @Autowired
        private RestHighLevelClient client;
    
        /**
         * 创建索引(简单模式)
         * @throws IOException
         */
        @Test
        public void createIndex() throws IOException {
            CreateIndexRequest request = new CreateIndexRequest("cs_index");
            CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
            System.out.println(response.isAcknowledged());
        }
    
    
        /**
         * 创建索引(复杂模式)
         * 可以直接把对应的文档结构也一并初始化
         * @throws IOException
         */
        @Test
        public void createIndexComplete() throws IOException {
            CreateIndexRequest request = new CreateIndexRequest();
            //索引名称
            request.index("cs_index");
            //索引配置
            Settings settings = Settings.builder()
                    .put("index.number_of_shards", 3)
                    .put("index.number_of_replicas", 1)
                    .build();
            request.settings(settings);
    
            //映射结构字段
            Map properties = new HashMap();
            properties.put("id", ImmutableBiMap.of("type", "text"));
            properties.put("name", ImmutableBiMap.of("type", "text"));
            properties.put("sex", ImmutableBiMap.of("type", "text"));
            properties.put("age", ImmutableBiMap.of("type", "long"));
            properties.put("city", ImmutableBiMap.of("type", "text"));
            properties.put("createTime", ImmutableBiMap.of("type", "long"));
            Map mapping = new HashMap<>();
            mapping.put("properties", properties);
            //添加一个默认类型
            System.out.println(JSON.toJSONString(request));
            request.mapping("_doc",mapping);
            CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
            System.out.println(response.isAcknowledged());
        }
    
    }

    Delete index

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = ElasticSearchApplication.class)
    public class IndexJunit {
    
    
        @Autowired
        private RestHighLevelClient client;
    
        /**
         * 删除索引
         * @throws IOException
         */
        @Test
        public void deleteIndex() throws IOException {
            DeleteIndexRequest request = new DeleteIndexRequest("cs_index1");
            AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
            System.out.println(response.isAcknowledged());
        }
    
    
    }

    Query index

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = ElasticSearchApplication.class)
    public class IndexJunit {
    
    
        @Autowired
        private RestHighLevelClient client;
    
        /**
         * 查询索引
         * @throws IOException
         */
        @Test
        public void getIndex() throws IOException {
            // 创建请求
            GetIndexRequest request = new GetIndexRequest();
            request.indices("cs_index");
            // 执行请求,获取响应
            GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);
            System.out.println(response.toString());
        }
    
    }

    Query whether the index exists

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = ElasticSearchApplication.class)
    public class IndexJunit {
    
    
        @Autowired
        private RestHighLevelClient client;
    
        /**
         * 检查索引是否存在
         * @throws IOException
         */
        @Test
        public void exists() throws IOException {
            // 创建请求
            GetIndexRequest request = new GetIndexRequest();
            request.indices("cs_index");
            // 执行请求,获取响应
            boolean response = client.indices().exists(request, RequestOptions.DEFAULT);
            System.out.println(response);
        }
    
    }

    Query all index names

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = ElasticSearchApplication.class)
    public class IndexJunit {
    
    
        @Autowired
        private RestHighLevelClient client;
    
        /**
         * 查询所有的索引名称
         * @throws IOException
         */
        @Test
        public void getAllIndices() throws IOException {
            GetAliasesRequest request = new GetAliasesRequest();
            GetAliasesResponse response =  client.indices().getAlias(request,RequestOptions.DEFAULT);
            Map> map = response.getAliases();
            Set indices = map.keySet();
            for (String key : indices) {
                System.out.println(key);
            }
        }
    
    }

    Query the index mapping field

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = ElasticSearchApplication.class)
    public class IndexJunit {
    
    
        @Autowired
        private RestHighLevelClient client;
    
        /**
         * 查询索引映射字段
         * @throws IOException
         */
        @Test
        public void getMapping() throws IOException {
            GetMappingsRequest request = new GetMappingsRequest();
            request.indices("cs_index");
            request.types("_doc");
            GetMappingsResponse response = client.indices().getMapping(request, RequestOptions.DEFAULT);
            System.out.println(response.toString());
        }
    
    
    }

    Add index mapping field

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = ElasticSearchApplication.class)
    public class IndexJunit {
    
    
        @Autowired
        private RestHighLevelClient client;
    
        /**
         * 添加索引映射字段
         * @throws IOException
         */
        @Test
        public void addMapping() throws IOException {
            PutMappingRequest request = new PutMappingRequest();
            request.indices("cs_index");
            request.type("_doc");
    
            //添加字段
            Map properties = new HashMap();
            properties.put("accountName", ImmutableBiMap.of("type", "keyword"));
            Map mapping = new HashMap<>();
            mapping.put("properties", properties);
            request.source(mapping);
            PutMappingResponse response = client.indices().putMapping(request, RequestOptions.DEFAULT);
            System.out.println(response.isAcknowledged());
        }
    
    
    }

    2.5. Document management

    The so-called document is to add data to the index to facilitate data query. For detailed operation content, please See below!

    Add document

    ublic class UserDocument {
    
        private String id;
        private String name;
        private String sex;
        private Integer age;
        private String city;
        private Date createTime;
    
        //省略get、set...
    }
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = ElasticSearchApplication.class)
    public class DocJunit {
    
        @Autowired
        private RestHighLevelClient client;
    
    
        /**
         * 添加文档
         * @throws IOException
         */
        @Test
        public void addDocument() throws IOException {
            // 创建对象
            UserDocument user = new UserDocument();
            user.setId("1");
            user.setName("里斯");
            user.setCity("武汉");
            user.setSex("男");
            user.setAge(20);
            user.setCreateTime(new Date());
    
            // 创建索引,即获取索引
            IndexRequest request = new IndexRequest();
            // 外层参数
            request.id("1");
            request.index("cs_index");
            request.type("_doc");
            request.timeout(TimeValue.timeValueSeconds(1));
            // 存入对象
            request.source(JSON.toJSONString(user), XContentType.JSON);
            // 发送请求
            System.out.println(request.toString());
            IndexResponse response = client.index(request, RequestOptions.DEFAULT);
            System.out.println(response.toString());
        }
    
    }

    Update document

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = ElasticSearchApplication.class)
    public class DocJunit {
    
        @Autowired
        private RestHighLevelClient client;
    
    
        /**
         * 更新文档(按需修改)
         * @throws IOException
         */
        @Test
        public void updateDocument() throws IOException {
            // 创建对象
            UserDocument user = new UserDocument();
            user.setId("2");
            user.setName("程咬金");
            user.setCreateTime(new Date());
            // 创建索引,即获取索引
            UpdateRequest request = new UpdateRequest();
            // 外层参数
            request.id("2");
            request.index("cs_index");
            request.type("_doc");
            request.timeout(TimeValue.timeValueSeconds(1));
            // 存入对象
            request.doc(JSON.toJSONString(user), XContentType.JSON);
            // 发送请求
            System.out.println(request.toString());
            UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
            System.out.println(response.toString());
        }
    
    
    }

    Delete document

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = ElasticSearchApplication.class)
    public class DocJunit {
    
        @Autowired
        private RestHighLevelClient client;
    
    
        /**
         * 删除文档
         * @throws IOException
         */
        @Test
        public void deleteDocument() throws IOException {
            // 创建索引,即获取索引
            DeleteRequest request = new DeleteRequest();
            // 外层参数
            request.id("1");
            request.index("cs_index");
            request.type("_doc");
            request.timeout(TimeValue.timeValueSeconds(1));
            // 发送请求
            System.out.println(request.toString());
            DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
            System.out.println(response.toString());
        }
    
    
    }

    Query whether the document exists

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = ElasticSearchApplication.class)
    public class DocJunit {
    
        @Autowired
        private RestHighLevelClient client;
    
    
        /**
         * 查询文档是不是存在
         * @throws IOException
         */
        @Test
        public void exists() throws IOException {
            // 创建索引,即获取索引
            GetRequest request = new GetRequest();
            // 外层参数
            request.id("3");
            request.index("cs_index");
            request.type("_doc");
            // 发送请求
            System.out.println(request.toString());
            boolean response = client.exists(request, RequestOptions.DEFAULT);
            System.out.println(response);
        }
    }

    Query the specified document by ID

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = ElasticSearchApplication.class)
    public class DocJunit {
    
        @Autowired
        private RestHighLevelClient client;
    
    
        /**
         * 通过ID,查询指定文档
         * @throws IOException
         */
        @Test
        public void getById() throws IOException {
            // 创建索引,即获取索引
            GetRequest request = new GetRequest();
            // 外层参数
            request.id("1");
            request.index("cs_index");
            request.type("_doc");
            // 发送请求
            System.out.println(request.toString());
            GetResponse response = client.get(request, RequestOptions.DEFAULT);
            System.out.println(response.toString());
        }
    }

    Add documents in batches

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = ElasticSearchApplication.class)
    public class DocJunit {
    
        @Autowired
        private RestHighLevelClient client;
    
    
        /**
         * 批量添加文档
         * @throws IOException
         */
        @Test
        public void batchAddDocument() throws IOException {
            // 批量请求
            BulkRequest bulkRequest = new BulkRequest();
            bulkRequest.timeout(TimeValue.timeValueSeconds(10));
            // 创建对象
            List userArrayList = new ArrayList<>();
            userArrayList.add(new UserDocument("张三", "男", 30, "武汉"));
            userArrayList.add(new UserDocument("里斯", "女", 31, "北京"));
            userArrayList.add(new UserDocument("王五", "男", 32, "武汉"));
            userArrayList.add(new UserDocument("赵六", "女", 33, "长沙"));
            userArrayList.add(new UserDocument("七七", "男", 34, "武汉"));
            // 添加请求
            for (int i = 0; i < userArrayList.size(); i++) {
                userArrayList.get(i).setId(String.valueOf(i));
                IndexRequest indexRequest = new IndexRequest();
                // 外层参数
                indexRequest.id(String.valueOf(i));
                indexRequest.index("cs_index");
                indexRequest.type("_doc");
                indexRequest.timeout(TimeValue.timeValueSeconds(1));
                indexRequest.source(JSON.toJSONString(userArrayList.get(i)), XContentType.JSON);
                bulkRequest.add(indexRequest);
            }
            // 执行请求
            BulkResponse response = client.bulk(bulkRequest, RequestOptions.DEFAULT);
            System.out.println(response.status());
        }
    
    }

    The above is the detailed content of How SpringBoot+Elasticsearch implements data search. For more information, please follow other related articles on the PHP Chinese website!

    Statement:
    This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete