使用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


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

查看所有标签

猜你喜欢:

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

风口上的汽车新商业

风口上的汽车新商业

郭桂山 / 人民邮电出版社 / 59

本书从互联网+汽车趋势解析、汽车电商困局突围策略、汽车后市场溃败求解等三个篇章详细阐述了作者的观察与思考,当然更多的还是作者在汽车电商行业的实践中得出的解决诸多问题的战略策略,作者站在行业之巅既有战略策略的解决方案,同时也有战术上的实施细则,更有实操案例解析与行业大咖访谈等不可多得的干货。当然,作者一向追崇的宗旨是,书中观点的对错不是最重要的,重在与行业同仁探讨,以书会友,希望作者的这块破砖头,能......一起来看看 《风口上的汽车新商业》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

html转js在线工具
html转js在线工具

html转js在线工具