Maison  >  Article  >  Java  >  Comment SpringBoot+Elasticsearch implémente la recherche de données

Comment SpringBoot+Elasticsearch implémente la recherche de données

WBOY
WBOYavant
2023-05-12 21:04:041150parcourir

    1. Introduction

    SpringBoot se connecte à ElasticSearch Il existe quatre méthodes principales :

    • Méthode 1 : Connectez-vous au serveur es via Elastic Transport Client. module de transport et service ES distant Communication de bout en bout, cependant, son utilisation n'est officiellement pas recommandée à partir de la V7.0 et sera officiellement supprimée à partir de la V8.0.

    • Méthode 2 : Connectez-vous au serveur ES via le client Elastic Java Low Level Rest. La couche sous-jacente communique avec le serveur ES distant via l'API restful basée sur le protocole HTTP. Seule l'API la plus simple et la plus basique est fournie. similaire à l'article précédent. La logique de fonctionnement de l'API vous a été présentée.

    • Méthode 3 : Connectez-vous au serveur es via le client Elastic Java High Level Rest Client. La couche inférieure est encapsulée sur la base du client Elastic Java Low Level Rest, fournissant une API plus avancée ainsi que l'interface et les paramètres du client Elastic Transport. Restez cohérent, le client es officiellement recommandé.

    • Méthode 4 : Connectez-vous au serveur es via le client JestClient. Il s'agit d'un client es développé par la communauté open source basé sur le protocole HTTP. Le responsable affirme que l'interface et la conception du code sont plus simples et plus raisonnables que le. Client de repos officiellement fourni par ES Il est plus facile à utiliser et a une certaine compatibilité avec la version du serveur ES, mais la vitesse de mise à jour n'est pas très rapide. La version actuelle d'ES a été publiée vers la version V7.9, mais JestClient ne prend en charge que la version V1.0 ~ V6. Versions .X d'ES.

    Il y a une autre chose à laquelle tout le monde doit prêter attention, c'est la compatibilité des numéros de version !

    Pendant le processus de développement, chacun doit porter une attention particulière aux numéros de version du client et du serveur, et les garder aussi cohérents que possible. Par exemple, le numéro de version du serveur es est 6.8.2, puis la version. le numéro du client connecté à es doit de préférence être le même 6.8.2, même s'il ne peut pas être cohérent pour des raisons de projet, le numéro de version du client doit être compris entre 6.0.0 et 6.8.2, sans dépasser le numéro de version du serveur, afin que le client puisse maintenir un fonctionnement normal, sinon de nombreux problèmes inattendus se produiront, si le client est en version 7.0.4, le programme signalera diverses erreurs à ce moment-là, et ne pourra même pas être utilisé

    Pourquoi faites-vous cela ? La raison principale est que la version supérieure du serveur es n'est pas compatible avec la version inférieure ; es6 est très différent de certaines structures de paramètres de requête API d'es7, de sorte que les numéros de version du client et du serveur doivent rester cohérents autant que possible.

    Fin de bêtises, passons directement au code !

    2. Code pratique

    Le numéro de version de SpringBoot utilisé dans cet article est 2.1.0.RELEASE, le numéro de version du serveur es est 6.8.2, et le utilisations du client Le numéro de version officiellement recommandé d'Elastic Java High Level Rest Client est 6.4.2, ce qui est idéalement compatible avec la version SpringBoot.

    2.1. Importer les dépendances

    <!--elasticsearch-->
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>6.4.2</version>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-client</artifactId>
        <version>6.4.2</version>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
        <version>6.4.2</version>
    </dependency>

    2.2. Configurer les variables d'environnement

    Dans le fichier de configuration globale application.properties, configurez les variables d'environnement personnalisées elasticsearch.

    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. Créez la classe de configuration d'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;
        }
    }

    À ce stade, la configuration du client est terminée et lorsque le projet démarrera, il sera automatiquement injecté dans le conteneur ioc de Spring.

    2.4. Gestion des index

    es Le plus important est la bibliothèque d'index. Comment la créer côté client ? "Créer un index"

    Champ de mappage d'index de requête

    @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<String, Object> 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<String, Object> 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());
        }
    
    }

    Ajouter un champ de mappage d'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());
        }
    
    
    }

    2.5. Gestion des documents

    Le soi-disant document consiste à ajouter des données à l'index pour faciliter l'interrogation des données. Pour le contenu détaillé de l'opération, veuillez voir ci-dessous !

    Ajouter un document

    @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());
        }
    
    }
    @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);
        }
    
    }

    Mettre à jour le document

    @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<String, Set<AliasMetaData>> map = response.getAliases();
            Set<String> indices = map.keySet();
            for (String key : indices) {
                System.out.println(key);
            }
        }
    
    }

    Supprimer le document

    @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());
        }
    
    
    }

    Demander si le document existe

    @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<String, Object> properties = new HashMap();
            properties.put("accountName", ImmutableBiMap.of("type", "keyword"));
            Map<String, Object> mapping = new HashMap<>();
            mapping.put("properties", properties);
            request.source(mapping);
            PutMappingResponse response = client.indices().putMapping(request, RequestOptions.DEFAULT);
            System.out.println(response.isAcknowledged());
        }
    
    
    }

    Interroger le document spécifié par ID

    ublic class UserDocument {
    
        private String id;
        private String name;
        private String sex;
        private Integer age;
        private String city;
        private Date createTime;
    
        //省略get、set...
    }

    Ajouter des documents par lots

    @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());
        }
    
    }

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration:
    Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer