1、检索

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

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

1.1 Linux安装ElsticSearch

查看docker 库中的 ElasticSearch镜像:docker search elasticsearch

拉取docker中的ElasticSearch:docker pull elasticsearch:7.14.1

运行ElasticSearch:

  1. docker run --name e2 -p 9200:9200 -p 9300:9300 -e ES_JAVA_OPTS="-Xms1024m -Xmx1024m" -e "discovery.type=single-node" -d f287f2cfc393

2、概念

  • 以员工文档的形式存储为例:一个文档代表一个员工数据。存储数据到ElasticSearch 的行为叫做索引,但在索引一个文档之前,需要确定将文档存储在哪里。
  • 一个ElasticSearch 集群可以包含多个索引,相应的每个索引可以包含多个类型。这些不同的类型存储着多个文档,每个文档又有多个属性。
  • 类似关系:
    • –索引-数据库
    • –类型-表
    • –文档-表中的记录
    • –属性-列

image.png

对于员工目录,我们将做如下操作:

  • 每个员工索引一个文档,文档包含该员工的所有信息。
  • 每个文档都将是 employee 类型
  • 该类型位于 索引 megacorp 内。
  • 该索引保存在我们的 Elasticsearch 集群中。

实践中这非常简单(尽管看起来有很多步骤),我们可以通过一条命令完成所有这些动作:

  1. http://192.168.75.137:9200/megacorp/employee/3
  2. PUT /megacorp/employee/1
  3. {
  4. "first_name" : "John",
  5. "last_name" : "Smith",
  6. "age" : 25,
  7. "about" : "I love to go rock climbing",
  8. "interests": [ "sports", "music" ]
  9. }

检索文档

  1. http://192.168.75.137:9200/megacorp/employee/1 get

轻量搜索

  1. GET /megacorp/employee/_search

搜索姓氏为 Smith 的雇员。为此,我们将使用一个 高亮 搜索,很容易通过命令行完成。这个方法一般涉及到一个 查询字符串query-string) 搜索,因为我们通过一个URL参数来传递查询信息给搜索接口:

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

查询表达式查询数据:

  1. GET /megacorp/employee/_search
  2. {
  3. "query" : {
  4. "match" : {
  5. "last_name" : "Smith"
  6. }
  7. }
  8. }

复杂查询

搜索姓氏为 Smith 的员工,但这次我们只需要年龄大于 30 的。查询需要稍作调整,使用过滤器 filter ,它支持高效地执行一个结构化查询。

  1. {
  2. "query" : {
  3. "bool": {
  4. "must": {
  5. "match" : {
  6. "last_name" : "smith"
  7. }
  8. },
  9. "filter": {
  10. "range" : {
  11. "age" : { "gt" : 30 }
  12. }
  13. }
  14. }
  15. }
  16. }

全文检索:

搜索下所有喜欢攀岩(rock climbing)的员工:

  1. GET /megacorp/employee/_search
  2. {
  3. "query" : {
  4. "match" : {
  5. "about" : "rock climbing"
  6. }
  7. }
  8. }

短语搜索:

找出一个属性中的独立单词是没有问题的,但有时候想要精确匹配一系列单词或者短语 。 比如, 我们想执行这样一个查询,仅匹配同时包含 “rock” “climbing” ,并且 二者以短语 “rock climbing” 的形式紧挨着的雇员记录。
为此对 match 查询稍作调整,使用一个叫做 match_phrase 的查询:

  1. GET /megacorp/employee/_search
  2. {
  3. "query" : {
  4. "match_phrase" : {
  5. "about" : "rock climbing"
  6. }
  7. }
  8. }

高亮搜索:

许多应用都倾向于在每个搜索结果中 高亮 部分文本片段,以便让用户知道为何该文档符合查询条件。在 Elasticsearch 中检索出高亮片段也很容易。
再次执行前面的查询,并增加一个新的 highlight 参数:

当执行该查询时,返回结果与之前一样,与此同时结果中还多了一个叫做 highlight 的部分。这个部分包含了 about 属性匹配的文本片段,并以 HTML 标签 <em></em> 封装:

  1. GET /megacorp/employee/_search
  2. {
  3. "query" : {
  4. "match_phrase" : {
  5. "about" : "rock climbing"
  6. }
  7. },
  8. "highlight": {
  9. "fields" : {
  10. "about" : {}
  11. }
  12. }
  13. }

3、整合ElasticSearch

•引入spring-boot-starter-data-elasticsearch

•安装Spring Data 对应版本的ElasticSearch

•application.yml配置

•Spring Boot自动配置的

  1. @Configuration
  2. public class MyESConfig {
  3. @Bean
  4. RestHighLevelClient elasticsearchClient() {
  5. ClientConfiguration configuration = ClientConfiguration.builder()
  6. .connectedTo("192.168.75.137:9200")
  7. //.withConnectTimeout(Duration.ofSeconds(5))
  8. //.withSocketTimeout(Duration.ofSeconds(3))
  9. //.useSsl()
  10. //.withDefaultHeaders(defaultHeaders)
  11. //.withBasicAuth(username, password)
  12. // ... other options
  13. .build();
  14. RestHighLevelClient client = RestClients.create(configuration).rest();
  15. return client;
  16. }
  17. }

ElasticsearchRepository、ElasticsearchTemplate、Jest

  1. public interface BookRepository extends ElasticsearchRepository<Book,Integer> {
  2. }

•测试ElasticSearch