SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)

接上篇:https://developer.aliyun.com/article/1618415?spm=a2c6h.13148508.setting.20.134b4f0epDiaoT

4.5 词组搜索

单词/词组搜索 搜搜条件不做任何分词解析 在搜索字段对应的倒排索引中精确匹配

http://127.0.0.1:9200/student/_search
{
    "query": {
        "terms": {
            "info": ["is", "who"]
        }
    }
}

4.6 模糊搜索

在搜索时可能会出现错误 Elasticsearch 会自动纠错 进行模糊匹配

  • query: 搜索条件
  • fuzziness: 最多错误字符数 不能超过2
http://127.0.0.1:9200/student/_search
{
    "query": {
        "match": {
            "info": {
                "query": "liyi",
                "fuzziness": 1
            }
        }
    }
}

4.7 复合搜索

多个条件结合 搜索符合的结果

  • must 必须满足的条件
  • should 多个条件任意满足一个
  • must_not 必须不满足的条件
http://127.0.0.1:9200/student/_search
{
    "query": {
        "bool": {
            "must": [
                {
                    "match_phrase": {
                        "info": "my"
                    }
                },
                {
                    "match_phrase": {
                        "info": "name"
                    }
                }
                
            ],
            "should": [
                {
                    "match_phrase": {
                        "info": "name"
                    }
                }
            ],
            "must_not": [
                {
                    "match_phrase": {
                        "info": "wzk"
                    }
                }
            ]
        }
    }
}

4.8 结果排序

对查询到的结果进行排序

由于elasticsearch对text类型字段数据会做分词处理

所以无论使用那个单词排序都是不合理的 所以默认不允许对text类型进行排序


如果要使用字符串结果排序

可以使用keyword类型的字段作为排序依据 因为keyword字段不做分词处理


http://127.0.0.1:9200/student/_search
{
    "query": {
        "match_all": {

        }
    },
    "sort": [
        {
            "id": {
                "order": "desc"
            }
        }
    ]
}

4.9 分页查询

实际线上使用过程中 符合的结果可能很多
所以必须要对结果进行分页 提升效率

http://127.0.0.1:9200/student/_search
{
    "query": {
        "match_all": {

        }
    },
    "from": 0,
    "size": 2
}

4.10 高亮查询

http://127.0.0.1:9200/student/_search
{
    "query": {
        "match": {
            "info": "is"
        }
    },
    "highlight": {
        "fields": {
            "info": {
                "fragment_size": 100,
                "number_of_fragments": 5
            }
        }
    }
}

5.衣带渐宽

搭建项目 在 SpringBoot 项目中使用 Elasticsearch

采用的方案是 SpringData 上手比较简单 (对我来说 但可能不是很自由 学习足够了)


假设你已经有SpringBoot的基础啦!

下面我就快刀斩乱麻 起一个项目 (随手parent为2.2.2.RELEASE)


5.1 搭建项目

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.2.2.RELEASE</version>
</parent>

<dependencies>
  <!-- spring-boot-web -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>

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

  <!-- lombok -->
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.20</version>
    <scope>provided</scope>
  </dependency>
</dependencies>

5.2 基础配置

项目中新建 config 目录

新建配置类 (不要忘记 @Configuration)

@Configuration
public class ElasticSearchConfig extends AbstractElasticsearchConfiguration {

    @Override
    public RestHighLevelClient elasticsearchClient() {
        ClientConfiguration clientConfiguration = ClientConfiguration
                .builder()
                .connectedTo("127.0.0.1:9200")
                .build();
        return RestClients.create(clientConfiguration).rest();
    }
}

5.3 实体类

@Document(indexName = “student”) 索引名称是student 如果不存在则会自动创建

@Id 为索引

@Field(type = FieldType.Text, store = true) 字段

结构和elasticsearch你存储的对象的字段可以对应

新建model文件夹

新建Student对象

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Document(indexName = "student")
public class Student {
    @Id
    private Integer id;

    @Field(type = FieldType.Text, store = true)
    private String name;

    @Field(type = FieldType.Text, store = true)
    private String info;

    @Field(type = FieldType.Text, store = true)
    private String age;

    @Field(type = FieldType.Text, store = true)
    private String links;

}

5.4 创建接口

ElasticsearchRepository是基础类 继承后 有很多现成的方法

