使用Spring Boot和Elasticsearch教程

栏目: Java · 发布时间: 5年前

内容简介:Elasticsearch  是一种实时分布式和开源的全文搜索和分析引擎。它是基于文档的搜索平台,具有快速搜索功能。它针对大海捞针式的搜索进行了优化,重点不在于一致性或原子性。在本博客中,我将介绍如何下载Elasticsearch并进行设置。此外,如何使用  Spring Boot  和  Spring Data ElasticSearch  项目与Elasticsearch 引擎集成  。首先,安装和设置elasticsearch引擎。

Elasticsearch  是一种实时分布式和开源的全文搜索和分析引擎。它是基于文档的搜索平台,具有快速搜索功能。它针对大海捞针式的搜索进行了优化,重点不在于一致性或原子性。

在本博客中,我将介绍如何下载Elasticsearch并进行设置。此外,如何使用  Spring Boot  和  Spring Data ElasticSearch  项目与Elasticsearch 引擎集成  。

首先,安装和设置elasticsearch引擎。

现在,我们将开发一个Spring Boot应用程序,它将展示  ElasticsearchTemplate 和  ElasticsearchRepository 访问Elasticsearch引擎的方式并进行CRUD操作。在开发应用程序之前,让我们首先了解  ElasticsearchTemplate 和  ElasticsearchRepository的 工作原理。

ElasticsearchTemplate - 它是一个实现ElasticsearchOperations的Template类  。 它比ElasticsearchRepository更强大,因为它可以做的不仅仅是CRUD操作。它具有创建,删除索引,批量上传的操作。它也可以进行聚合搜索。

ElasticsearchRepository  - 如果我们定义一个扩展ElasticsearchRepository的接口  , 它由Spring数据Elasticsearch提供,它将自动为该Document提供CRUD操作。例如,通过扩展ElasticsearchRepository,UserRepository接口在下面定义了“ User ”文档。现在可以在用户文档上完成所有查找,保存,删除,更新默认操作。

@Repository
<b>public</b> <b>interface</b> UserRepository <b>extends</b> ElasticsearchRepository<User, String> {
}

它扩展了ElasticsearchCrudRepository,最终扩展了Repository接口。此存储库接口是Spring数据的标准功能。无需提供此接口的实现。您也可以使用@Query 注释编写自定义查询。

Maven配置:

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</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-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

配置application.properties  ,ElasticsearchTemplate 和  ElasticsearchRepository用这个配置来连接引擎。我使用了诸如集群节点之类的传输客户端属性和索引名称来连接elasticsearch引擎。

#application.properties

# Local Elasticsearch config
spring.data.elasticsearch.repositories.enabled=<b>true</b>
spring.data.elasticsearch.cluster-nodes=localhost:9300
spring.data.elasticsearch.cluster-name=elasticsearch

elasticsearch.index.name=my_index
elasticsearch.user.type=user

# App config
server.port=8102
spring.application.name=BootElastic

Mappings

在Elasticsearch中,  Index 就像RDBMS中的DB,  Mappings / Type  类似于RDBMS中的表。 Document 是属于某种类型并位于索引中的字段的集合。Spring数据提供了像@ Document 这样的注释来创建文档。在这里,我们将User定义为索引为“ my_index ”并键入“ user ” 的文档。

@Document(indexName = <font>"my_index"</font><font>, type = </font><font>"user"</font><font>)
<b>public</b> <b>class</b> User {

    @Id
    <b>private</b> String userId;
    <b>private</b> String name;
    <b>private</b> Date creationDate = <b>new</b> Date();
    <b>private</b> Map<String, String> userSettings = <b>new</b> HashMap<>();

 </font><font><i>//getter and setters </i></font><font>
}
</font>

控制器

第一个控制器是  UserController。它将使用  UserDAOImpl 让  ElasticserachTemplate 与Elasticsearch  Engine 交互  。

@RestController
<b>public</b> <b>class</b> UserController {

    @Autowired
    <b>private</b> UserDAO userDAO;

    @RequestMapping(<font>"/all"</font><font>)
    <b>public</b> List<User> getAllUsers() {
        <b>return</b> userDAO.getAllUsers();
    }
     @RequestMapping(value = </font><font>"/new"</font><font>, method = RequestMethod.POST)
    <b>public</b> User addUsers(@RequestBody User user) {
        userDAO.addNewUser(user);
        <b>return</b> user;
    }
  --- Other methods
}
</font>

UserDAOImpl - 此类初始化elasticsearchtemplate并使用queryForList方法检索数据。

