微服务[学成在线] day11:基于 ElasticSearch 构建搜索服务

本文介绍了如何使用Elasticsearch构建搜索服务,涵盖了环境准备、DSL搜索、集群管理和搜索服务开发等内容。从创建映射、插入数据到实现DSL查询,包括Term Query、分页、过滤器等,最后讨论了集群搭建、健康状态检查以及搜索服务的Java实现。
摘要由CSDN通过智能技术生成

😎 知识点概览

为了方便后续回顾该项目时能够清晰的知道本章节讲了哪些内容,并且能够从该章节的笔记中得到一些帮助,所以在完成本章节的学习后在此对本章节所涉及到的知识点进行总结概述。

本章节为【学成在线】项目的 day11 的内容

  • 基于 Java 客户端实现 DSL 搜索
  • 搭建 ElasticSearch 集群环境
  • 使用 Logstash 自动创建 ElasticSearch 的索引、数据文档
  • 基于 ElasticSearch 开发搜索服务接口

目录

内容会比较多,小伙伴们可以根据目录进行按需查阅。

一、搜索管理

0x01 准备环境

1、创建映射

创建 xc_course 索引库,方式如下

post:http://localhost:9200/xc_course/doc/_mapping

{
   
    "properties": {
   
        "description": {
   
            "type": "text",
            "analyzer": "ik_max_word",
            "search_analyzer": "ik_smart"
        },
        "name": {
   
            "type": "text",
            "analyzer": "ik_max_word",
            "search_analyzer": "ik_smart"
        },
        "pic": {
   
            "type": "text",
            "index": false
        },
        "price": {
   
            "type": "float"
        },
        "studymodel": {
   
            "type": "keyword"
        },
        "timestamp": {
   
            "type": "date",
            "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
        }
    }
}

2、插入原始数据

xc_course/doc 中插入以下三个文档数据:

PUT:http://localhost:9200/xc_course/doc/1

{
    
    "name": "Bootstrap开发",
    "description": "Bootstrap是由Twitter推出的一个前台页面开发框架,是一个非常流行的开发框架,此框架集成了多种页面效果。此开发框架包含了大量的CSS、JS程序代码,可以帮助开发者(尤其是不擅长页面开发的程序人员)轻松的实现一个不受浏览器限制的精美界面效果。",
    "studymodel": "201002",
    "price":38.6,
    "timestamp":"2018-04-25 19:11:35",
 "pic":"group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg"
} 

PUT:http://localhost:9200/xc_course/doc/2

{
    
	"name": "java编程基础",
"description": "java语言是世界第一编程语言,在软件开发领域使用人数最多。",
"studymodel": "201001",
"price":68.6,
"timestamp":"2018-03-25 19:11:35",
"pic":"group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg"
} 

PUT:http://localhost:9200/xc_course/doc/3

{
    
    "name": "spring开发基础",
    "description": "spring 在java领域非常流行,java程序员都在用。",
    "studymodel": "201001",
    "price":88.6,
    "timestamp":"2018-02-24 19:11:35",
  "pic":"group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg"
}

3、简单的搜索一下

简单搜索就是通过 url 进行查询,以 get 方式请求 ES

格式:GET …/_search?q=…

q:搜索字符串。

例子:?q=name:spring

搜索name中包括spring的文档。

0x02 DSL 搜索

DSL(Domain Specific Language) 是 ES 提出的基于 json 的搜索方式,在搜索时传入特定的 json 格式的数据来完成不同的搜索需求。

DSLURI (在url传递搜索参数) 搜索方式功能强大,在项目中建议使用 DSL 方式来完成搜索。

1、查询所有文档

查询所有索引库的文档。

发送:post http://localhost:9200/_search

查询指定索引库 指定类型 下的文档。(通过使用此方法)

发送:post http://localhost:9200/xc_course/doc/_search

{
   
    "query": {
   
    	"match_all": {
   }
    },
    "_source" : ["name","studymodel"]
}

_source:source 源过虑设置,指定结果中所包括的字段有哪些。

搜索结果:

{
   
    "took": 9,
    "timed_out": false,
    "_shards": {
   
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
   
        "total": 3,
        "max_score": 1.0,
        "hits": [
            {
   
                "_index": "xc_course",
                "_type": "doc",
                "_id": "1",
                "_score": 1.0,
                "_source": {
   
                    "studymodel": "201002",
                    "name": "Bootstrap开发"
                }
            },
            {
   
                "_index": "xc_course",
                "_type": "doc",
                "_id": "2",
                "_score": 1.0,
                "_source": {
   
                    "studymodel": "201001",
                    "name": "java编程基础"
                }
            },
            {
   
                "_index": "xc_course",
                "_type": "doc",
                "_id": "3",
                "_score": 1.0,
                "_source": {
   
                    "studymodel": "201001",
                    "name": "spring开发基础"
                }
            }
        ]
    }
}

结果说明:

字段名称 描述
took 本次操作花费的时间,单位为毫秒。
timed_out 请求是否超时
_shards 说明本次操作共搜索了哪些分片
hits 搜索命中的记录
hits.total 符合条件的文档总数 hits.hits :匹配度较高的前N个文档
hits.max_score 文档匹配得分,这里为最高分
_score 每个文档都有一个匹配度得分,按照降序排列。
_source 显示了文档的原始内容。

使用JAVA 客户端实现:

  • 创建搜索请求对象

  • 指定类型(部分版本不需要指定类型,这里以 6.2.1 为例)

  • 构建搜索源对象

  • 配置搜索方式,设置需要过滤字段

  • 向搜索请求中设置搜索源

  • 执行搜索,向ES发起 http 请求

  • 搜索结果 asd as

  • 匹配到的总记录数

  • 得到匹配度高的文档

  • 遍历结果,获取 SearchHit 对象中的属性,输出或者存档。

具体代码如下:

@SpringBootTest
@RunWith(SpringRunner.class)
public class TestSearch {
   
    @Autowired
    RestHighLevelClient client;

    //搜索type下的全部记录
    @Test
    public void testSearchAll() throws IOException {
   
        //获取搜索请求对象,并且设置类型
        SearchRequest searchRequest = new SearchRequest("xc_course");
        searchRequest.types("doc");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        
        //设置搜索方式
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        
        //配置source源字段过虑,1显示的,2排除的
        searchSourceBuilder.fetchSource(new String[]{
   "name","studymodel"}, new String[]{
   });
        
        //将搜索源配置到搜索请求中,执行搜索,获取搜索响应结果
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest);
       	
        //获取所有搜索结果、总匹配数量
        SearchHits hits = searchResponse.getHits();
        long totalHits = hits.getTotalHits();
        
        //筛选出匹配度高的文档记录
        SearchHit[] searchHits = hits.getHits();
        
        //遍历结果
        for (SearchHit hit : searchHits) {
   
            String index = hit.getIndex();
            String type = hit.getType();
            String id = hit.getId();
            float score = hit.getScore();
            String sourceAsString = hit.getSourceAsString();
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            String name = (String) sourceAsMap.get("name");
            String studymodel = (String) sourceAsMap.get("studymodel");
            String description = (String) sourceAsMap.get("description");
            System.out.println(name);
            System.out.println(studymodel);
            System.out.println(description);
        }
    }
}

2、分页查询

ES 支持分页查询,传入两个参数:fromsize

  • form:表示起始文档的下标,从0开始。

  • size:查询的文档数量。

发送:post http://localhost:9200/xc_course/doc/_search

{
   
    "from" : 0, 
    "size" : 1,
    "query": {
   
    	"match_all": {
   }
    },
    "_source" : ["name","studymodel"]
}

使用JAVA 客户端实现:

 //分页查询
@Test
public void testSearchPage() throws IOException {
   
    //获取搜索请求对象,并且设置类型
    SearchRequest searchRequest = new SearchRequest("xc_course");
    searchRequest.types("doc");
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

    //设置搜索方式
    searchSourceBuilder.query(QueryBuilders.matchAllQuery());

    //ES这里是按起始坐标来实现分页查询,所以我们要指定一个页码
    int pageNum = 1;
    int size = 2;
    //通过页码和查询数量得出起始位置
    int fromNum = (pageNum - 1) * size;
    //分页查询,设置起始下标,从0开始
    searchSourceBuilder.from(0);
    //每页显示个数
    searchSourceBuilder.size(size);
    //配置source源字段过虑,1显示的,2排除的
    searchSourceBuilder.fetchSource(new String[]{
   "name","studymodel"}, new String[]{
   });

    //将搜索源配置到搜索请求中,执行搜索,获取搜索响应结果
    searchRequest.source(searchSourceBuilder);
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest);

    //获取所有搜索结果、总匹配数量
    SearchHits hits = searchResponse.getHits();
    long totalHits = hits.getTotalHits();

    //筛选出匹配度高的文档记录
    SearchHit[] searchHits = hits.getHits();

    //遍历结果
    for(SearchHit hit : searchHits){
   
        System.out.println(hit.toString());
    }
}

3、Term Query

Term Query 为精确查询,在搜索时会整体匹配关键字,不再将关键字分词。

发送:post http://localhost:9200/xc_course/doc/_search

{
   
    "query": {
   
        "term" : {
   
            "name": "spring"
        }
    },
    "_source" : ["name","studymodel"]
}

上边的搜索会查询 name 包括 spring 这个词的文档。

JAVA客户端实现:

/**
     * Term Query 精确查询
     */
@Test
public void TestSearchTermQuery() throws IOException {
   
    SearchRequest searchRequest = new SearchRequest("xc_course");
    searchRequest.types("doc");
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    //设置查询类型为termQuery,精确匹配name中包含spring的文档
    searchSourceBuilder.query(QueryBuilders.termQuery("name","spring"));//source源字段过虑

    //不指定过滤条件则默认显示查询到的文档的所有字段
    searchSourceBuilder.fetchSource(new String[]{
   }, new String[]{
   });

    //设置搜索源并获取搜索结果
    searchRequest.source(searchSourceBuilder);
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest);

    //获取搜索结果
    //  .getHits() 取本次所有匹配结果
    //  .getHits().getHits() 筛选出匹配度高的文档记录
    SearchHits hits = searchResponse.getHits();
    long tot
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值