为 Student索引的名称 Integer为@Id字段

新建 dao 文件夹

新建 StudentRepository 类

public interface StudentRepository extends ElasticsearchRepository<Student, Integer> {

}

5.5 新增数据

这里为了省事 直接将逻辑放到了 Controller 上

将 StudentRepository 注入进来

SpringData 帮忙提供了很多现成的方法

@Autowired
private StudentRepository studentRepository;

@GetMapping("/addStudent")
public String addStudent() {
    String name = UUID.randomUUID().toString();
    name = name.replace("-", " ");
    Student student = Student
        .builder()
        .name(name)
        .links("this is a link to " + name)
        .build();
    studentRepository.save(student);
    return "ok";
}

5.6 查询数据

将 StudentRepository 注入进来


@Autowired

private StudentRepository studentRepository;


5.7 查询单条

将 StudentRepository 注入进来


@Autowired
private StudentRepository studentRepository;
@GetMapping("/getStudentById")
public Student getStudentById() {
    Optional<Student> stuData = studentRepository.findById(11);
    return stuData.orElseGet(Student::new);
}


5.8 修改数据

将 StudentRepository 注入进来

@Autowired
private StudentRepository studentRepository;

@GetMapping("/updStudent")
public String updStudent() {
    String name = UUID.randomUUID().toString();
    name = name.replace("-", " ");
    Student student = Student
        .builder()
        .id(1)
        .name(name)
        .links("this is a link to " + name)
        .build();
    studentRepository.save(student);
    return "ok";
}

5.9 删除数据

将 StudentRepository 注入进来


@Autowired
private StudentRepository studentRepository;
@GetMapping("/delStudent")
public String delStudent() {
    studentRepository.deleteById(1);
    return "ok";
}


6.灯火阑珊

第5章 我们发现 虽然SpringData帮我们提供了很多方法(通过继承的方式)

但是不够自由 当查询时条件复杂就不可以使用了

所以官方也提供了对应的解决方案


6.1 自定方法

先附上一篇 官方的对应关系

image.png

image.png

举例 根据上述规则使用一下


// 根据名字查询
List<Student> findByName(String name);
// 根据名字模糊查询
List<Student> findByNameLike(String name);


6.2 条件分页

Pageable pageable = PageRequest.of(0, 2); 即可实现分页查询


@Autowired

private StudentRepository studentRepository;


@GetMapping("/getPage")
public List<Student> getPage() {
    Pageable pageable = PageRequest.of(0, 2);
    Page<Student> page = studentRepository.findAll(pageable);
    List<Student> dataList = page.getContent();
    long number = page.getTotalElements();
    int total = page.getTotalPages();
    out.println("number: " + number);
    out.println("total: "+ total);
    return dataList;
}


6.3 自定分页

6.2 中使用了 Pageable 分页

我们也可以利用 6.1中的方式进行分页


在 StudentRepository 中 加入方法


// 注意 Pageable page
// 这样逻辑大约变成了(方便理解 用SQL表达一下): 
// select * from student where name=#{name} limit #{page.page, page.size}
Page<Student> findByNameLike(String name, Pageable page);

@Autowired

private StudentRepository studentRepository;


@GetMapping("/findByNamePage")
public List<Student> findByNamePage() {
    Pageable pageable = PageRequest.of(0, 1);
    // 传参 将 条件、分页 一起传入
    Page<Student> data = studentRepository.findByNameLike("2", pageable);
    System.out.println(data.getTotalElements());
    System.out.println(data.getTotalPages());
    return data.getContent();
}


6.4 查询排序

查询时 进行排序

Sort sort = Sort.by(Sort.Direction.DESC, “id”);


@Autowired

private StudentRepository studentRepository;

@GetMapping("/findByNameOrder")
public List<Student> findByNameOrder() {
  // 排序顺序、排序字段
    Sort sort = Sort.by(Sort.Direction.DESC, "id");
    Iterable<Student> dataList = studentRepository.findAll(sort);
    List<Student> resultList = new ArrayList<>();
    for (Student student : dataList) {
        resultList.add(student);
    }
    return resultList;
}


6.5 排序分页

Pageable 中加入了 Sort 所以可以分页、排序


@Autowired

private StudentRepository studentRepository;