@Repository
<b>public</b> <b>class</b> UserDAOImpl implements UserDAO {

    <b>private</b> <b>final</b> Logger LOG = LoggerFactory.getLogger(getClass());

    @Value(<font>"${elasticsearch.index.name}"</font><font>)
    <b>private</b> String indexName;

    @Value(</font><font>"${elasticsearch.user.type}"</font><font>)
    <b>private</b> String userTypeName;

    @Autowired
    <b>private</b> ElasticsearchTemplate esTemplate;

    @Override
    <b>public</b> List<User> getAllUsers() {
        SearchQuery getAllQuery = <b>new</b> NativeSearchQueryBuilder()
                .withQuery(matchAllQuery()).build();
        <b>return</b> esTemplate.queryForList(getAllQuery, User.<b>class</b>);
    }
  </font><font><i>// Other methods</i></font><font>
}
</font>

另一个Controller是UserRepositoryConroller。这是使用UserRepository与elasticsearch引擎进行交互。

@RestController
@RequestMapping(<font>"/repo"</font><font>)
<b>public</b> <b>class</b> UserRepositoryController {

    @Autowired
    <b>private</b> UserRepository userRepository;

    @RequestMapping(</font><font>"/all"</font><font>)
    <b>public</b> List<User> getAllUsers() {
        List<User> users = <b>new</b> ArrayList<>();
        userRepository.findAll().forEach(users::add);
        <b>return</b> users;
    }
  </font><font><i>//Other methods</i></font><font>
}
</font>

此Repository类扩展了ElasticsearchRepository类,该类在内部扩展了  ElasticsearchCrudRepository - >   PagingAndSortingRepository

@Repository
<b>public</b> <b>interface</b> UserRepository <b>extends</b> ElasticsearchRepository<User, String> {
}

你可以在github链接找到完整的代码 - https://github.com/RajeshBhojwani/spring-boot-elasticsearch.git

构建应用程序

可以使用Maven命令构建应用程序。

mvn clean install

将构建代码并创建  elasticsearch-0.0.1-SNAPSHOT.jar   文件。

运行该应用程序

java -jar  target/elasticsearch-0.0.1-SNAPSHOT.jar

将启动该应用程序。应用程序将侦听application.properties  文件中定义的  端口  8102 。

测试应用程序 -

测试  使用ElasticsearchTemplate的UserController 流程。

第1步  - 添加新用户。使用此REST API URL添加新用户  http://localhost:8102/new

在Request正文中添加Json数据。

{
  <font>"name"</font><font>: </font><font>"Sumit"</font><font>,
   </font><font>"userSettings"</font><font>: {
   </font><font>"gender"</font><font> : </font><font>"male"</font><font>,
   </font><font>"occupation"</font><font> : </font><font>"CA"</font><font>,
   </font><font>"hobby"</font><font> : </font><font>"chess"</font><font>
   }
}
</font>

第2步  - 检查响应。您将看到使用userId生成的新用户,该文档是此文档的唯一ID。输出如下:

{
    <font>"userId"</font><font>: </font><font>"AWdj-3KcTJbZRlQtLZfO"</font><font>,
    </font><font>"name"</font><font>: </font><font>"Sumit"</font><font>,
    </font><font>"creationDate"</font><font>: 1543570682521,
    </font><font>"userSettings"</font><font>: {
        </font><font>"gender"</font><font>: </font><font>"male"</font><font>,
        </font><font>"occupation"</font><font>: </font><font>"CA"</font><font>,
        </font><font>"hobby"</font><font>: </font><font>"chess"</font><font>
    }
}
</font>

第3步  - 检索所有用户。使用   http://localhost:8102/all

{
        <font>"userId"</font><font>: </font><font>"AWdj-3KcTJbZRlQtLZfO"</font><font>,
        </font><font>"name"</font><font>: </font><font>"Sumit"</font><font>,
        </font><font>"creationDate"</font><font>: 1543570682521,
        </font><font>"userSettings"</font><font>: {
            </font><font>"gender"</font><font>: </font><font>"male"</font><font>,
            </font><font>"occupation"</font><font>: </font><font>"CA"</font><font>,
            </font><font>"hobby"</font><font>: </font><font>"chess"</font><font>
        }
    },
    {
        </font><font>"userId"</font><font>: </font><font>"AWdZuKFRgzULDLBu_Y0c"</font><font>,
        </font><font>"name"</font><font>: </font><font>"Suresh"</font><font>,
        </font><font>"creationDate"</font><font>: 1543398531296,
        </font><font>"userSettings"</font><font>: {}
    }
</font>

测试  使用ElasticsearchRepository的UserRepositoryController 流。

第1步  - 添加新用户。使用此REST API URL添加新用户  http://localhost:8102/repo/new

像我们在之前的测试用例中那样在Request体中添加Json数据。

第2步  - 检查响应。您将看到使用userId生成的新用户,该文档是此文档的唯一ID。

Transport 客户端库

如何使用传输客户端库与最新版本的Elasticsearch引擎进行交互?我们可以直接从代码中调用Elasticsearch的REST API进行CRUD,也可以使用Elasticsearch提供的传输Transport客户端。

Maven依赖:需要Elasticsearch,一个传输客户端和log4j jar。

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>2.7</version>
</dependency>
</dependencies>

 配置:

由于我们将使用传输客户端连接到Elasticsearch引擎,因此我们需要为引擎的群集节点提供URL路径。所以我已将属性放在application.properties文件中,用于URL 的主机和端口。

# Local Elasticsearch config
elasticsearch.host=localhost
elasticsearch.port=9300
# App config
server.port=8102
spring.application.name=BootElastic

创建一个名为的域类User。JSON输入将映射到此  User 对象。这将用于创建与索引和类型关联的用户文档。

<b>public</b> <b>class</b> User {
    <b>private</b> String userId;
    <b>private</b> String name;
    <b>private</b> Date creationDate = <b>new</b> Date();
    <b>private</b> Map<String, String> userSettings = <b>new</b> HashMap<>();
  -- getter/setter methods
}

创建 Java 配置文件以创建连接到Elasticsearch集群节点的传输客户端。它还从application.properties文件配置的环境加载主机和端口的值  。

@Configuration
<b>public</b> <b>class</b> config{
    @Value(<font>"${elasticsearch.host:localhost}"</font><font>) 
    <b>public</b> String host;
    @Value(</font><font>"${elasticsearch.port:9300}"</font><font>) 
    <b>public</b> <b>int</b> port;
    <b>public</b> String getHost() {
<b>return</b> host;
}
<b>public</b> <b>int</b> getPort() {
<b>return</b> port;
    }
    @Bean
    <b>public</b> Client client(){
        TransportClient client = <b>null</b>;
        <b>try</b>{
            System.out.println(</font><font>"host:"</font><font>+ host+</font><font>"port:"</font><font>+port);
            client = <b>new</b> PreBuiltTransportClient(Settings.EMPTY)
            .addTransportAddress(<b>new</b> InetSocketTransportAddress(InetAddress.getByName(host), port));
        } <b>catch</b> (UnknownHostException e) {
            e.printStackTrace();
        }
        <b>return</b> client;
    }
}
</font>

UserController 创建以展示以下功能:

  1. 创建一个名为“ users ” 的索引并键入“ employee ”。它将创建一个用于存储用户信息的文档。文档的id可以作为JSON输入传递,如果没有传递,Elasticsearch将生成自己的id。客户端有一个称为方法  prepareIndex() 构建文档对象和存储针对索引和类型。这方法是一种  POST 方法调用,其中  User 信息将作为JSON传递。
@Autowired
    Client client;
    @PostMapping(<font>"/create"</font><font>)
    <b>public</b> String create(@RequestBody User user) throws IOException {
        IndexResponse response = client.prepareIndex(</font><font>"users"</font><font>, </font><font>"employee"</font><font>, user.getUserId())
                .setSource(jsonBuilder()
                        .startObject()
                        .field(</font><font>"name"</font><font>, user.getName())
                        .field(</font><font>"userSettings"</font><font>, user.getUserSettings())
                        .endObject()
                )
                .get();
               System.out.println(</font><font>"response id:"</font><font>+response.getId());
        <b>return</b> response.getResult().toString();
    }
</font>

2.根据传递的“id”查看用户信息。客户端有一种  prepareGet() 方法可以根据索引,类型和id检索信息。它将以JSON格式返回用户信息。

@GetMapping(<font>"/view/{id}"</font><font>)
    <b>public</b> Map<String, Object> view(@PathVariable <b>final</b> String id) {
        GetResponse getResponse = client.prepareGet(</font><font>"users"</font><font>, </font><font>"employee"</font><font>, id).get();
        <b>return</b> getResponse.getSource();
    }
</font>

3.根据字段名称查看用户信息。我用  matchQuery() 这里搜索“ 名称 ”字段并返回  User 信息。但是,班级有许多不同类型的可用   。例如,用于  搜索特定范围内的字段值,例如10到20年之间的年龄。有一种    方法可以使用通配符搜索字段:

@GetMapping(<font>"/view/name/{field}"</font><font>)
    <b>public</b> Map<String, Object> searchByName(@PathVariable <b>final</b> String field) {
        Map<String,Object> map = <b>null</b>;
        SearchResponse response = client.prepareSearch(</font><font>"users"</font><font>)
                                .setTypes(</font><font>"employee"</font><font>)
                                .setSearchType(SearchType.QUERY_AND_FETCH)
                                .setQuery(QueryBuilders..matchQuery(</font><font>"name"</font><font>, field))
                                .get()
                                ;
        List<SearchHit> searchHits = Arrays.asList(response.getHits().getHits());
        map =   searchHits.get(0).getSource();
        <b>return</b> map;
    }
</font>

4.通过使用Id搜索文档来更新文档并替换字段值。客户端有一个名为的方法   update()。它接受  UpdateRequest 更新查询的输入。

@GetMapping(<font>"/update/{id}"</font><font>)
    <b>public</b> String update(@PathVariable <b>final</b> String id) throws IOException {
        UpdateRequest updateRequest = <b>new</b> UpdateRequest();
        updateRequest.index(</font><font>"users"</font><font>)
                .type(</font><font>"employee"</font><font>)
                .id(id)
                .doc(jsonBuilder()
                        .startObject()
                        .field(</font><font>"name"</font><font>, </font><font>"Rajesh"</font><font>)
                        .endObject());
        <b>try</b> {
            UpdateResponse updateResponse = client.update(updateRequest).get();
            System.out.println(updateResponse.status());
            <b>return</b> updateResponse.status().toString();
        } <b>catch</b> (InterruptedException | ExecutionException e) {
            System.out.println(e);
        }
        <b>return</b> </font><font>"Exception"</font><font>;
    }
</font>

5.最后一种方法是展示如何删除索引和类型的文档。客户端确实有一个  prepareDelete() 接受索引,类型和id的方法来删除文档。

@GetMapping(<font>"/delete/{id}"</font><font>)
    <b>public</b> String delete(@PathVariable <b>final</b> String id) {
        DeleteResponse deleteResponse = client.prepareDelete(</font><font>"users"</font><font>, </font><font>"employee"</font><font>, id).get();
        <b>return</b> deleteResponse.getResult().toString();
    }
</font>

代码见: GitHub .

测试应用

该应用程序将在http://localhost:8102URL 上运行  。现在让我们测试一下我们上面讨论过的几个用例。

1.测试创建文档。

通过curl 或Postman  启动  。http://localhost:8102/rest/users/createPOST

输入:

{
<font>"userId"</font><font>:</font><font>"1"</font><font>,
</font><font>"name"</font><font>: </font><font>"Sumit"</font><font>,
</font><font>"userSettings"</font><font>: {
</font><font>"gender"</font><font> : </font><font>"male"</font><font>,
</font><font>"occupation"</font><font> : </font><font>"CA"</font><font>,
</font><font>"hobby"</font><font> : </font><font>"chess"</font><font>
}
}
</font>

您将看到显示“已创建”的响应。

2.要测试文档是否已创建,让我们测试视图功能。

启动。http://localhost:8102/rest/users/view/1GET

作为响应,您将看到id的用户信息,其值为“1”。

{
<font>"userSettings"</font><font>: {
</font><font>"occupation"</font><font>: </font><font>"CA"</font><font>,
</font><font>"gender"</font><font>: </font><font>"male"</font><font>,
</font><font>"hobby"</font><font>: </font><font>"chess"</font><font>
},
</font><font>"name"</font><font>: </font><font>"Rajesh"</font><font>
}
</font>

3.您可以通过名称字段查看用户信息以及启动  http://localhost:8102/rest/users/view/name/Rajesh。这是将“Rajesh”作为“名称”字段值传递。

同样,可以通过启动  和 来测试更新和删除功能  。http://localhost:8102/rest/users/update/1http://localhost:8102/rest/users/delete/1


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

编译器设计

编译器设计

Keith Cooper、Linda Torczon / 郭旭 / 人民邮电出版社 / 2012-12 / 99.00元

深入剖析现代编译器运用的算法和技术 强调代码优化和代码生成 体现编译原理教学的最新理念 本书旨在介绍编译器构造法中的艺术和科学。书中深入分析现代编译器后端所用的算法和技术,重点讨论代码优化和代码生成,详细介绍了用几个编程语言编写的示例等。 Keith D. Cooper 莱斯大学计算机科学系计算工程专业Doerr特聘教授,曾任该系系主任。Cooper博士的研究课题涵盖过程间......一起来看看 《编译器设计》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换