当先锋百科网

首页 1 2 3 4 5 6 7

SpringBoot 使用 ElasticSearch 6.x搜索引擎

一、介绍

Elasticsearch (ES)是一个基于Lucene构建的开源、分布式、RESTful 接口全文搜索引擎。Elasticsearch 还是一个分布式文档数据库,其中每个字段均是被索引的数据且可被搜索,它能够扩展至数以百计的服务器存储以及处理PB级的数据。它可以在很短的时间内在储、搜索和分析大量的数据。它通常作为具有复杂搜索场景情况下的核心发动机。
Elasticsearch就是为高可用和可扩展而生的。可以通过购置性能更强的服务器来完成。

二、Elasticsearch优势

  1. 横向可扩展性:只需要增加台服务器,做一点儿配置,启动一下Elasticsearch就可以并入集群。

  2. 分片机制提供更好的分布性:同一个索引分成多个分片(sharding), 这点类似于HDFS的块机制;分而治之的方式可提升处理效率。

  3. 高可用:提供复制( replica) 机制,一个分片可以设置多个复制,使得某台服务器在宕机的情况下,集群仍旧可以照常运行,并会把服务器宕机丢失的数据信息复制恢复到其他可用节点上。
    口使用简单:共需一条命令就可以下载文件,然后很快就能搭建一一个站内搜索引擎。

三、Elasticsearch存储结构

Elasticsearch是文件存储,Elasticsearch是面向文档型数据库,一条数据在这里就是一个文档,用JSON作为文档序列化的格式,比如下面这条用户数据

{
    "name" :     "哈哈哈",
    "sex" :      男,
    "age" :     10
}

关系数据库 ⇒ 数据库 ⇒ 表 ⇒ 行 ⇒ 列(Columns)
Elasticsearch ⇒ 索引(Index) ⇒ 类型(type) ⇒ 文档(Docments) ⇒ 字段(Fields)

四、Elasticsearch版本控制

  1. 版本控制
    为了保证数据再多线程操作下的准确性
  2. 悲观锁和乐观锁
    悲观锁:假设会发生并发冲突,屏蔽一切可能违反数据准确性的操作
    悲观锁:假设不会发生并发冲突,只在提交操作是检查是否违反数据完整性。
  3. 内部版本控制和外部版本控制
    内部版本控制:_version自增长,修改数据后,_version会自动的加1
    外部版本控制:为了保持_version与外部版本控制的数值一致

五、环境搭建

Es的环境搭建,在我博客中有介绍,可参考:

https://blog.csdn.net/qq_43692950/article/details/107689309

六、SpringBoot集成Elasticsearch

1. pom

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

2. application.properties

#elasticsearch
spring.data.elasticsearch.cluster-name=elasticsearch
#集群
#spring.data.elasticsearch.cluster-nodes=192.168.2.112:9300,192.168.2.139:9300,192.168.2.133:9300
#单机
spring.data.elasticsearch.cluster-nodes=localhost:9300
spring.data.elasticsearch.repositories.enabled=true

3. Entity

@Document(indexName = "detection",type = "info") //索引名和类型
@Data
public class TakeEntity implements Serializable {
    @Id
    private long id;
    @Field(type = FieldType.text, analyzer = "ik_smart", searchAnalyzer = "ik_smart") //使用ik中文分词器,ik的环境需要配置
    private String deviceid;
    @Field
    private String imgpath;
    @Field
    private long time;
    @Field
    private String age;
    @Field
    private String gender;
}

4. Repository

@Repository
public interface TakeFaceRepository extends ElasticsearchRepository<TakeEntity, Long> {
}

5. Service

public interface DemoService {

    boolean save(TakeEntity takeFace);

    Iterable<TakeEntity> findall();

    void search();

    boolean delete();

    void update();
}

6. Impl

@Service
public class DemoServiceImpl implements DemoService {

    @Autowired
    TakeFaceRepository takeFaceRepository;

