Heim >Java >javaLernprogramm >Wie SpringBoot+Elasticsearch die Datensuche implementiert

Wie SpringBoot+Elasticsearch die Datensuche implementiert

WBOY
WBOYnach vorne
2023-05-12 21:04:041224Durchsuche

    1. Einführung

    SpringBoot stellt eine Verbindung zu ElasticSearch her. Es gibt vier gängige Methoden:

    • Methode 1: Verbindung zum ES-Server über den Elastic Transport Client. Die zugrunde liegende Schicht basiert auf dem TCP-Protokoll Transportmodul und Remote-ES-Dienst End-to-End-Kommunikation, die Verwendung ab V7.0 wird jedoch offiziell nicht empfohlen und ab V8.0 offiziell entfernt.

    • Methode 2: Verbindung zum ES-Server über den Elastic Java Low Level Rest Client herstellen. Die zugrunde liegende Schicht kommuniziert mit dem Remote-ES-Server über die Restful-API, die auf dem HTTP-Protokoll basiert. Es wird nur die einfachste und grundlegendste API bereitgestellt. Ähnlich wie im vorherigen Artikel wurde Ihnen die API-Betriebslogik vorgestellt.

    • Methode 3: Stellen Sie eine Verbindung zum es-Server über den Elastic Java High Level Rest Client her. Die unterste Ebene ist basierend auf dem Elastic Java Low Level Rest Client gekapselt und bietet eine erweiterte API sowie die Elastic Transport Client-Schnittstelle und -Parameter. Bleiben Sie konsequent, der offiziell empfohlene es-Client.

    • Methode 4: Stellen Sie über den JestClient-Client eine Verbindung zum es-Server her. Dies ist ein von der Open-Source-Community entwickelter es-Client, der auf dem HTTP-Protokoll basiert. Der Beamte behauptet, dass die Schnittstelle und das Code-Design einfacher und vernünftiger sind Der offiziell von ES bereitgestellte Rest-Client ist einfacher zu verwenden und weist eine gewisse Kompatibilität mit ES-Serverversionen auf, die Aktualisierungsgeschwindigkeit ist jedoch nicht sehr hoch. Die aktuelle ES-Version wurde auf V7.9 veröffentlicht, JestClient unterstützt jedoch nur V1.0 bis V6 .X-Versionen von ES.

    Es gibt noch eine weitere Sache, auf die jeder achten muss, und das ist die Kompatibilität der Versionsnummern!

    Während des Entwicklungsprozesses muss jeder besonders auf die Versionsnummern des Clients und des Servers achten und diese so konsistent wie möglich halten. Beispielsweise lautet die Versionsnummer des Servers 6.8.2 und dann die Version Die Nummer des mit es verbundenen Clients sollte vorzugsweise gleich 6.8.2 sein. Auch wenn sie aus Projektgründen nicht konsistent sein kann, muss die Client-Versionsnummer zwischen 6.0.0 und 6.8.2 liegen und darf die Versionsnummer des Servers nicht überschreiten. Damit der Client den normalen Betrieb aufrechterhalten kann, treten sonst viele unerwartete Probleme auf. Wenn der Client die Version 7.0.4 hat, meldet das Programm zu diesem Zeitpunkt verschiedene Fehler und kann nicht einmal verwendet werden.

    Warum machen Sie das? Der Hauptgrund ist, dass die höhere Version des ES-Servers nicht mit der niedrigeren Version von ES6 kompatibel ist. Sie unterscheidet sich stark von einigen API-Anforderungsparameterstrukturen von ES7, daher sollten die Client- und Server-Versionsnummern so weit wie möglich konsistent gehalten werden.

    Kein Unsinn mehr, gehen wir direkt zum Code!

    2. Code-Praxis

    Die in diesem Artikel verwendete SpringBoot-Versionsnummer ist 2.1.0.RELEASE, die Versionsnummer des Servers ist 6.8.2 und die Client verwendet Die offiziell empfohlene Versionsnummer des Elastic Java High Level Rest Client ist 6.4.2, was bequem mit der SpringBoot-Version kompatibel ist.

    2.1. Abhängigkeiten importieren

    <!--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. Umgebungsvariablen konfigurieren

    In der globalen Konfigurationsdatei application.properties konfigurieren Sie benutzerdefinierte Elasticsearch-Umgebungsvariablen.

    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. Erstellen Sie die Konfigurationsklasse von 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;
        }
    }

    Zu diesem Zeitpunkt ist die Client-Konfiguration abgeschlossen und wird beim Starten des Projekts automatisch in den IOC-Container von Spring eingefügt.

    2.4. Indexverwaltung

    es Das Wichtigste ist die Indexbibliothek. Wie wird sie auf der Clientseite erstellt?

    Index erstellen

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

    Index löschen

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

    Index abfragen

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

    Abfragen, ob Index vorhanden ist

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

    Alle Indexnamen abfragen

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

    Abfrageindex-Zuordnungsfeld

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

    Indexzuordnungsfeld hinzufügen

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

    2.5. Das sogenannte Dokument dient zum Hinzufügen von Daten zum Index, um die Datenabfrage zu erleichtern. Weitere Informationen finden Sie unten.

    Dokument hinzufügen

    rrree

    Fügen Sie Dokumente stapelweise hinzu

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

    Das obige ist der detaillierte Inhalt vonWie SpringBoot+Elasticsearch die Datensuche implementiert. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Stellungnahme:
    Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen