本文共 12869 字,大约阅读时间需要 42 分钟。
In this post, we will setup up a sample Spring boot Elasticsearch application. We will use latest version of Elasticsearch i.e. 6.1.x. To interact with the Elasticsearch search engine, we will use Elasticsearch Rest client. We are not using Spring Data ElasticSearch because that doesn’t support latest ElasticSearch version i.e 6.x.
在本文中,我们将设置一个示例Spring boot Elasticsearch应用程序。 我们将使用最新版本的Elasticsearch,即6.1.x。 为了与Elasticsearch搜索引擎进行交互,我们将使用Elasticsearch Rest客户端 。 我们不使用Spring Data ElasticSearch,因为它不支持最新的ElasticSearch版本,即6.x。
We will use Maven build system for this project and here are the dependencies we used:
我们将为此项目使用Maven构建系统,这是我们使用的依赖项:
org.springframework.boot spring-boot-starter-parent 1.5.9.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.elasticsearch elasticsearch 6.1.2 org.elasticsearch.client elasticsearch-rest-high-level-client 6.1.2 org.apache.logging.log4j log4j-api 2.8.2 org.apache.logging.log4j log4j-core 2.8.2 org.elasticsearch.client elasticsearch-rest-client 6.1.2 org.elasticsearch.client elasticsearch-rest-client-sniffer 6.1.2 org.springframework.boot spring-boot-maven-plugin
Make sure to use stable version for from the maven central.
确保从Maven Central使用稳定版本的 。
Now, we will have to configure ElasticSearch in our application. Let’s d this in two parts. First, we will provide Elasticsearch address in our application.properties
file:
现在,我们将不得不在应用程序中配置ElasticSearch。 让我们分为两部分。 首先,我们将在application.properties
文件中提供Elasticsearch地址:
spring.data.elasticsearch.cluster-name=elasticsearchspring.data.elasticsearch.cluster-nodes=elasticsearch
We only provided the Elasticsearch cluster name and node name here and these are actually the default values. Now, it’s time to put these values to use in our Java config class.
我们仅在此处提供了Elasticsearch集群名称和节点名称,而这些实际上是默认值。 现在,是时候在Java配置类中使用这些值了。
package com.journaldev.elasticsearch.config;import org.apache.http.HttpHost;import org.elasticsearch.client.RestClient;import org.elasticsearch.client.RestHighLevelClient;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Value;import org.springframework.beans.factory.config.AbstractFactoryBean;import org.springframework.context.annotation.Configuration;@Configurationpublic class ElasticSearchConfiguration extends AbstractFactoryBean { private static final Logger LOG = LoggerFactory.getLogger(ElasticSearchConfiguration.class); @Value("${spring.data.elasticsearch.cluster-nodes}") private String clusterNodes; @Value("${spring.data.elasticsearch.cluster-name}") private String clusterName; private RestHighLevelClient restHighLevelClient; @Override public void destroy() { try { if (restHighLevelClient != null) { restHighLevelClient.close(); } } catch (final Exception e) { LOG.error("Error closing ElasticSearch client: ", e); } } @Override public ClassgetObjectType() { return RestHighLevelClient.class; } @Override public boolean isSingleton() { return false; } @Override public RestHighLevelClient createInstance() { return buildClient(); } private RestHighLevelClient buildClient() { try { restHighLevelClient = new RestHighLevelClient( RestClient.builder( new HttpHost("localhost", 9200, "http"), new HttpHost("localhost", 9201, "http"))); } catch (Exception e) { LOG.error(e.getMessage()); } return restHighLevelClient; }}
With this configuration, we ensured that ElasticSearch is able to make a successful connection to its server using the Rest Client API.
通过这种配置,我们确保了ElasticSearch能够使用Rest Client API与其服务器成功建立连接。
Let’s start putting the working components of the app now.
现在让我们开始放置应用程序的工作组件。
We will be just using a simple model as a User:
我们将以简单的模型作为用户:
package com.journaldev.elasticsearch.model;import com.fasterxml.jackson.annotation.JsonInclude;@JsonInclude(JsonInclude.Include.NON_EMPTY)public class Book { private String id; private String title; private String author; private float price; //standard setters and getters}
We will be making following functionalities and Database interactions in our app:
我们将在我们的应用程序中进行以下功能和数据库交互:
Let us move to making our Controller:
让我们开始制作我们的控制器:
package com.journaldev.elasticsearch.controller;import com.journaldev.elasticsearch.model.Book;import com.journaldev.elasticsearch.dao.BookDao;import org.springframework.web.bind.annotation.*;import java.util.Map;@RestController@RequestMapping("/books")public class BookController { private BookDao bookDao; public BookController(BookDao bookDao) { this.bookDao = bookDao; } ...}
We just Autowired the DAO dependency and we will use this next.
我们只是自动装配了DAO依赖项,接下来将使用它。
For the functionalities we mentioned, we will now be making APIs and accessing the DAO dependency which will internally use Elasticsearch Rest Client API.
对于我们提到的功能,我们现在将制作API并访问内部将使用Elasticsearch Rest Client API的DAO依赖项。
Let us get a book with ID:
让我们得到一本ID为的书:
@GetMapping("/{id}")public MapgetBookById(@PathVariable String id){ return bookDao.getBookById(id);}
Now, let us insert a book now:
现在,让我们现在插入一本书:
@PostMappingpublic Book insertBook(@RequestBody Book book) throws Exception { return bookDao.insertBook(book);}
We will be updating a book in this snippet:
我们将在以下片段中更新一本书:
@PutMapping("/{id}")public MapupdateBookById(@RequestBody Book book, @PathVariable String id) { return bookDao.updateBookById(id, book);}
Now that we have added sample data into the DB, let’s try to extract some part of it:
现在,我们已经将示例数据添加到数据库中,让我们尝试提取其中的一部分:
@DeleteMapping("/{id}")public void deleteBookById(@PathVariable String id) { bookDao.deleteBookById(id);}
This is the ease Spring Data API offers us but it also has some downsides. We will elaborate this when we Have defined the ElasticsearchTemplate version as well. Let’s get started with that too.
这是Spring Data API为我们提供的便利,但也有一些缺点。 当我们还定义了ElasticsearchTemplate版本时,我们将详细说明。 让我们也开始吧。
Now, we will actually define the DAL queries which achieves these objectives.
现在,我们将实际定义实现这些目标的DAL查询。
We will start by mentioning the dependencies we need:
我们将从提及我们需要的依赖关系开始:
package com.journaldev.elasticsearch.dao;import com.journaldev.elasticsearch.model.Book;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.ObjectMapper;import org.elasticsearch.ElasticsearchException;import org.elasticsearch.action.delete.DeleteRequest;import org.elasticsearch.action.delete.DeleteResponse;import org.elasticsearch.action.get.GetRequest;import org.elasticsearch.action.get.GetResponse;import org.elasticsearch.action.index.IndexRequest;import org.elasticsearch.action.index.IndexResponse;import org.elasticsearch.action.update.UpdateRequest;import org.elasticsearch.action.update.UpdateResponse;import org.elasticsearch.client.RestHighLevelClient;import org.elasticsearch.common.xcontent.XContentType;import org.springframework.stereotype.Repository;import java.util.HashMap;import java.util.Map;import java.util.UUID;@Repositorypublic class BookDao { private final String INDEX = "bookdata"; private final String TYPE = "books"; private RestHighLevelClient restHighLevelClient; private ObjectMapper objectMapper; public BookDao( ObjectMapper objectMapper, RestHighLevelClient restHighLevelClient) { this.objectMapper = objectMapper; this.restHighLevelClient = restHighLevelClient; } ...}
We will start by inserting a Book into the ES:
我们将从在ES中插入一本书开始:
public Book insertBook(Book book){ book.setId(UUID.randomUUID().toString()); Map dataMap = objectMapper.convertValue(book, Map.class); IndexRequest indexRequest = new IndexRequest(INDEX, TYPE, book.getId()) .source(dataMap); try { IndexResponse response = restHighLevelClient.index(indexRequest); } catch(ElasticsearchException e) { e.getDetailedMessage(); } catch (java.io.IOException ex){ ex.getLocalizedMessage(); } return book;}
Clearly, we need to convert the model data to a Map data structure before we insert it into the ES database.
显然,在将模型数据插入ES数据库之前,我们需要将其转换为Map数据结构。
We will now search a book with an ID:
现在,我们将搜索ID为:的图书:
public MapgetBookById(String id){ GetRequest getRequest = new GetRequest(INDEX, TYPE, id); GetResponse getResponse = null; try { getResponse = restHighLevelClient.get(getRequest); } catch (java.io.IOException e){ e.getLocalizedMessage(); } Map sourceAsMap = getResponse.getSourceAsMap(); return sourceAsMap;}
Here, this is to be noted that data is searched and got back as a Map data structure as well. This is something we need to handle, converting data to Map and forth to make DB transactions.
在此,要注意的是,数据也作为地图数据结构被搜索并返回。 这是我们需要处理的事情,将数据转换为Map来进行数据库事务。
public MapupdateBookById(String id, Book book){ UpdateRequest updateRequest = new UpdateRequest(INDEX, TYPE, id) .fetchSource(true); // Fetch Object after its update Map error = new HashMap<>(); error.put("Error", "Unable to update book"); try { String bookJson = objectMapper.writeValueAsString(book); updateRequest.doc(bookJson, XContentType.JSON); UpdateResponse updateResponse = restHighLevelClient.update(updateRequest); Map sourceAsMap = updateResponse.getGetResult().sourceAsMap(); return sourceAsMap; }catch (JsonProcessingException e){ e.getMessage(); } catch (java.io.IOException e){ e.getLocalizedMessage(); } return error;}
We will now search a book with an ID:
现在,我们将搜索ID为:的图书:
public void deleteBookById(String id) { DeleteRequest deleteRequest = new DeleteRequest(INDEX, TYPE, id); try { DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest); } catch (java.io.IOException e){ e.getLocalizedMessage(); }}
I think deleting an object was having the easiest query. Let’s try this application now by running it.
我认为删除对象的查询最简单。 现在通过运行它来尝试该应用程序。
We can run this app simply by using a single command:
我们只需使用一个命令即可运行此应用程序:
mvn spring-boot:run
Once the app is running, we can try saving a new book by using this API. Before doing that, just confirm that the ES is running by using this API:
应用程序运行后,我们可以尝试使用此API保存新书。 在此之前,只需使用以下API确认ES正在运行:
127.0.0.1:9200
We will get this response:
我们将收到以下答复:
现在,使用以下API插入数据:127.0.0.1:8080/books
We use a POST request with this JSON:
我们使用带有JSON的POST请求:
{ "title" : "Java Always", "author" : "JournalDev", "price" : 99.1}
We have the following response:
我们有以下回应:
让我们尝试另一个请求以获取具有上述ID的书。 我们将在此API上使用GET请求:127.0.0.1:8080/books/55c200ff-9674-44aa-8779-a0f3ff925e74
This is what we get back:
这就是我们得到的:
继续尝试我们定义的更多API。In this lesson, we looked at how Elasticsearch can be queried using a Rest Client API it provides. Download the source code here and modify it.
在本课程中,我们研究了如何使用它提供的Rest Client API查询Elasticsearch。 在此处下载源代码并进行修改。
翻译自:
转载地址:http://fymzd.baihongyu.com/