@GetMapping("/findByNamePageOrder")
public List<Student> findByNamePageOrder() {
    Sort sort = Sort.by(Sort.Direction.ASC, "id");
    // 传参 start、limit、sort规则
    // 即可实现 分页 + 排序
    Pageable pageable = PageRequest.of(0,2, sort);
    Page<Student> page = studentRepository.findAll(pageable);
    return page.getContent();
}
相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
22天前
|
SQL 前端开发 关系型数据库
SpringBoot使用mysql查询昨天、今天、过去一周、过去半年、过去一年数据
SpringBoot使用mysql查询昨天、今天、过去一周、过去半年、过去一年数据
48 9
|
2月前
|
JSON Java 网络架构
elasticsearch学习四:使用springboot整合 rest 进行搭建elasticsearch服务
这篇文章介绍了如何使用Spring Boot整合REST方式来搭建和操作Elasticsearch服务。
130 4
elasticsearch学习四:使用springboot整合 rest 进行搭建elasticsearch服务
|
1月前
|
JSON Java API
springboot集成ElasticSearch使用completion实现补全功能
springboot集成ElasticSearch使用completion实现补全功能
35 1
|
2月前
|
自然语言处理 搜索推荐 关系型数据库
elasticsearch学习六:学习 全文搜索引擎 elasticsearch的语法,使用kibana进行模拟测试(持续更新学习)
这篇文章是关于Elasticsearch全文搜索引擎的学习指南,涵盖了基本概念、命令风格、索引操作、分词器使用,以及数据的增加、修改、删除和查询等操作。
27 0
elasticsearch学习六:学习 全文搜索引擎 elasticsearch的语法,使用kibana进行模拟测试(持续更新学习)
|
2月前
|
Web App开发 JavaScript Java
elasticsearch学习五:springboot整合 rest 操作elasticsearch的 实际案例操作,编写搜索的前后端,爬取京东数据到elasticsearch中。
这篇文章是关于如何使用Spring Boot整合Elasticsearch,并通过REST客户端操作Elasticsearch,实现一个简单的搜索前后端,以及如何爬取京东数据到Elasticsearch的案例教程。
203 0
elasticsearch学习五:springboot整合 rest 操作elasticsearch的 实际案例操作,编写搜索的前后端,爬取京东数据到elasticsearch中。
|
2月前
|
自然语言处理 Java Maven
elasticsearch学习二:使用springboot整合TransportClient 进行搭建elasticsearch服务
这篇博客介绍了如何使用Spring Boot整合TransportClient搭建Elasticsearch服务,包括项目创建、Maven依赖、业务代码和测试示例。
107 0
elasticsearch学习二:使用springboot整合TransportClient 进行搭建elasticsearch服务
|
2月前
|
存储 JSON Java
elasticsearch学习一:了解 ES,版本之间的对应。安装elasticsearch,kibana,head插件、elasticsearch-ik分词器。
这篇文章是关于Elasticsearch的学习指南,包括了解Elasticsearch、版本对应、安装运行Elasticsearch和Kibana、安装head插件和elasticsearch-ik分词器的步骤。
147 0
elasticsearch学习一:了解 ES,版本之间的对应。安装elasticsearch,kibana,head插件、elasticsearch-ik分词器。
|
2月前
|
开发框架 监控 搜索推荐
GoFly快速开发框架集成ZincSearch全文搜索引擎 - Elasticsearch轻量级替代为ZincSearch全文搜索引擎
本文介绍了在项目开发中使用ZincSearch作为全文搜索引擎的优势,包括其轻量级、易于安装和使用、资源占用低等特点,以及如何在GoFly快速开发框架中集成和使用ZincSearch,提供了详细的开发文档和实例代码,帮助开发者高效地实现搜索功能。
140 0
|
19天前
|
存储 安全 数据管理
如何在 Rocky Linux 8 上安装和配置 Elasticsearch
本文详细介绍了在 Rocky Linux 8 上安装和配置 Elasticsearch 的步骤,包括添加仓库、安装 Elasticsearch、配置文件修改、设置内存和文件描述符、启动和验证 Elasticsearch,以及常见问题的解决方法。通过这些步骤,你可以快速搭建起这个强大的分布式搜索和分析引擎。
34 5
|
3月前
|
NoSQL 关系型数据库 Redis
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
mall在linux环境下的部署(基于Docker容器),docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongodb、minio详细教程,拉取镜像、运行容器
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo