一、ElasticSearch简介

我们的应用经常需要添加检索功能,开源的 ElasticSearch 是目前全文搜索引擎的首选。他可以快速的存储、搜索和分析海量数据。Spring Boot通过整合Spring Data ElasticSearch为我们提供了非常便捷的检索功能支持;

Elasticsearch是一个分布式搜索服务,提供Restful API,底层基于Lucene,采用多shard(分片)的方式保证数据安全,并且提供自动resharding的功能,github等大型的站点也是采用了ElasticSearch作为其搜索服务.

能实现类似于Solr的站内搜索。

ElasticSearch中文文档

二、ElasticSearch部署与使用

通过docker去运行ElasticSearch容器,因为ElasticSearch可以支持使用Rest风格的Http请求进行对其操作。

ElasticSearch可以使用基于HTTP协议,以JSON为数据交互格式的RESTful API

1.简介一下ElasticSearch的名词概念:

索引(Indices):索引(名词) 一个索引(index)就像是传统关系数据库中的数据库,它是相关文档存储的地方,index的复数是indices indexes

索引(动词) 「索引一个文档」表示把一个文档存储到索引(名词)里,类似于SQL中的insert

类型(type):一个索引可以包含多个类型,类似于SQL中的

文档(documents):每个类型可以包含多个文档,类似于SQL中每一行数据

列(Fields):每个文档包含多个字段(Fields)(列)。类似于SQL中的

Relational DB -> Databases -> Tables -> Rows -> Columns Elasticsearch -> Indices -> Types -> Documents -> Fields

2.使用docker将ElesticSearch部署到linux

要注意一点,ElesticSearch在启动的时候需要吃内存,如果虚拟机内存小可能会导致启动后几十秒就自动崩溃,解决方案:

关于docker启动ElasticSearch自动崩溃的解决方案

9200端口是用来进行web操作的,9300端口是用来集群之间通信的,所以我们这里暂时只用到了9200端口。

运行起来没问题之后,我们可以浏览器输入http://IP:9200访问

spring es 搜索商品_spring

证明部署成功

可以通过向这个url发送一个uri为/megacorp/employee/1的PUT请求来进行文档的添加,发送的请求行为要添加的内容的json串

{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}

spring es 搜索商品_elasticsearch_02

删除则向对应的URL发DELETE请求即可

更新可以通过向指定URL发送POST请求,如果文档存在则默认会覆盖。

可以通过向指定URL发送HEAD请求来检查某文档是否存在

查询特定文档可以向指定URL发送get请求,例如:

GET /megacorp/employee/1

响应的内容中包含一些文档的元信息

spring es 搜索商品_Elastic_03

查询某索引下某类型的全部文档可以向指定URL发送GET请求,例如:

GET /megacorp/employee/_search

可以通过

GET /megacorp/employee/_search?q=last_name:Smith

进行指定字符串查询

但查询字符串搜索便于通过命令行完成特定(ad hoc)的搜索,但是它也有局限性(参阅简单搜索章节)。Elasticsearch提供丰富且灵活的查询语言叫做DSL查询(Query DSL),它允许你构建更加复杂、强大的查询。

DSL(Domain Specific Language特定领域语言)以JSON请求体的形式出现。我们可以这样表示之前关于“Smith”的查询:

GET /megacorp/employee/_search
{
    "query" : {
        "match" : {
            "last_name" : "Smith"
        }
    }
}

这会返回与之前查询相同的结果。你可以看到有些东西改变了,我们不再使用查询字符串(query string)做为参数,而是使用请求体代替。这个请求体使用JSON表示,其中使用了match语句。

3.SpringBoot进行整合

这里我们使用SpringData对ElasticSearch进行整合

依赖:


<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>


查看依赖后发现,SpringBoot2.1.4采用的elasticsearch是6.4.3版本

为了确保不出问题,我重新下载6.4.3版本,事后我验证了,就以下的这些基本操作,es的版本可以不影响

package org.dreamtech.esdemo.domain;

import java.io.Serializable;

import org.springframework.data.elasticsearch.annotations.Document;

/**
 * 文章对象
 * 
 * @author Xu Yiqing
 *
 */
@Document(indexName = "blog", type = "article")
public class Article implements Serializable {

    private static final long serialVersionUID = 8210249797764830332L;

    private long id;

    private String title;

    private String summary;

    private String content;

    private int pv;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getSummary() {
        return summary;
    }

    public void setSummary(String summary) {
        this.summary = summary;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public int getPv() {
        return pv;
    }

    public void setPv(int pv) {
        this.pv = pv;
    }

}

配置文件

spring.data.elasticsearch.cluster-name=elasticsearch
spring.data.elasticsearch.cluster-nodes=IP:9300
spring.data.elasticsearch.repositories.enabled=true

对ES进行默认操作的接口

package org.dreamtech.esdemo.repository;

import org.dreamtech.esdemo.domain.Article;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Component;

@Component
public interface ArticleRepository extends ElasticsearchRepository<Article, Long> {
}

Controller层进行测试

@RestController
public class ArticleController {

    @Autowired
    private ArticleRepository articleRepository;

    @GetMapping("/save")
    public Object save(long id, String title) {

        Article article = new Article();
        article.setId(id);
        article.setPv(123);
        article.setContent("Springboot整合Elasticsearch");
        article.setTitle(title);
        article.setSummary("搜索框架整合");

        articleRepository.save(article);

        return "save";
    }

    @GetMapping("/search")
    public Object search(String title) {
        QueryBuilder queryBuilder = QueryBuilders.matchQuery("title", title);
        Iterable<Article> list = articleRepository.search(queryBuilder);
        return list;
    }