day06 分布式搜索引擎es

elasticsearch的作用

elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以帮助我们从海量数据中快速找到需要的内容

倒排索引

倒排索引的概念是基于MySQL这样的正向索引而言的。

倒排索引中有两个非常重要的概念:

  • 文档(Document):用来搜索的数据,其中的每一条数据就是一个文档。例如一个网页、一个商品信息

  • 词条(Term):对文档数据或用户搜索数据,利用某种算法分词,得到的具备含义的词语就是词条。例如:我是中国人,就可以分为:我、是、中国人、中国、国人这样的几个词条

那么为什么一个叫做正向索引,一个叫做倒排索引呢?

  • 正向索引是最传统的,根据id索引的方式。但根据词条查询时,必须先逐条获取每个文档,然后判断文档中是否包含所需要的词条,是根据文档找词条的过程

  • 倒排索引则相反,是先找到用户要搜索的词条,根据词条得到保护词条的文档的id,然后根据id获取文档。是根据词条找文档的过程

mysql与elasticsearch

我们统一的把mysql与elasticsearch的概念做一下对比

MYSQLELASTICSEARCH说明
TableIndex索引(index),就是文档的集合,类似数据库的表(table)
RowDocument文档(Document),就是一条条的数据,类似数据库中的行(Row),文档都是JSON格式
ColumnField字段(Field),就是JSON文档中的字段,类似数据库中的列(Column)
SchemaMappingMapping(映射)是索引中文档的约束,例如字段类型约束。类似数据库的表结构(Schema)
SQLDSLDSL是elasticsearch提供的JSON风格的请求语句,用来操作elasticsearch,实现CRUD

 

分词器

根据我们之前讲解的倒排索引原理,当我们向elasticsearch插入一条文档数据时,elasticsearch需要对数据分词,分词到底如何完成呢?

IK分词器

标准分词器并不能很好处理中文,一般我们会用第三方的分词器,例如:IK分词器。

IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包,是一个基于Maven构建的项目,具有60万字/秒的高速处理能力,支持用户词典扩展定义。(面试)

IK分词器的 地址:GitHub - medcl/elasticsearch-analysis-ik: The IK Analysis plugin integrates Lucene IK analyzer into elasticsearch, support customized dictionary., 安装非常简单。

IK分词器可以用ik_max_word(细粒度的分析)和ik_smart(粗粒度的分词)两种方式,分词粒度不同。

索引库的操作

按照Rest风格,增删改查分别使用:POST、DELETE、PUT、GET等请求方式,路径一般是资源名称。因此索引库操作的语法类似。

put /创建的索引库名称
{
    "settings": {
        "属性名": "属性值"
    }
}

  • 创建索引库: PUT /库名称

  • 查询索引库: GET /索引库名称

  • 删除索引库: DELETE /索引库名称

映射的属性

mapping是对索引库中文档的约束,常见的mapping属性包括:

  • type:字段数据类型,常见的简单类型有:

    • 字符串:text(可分词的文本)、keyword(精确值,例如:品牌、国家、ip地址)

    • 数值:long、integer、short、byte、double、float、

    • 布尔:boolean

    • 日期:date

    • 对象:object

  • index:是否创建索引,默认为true

  • analyzer:使用哪种分词器

  • properties:该字段的子字段

索引库已经存在:PUT /索引库名/_mapping

索引库不存在:PUT /索引库名称
{
  "mappings": {

    "properties": {
       "字段名":{
        "type": "text",
        "analyzer": "ik_smart"
      },

 }

}

查看使用Get请求   GET /索引库名/_mapping

 通过id查询 GET /{索引库名称}/_doc/{id}

GET /{索引库名称}/_doc/rGFGbm8BR8Fh6kyTbuq8

需要根据id进行删除: DELETE /{索引库名}/_doc/id值

为了与索引库操作分离,我们再次参加一个测试类,做两件事情:

  • 初始化RestHighLevelClient

  • 我们的酒店数据在数据库,需要利用IHotelService去查询,所以注入这个接口

@Test
void testGetDocumentById() throws IOException {
    // 1.准备Request
    GetRequest request = new GetRequest("hotel", "61082");
    // 2.发送请求,得到响应
    GetResponse response = client.get(request, RequestOptions.DEFAULT);
    // 3.解析响应结果
    String json = response.getSourceAsString();

    HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
    System.out.println(hotelDoc);
}

 批量导入:

@Test
void testBulkRequest() throws IOException {
    // 批量查询酒店数据
    List<Hotel> hotels = hotelService.list();

    // 1.创建Request
    BulkRequest request = new BulkRequest();
    // 2.准备参数,添加多个新增的Request
    for (Hotel hotel : hotels) {
        // 2.1.转换为文档类型HotelDoc
        HotelDoc hotelDoc = new HotelDoc(hotel);
        // 2.2.创建新增文档的Request对象
        request.add(new IndexRequest("hotel")
                    .id(hotelDoc.getId().toString())
                    .source(JSON.toJSONString(hotelDoc), XContentType.JSON));
    }
    // 3.发送请求
    client.bulk(request, RequestOptions.DEFAULT);
}

由于result风格都大同小异,掌握一个就等于掌握多个,不再赘述了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值