    /*
    添加数据
     */
    @Override
    public boolean save(TakeEntity takeFace) {
        try {
            //添加单条数据
            takeFaceRepository.save(takeFace);
            //添加多条数据
            List<TakeEntity> list = new ArrayList<>();
            list.add(takeFace);
            list.add(takeFace);
            list.add(takeFace);
            takeFaceRepository.saveAll(list);

            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


    /*
    查询数据 find
     */
    @Override
    public Iterable<TakeEntity> findall() {
        //查询全部
        Iterable<TakeEntity> all = takeFaceRepository.findAll();
        //排序
        takeFaceRepository.findAll(Sort.by(Sort.Direction.DESC, "time"));
        //分页查询
        Pageable pageable1 = PageRequest.of(1, 20);
        //分页加排序
        Pageable pageable = new PageRequest(1, 20, Sort.by(Sort.Direction.DESC, "time"));
        Pageable pageable2 = PageRequest.of(1, 20, Sort.by(Sort.Direction.DESC, "time"));
        Pageable pageable3 = PageRequest.of(1, 20, Sort.Direction.DESC, "time");
        takeFaceRepository.findAll(pageable);
        //根据id查询多个
        List<Long> longs = new ArrayList<>();
        longs.add(1234L);
        takeFaceRepository.findAllById(longs);

        return all;
    }

    /*
    条件查询
     */
    public void search() {
        //精确查询 =
        QueryBuilder queryBuilder = QueryBuilders.termQuery("info", "abc");

        //精确查询 多个 in
        QueryBuilder queryBuilder1 = QueryBuilders.termsQuery("info", "abc", "asd");

        //模糊匹配
        QueryBuilder queryBuilder2 = QueryBuilders.matchQuery("info", "ab");

        //模糊匹配 多个
        QueryBuilder queryBuilder3 = QueryBuilders.multiMatchQuery("info", "ab", "tc");

        //全部数据
        QueryBuilder queryBuilder4 = QueryBuilders.matchAllQuery();

        //多条件构建BoolQueryBuilder
        BoolQueryBuilder queryBuilder5 = QueryBuilders.boolQuery();
        //并且 and
        queryBuilder5.must(QueryBuilders.termQuery("info", "abc"));
        queryBuilder5.must(QueryBuilders.termQuery("gender", "18"));

        //或者 or
        queryBuilder5.should(QueryBuilders.termQuery("info", "azs"));
        queryBuilder5.should(QueryBuilders.termQuery("info", "azs1"));

        //不等于
        queryBuilder5.mustNot(QueryBuilders.termQuery("gender", "19"));

        //过滤数据
        queryBuilder5.filter(QueryBuilders.matchQuery("info", "ab"));

        //范围查询
        /*
            gt 大于 >
            gte 大于等于 >=
            lt 小于 <
            lte 小于等于 <=
        */
        queryBuilder5.filter(new RangeQueryBuilder("age").gt(10).lte(50));

        //使用分词器
        queryBuilder5.must(QueryBuilders.matchQuery("info","abc").analyzer("ik_max_word"));
        queryBuilder5.must(QueryBuilders.matchQuery("info","abc1").analyzer("ik_smart"));

        //构建分页
        Pageable pageable = PageRequest.of(1, 20);

        //多场景下复杂条件
        SearchQuery search = new NativeSearchQueryBuilder()
                .withQuery(queryBuilder4)
                .withPageable(pageable)
                .withSort(SortBuilders.fieldSort("age").order(SortOrder.DESC))
                .build();

        takeFaceRepository.search(search);
        takeFaceRepository.search(queryBuilder);
        takeFaceRepository.search(queryBuilder5);
        //分页查询
        takeFaceRepository.search(queryBuilder, pageable);

    }

    /*
  删除
   */
    @Override
    public boolean delete() {
        try {
            //删除全部数据
            takeFaceRepository.deleteAll();
            //根据id
            takeFaceRepository.deleteById(1L);
            //根据条件
            TakeEntity takeEntity = new TakeEntity();
            takeEntity.setInfo("abc");
            takeFaceRepository.delete(takeEntity);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /*
    修改数据,直接save保存
     */
    @Override
    public void update(){
        TakeEntity entity = new TakeEntity();
        entity.setId(10);
        entity.setInfo("afg");
        takeFaceRepository.save(entity);
    }
}

七、Kibana基本使用

Kibana es的客户端工具,安装可参考:

https://blog.csdn.net/qq_43692950/article/details/107713161

  1. 创建索引
PUT /testindex
  1. 查询索引
GET /testindex
  1. 添加文档
    /索引名称/类型/id
PUT /testindex/user/2
{
  "name":"abc",
  "sex":2,
  "age":18
}
  1. 根据id查询文档
GET /testindex/user/1
  1. 查询全部
GET /testindex/_search
GET /testindex/user/_search
  1. 查询多个id分别为1、2
GET /testindex/user/_mget
{
  "ids":["1","2"]
}
  1. 精确查询
GET /testindex/user/_search
{
  "query": {
    "term": {
      "name": "abc"
    }
  }
}
  1. 模糊查询
GET /testindex/user/_search
{
  "from": 1,
  "size": 2, 
  "query": {
    "match": {
        "name": "abc"
      }
  }
}
  1. 删除索引
DELETE /testindex