ElasticSearch

全文检索

用户访问我们的首页,一般都会直接搜索来寻找自己想要购买的商品。 而商品的数量非常多,而且分类繁杂。如果能正确的显示出用户想要的商品,并进行合 理的过滤,尽快促成交易,是搜索系统要研究的核心。 面对这样复杂的搜索业务和数据量,使用传统数据库搜索就显得力不从心,一般我们都 会使用全文检索技术。

  • 面对这样复杂的搜索业务和数据量,使用传统数据库搜索就显得力不从心,一般我们都 会使用全文检索技术。
  • 常见的全文检索技术有 Lucene、solr 、elasticsearch 等。

索引结构

在这里插入图片描述

  • 逻辑索引结构部分是一个倒排索引表:
  1. 将要搜索的文档内容分词,所有不重复的词组成分词列表。
  2. 将要搜索的文档最终以Document方式存储起来。
  3. 每个词和document都有关联。
    如下:
    在这里插入图片描述
    现在如果我们想要搜索quick brown,我们只需要查询包含每个词条的文档:
    在这里插入图片描述
    两个文档都匹配,但是第一个文档比第二个匹配度更高。如果我们使用仅仅计算匹配词条数量的简单相似算法,那么,我们可以说,对于我们查询的相关性来讲第一个文档比第二个文档更佳。

概述

  • ElasticSearch是一个基于Lucene的搜索服务器。他提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。ElasticSearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当下流行的企业级说说引擎。设计用于云计算中国,能够达到实时搜索,稳定,可靠,快速,安装使用方便。
  • 官方网址:https://www.elastic.co/cn/products/elasticsearch
  • Github:https://github.com/elastic/elasticsearch
  • 优点:
  1. 可以作为一个大型分布式集群(数百台服务器)技术,处理PB级的数据,也可以运行在单机上
  2. 将全文检索、数据分析以及分布式技术合并在了一起,才形成了独一无二的ES;
  3. 开箱即用,部署简单
  4. 全文检索,同义词处理,相关度排名,复杂数据分析,海量数据的近实时处理;

ElasticSearch与MySQL的逻辑结构概念对比

在这里插入图片描述

使用postman工具操作索引库

1、 新建文档
  • 以post方式提交到localhost:9200/testindex/doc
    提交一个json数据:
    在这里插入图片描述
    将返回如下结果:
    在这里插入图片描述
    _id是由系统自动生成的。
2、查询文档

查询某索引某类型的全部数据,以get方式请求 http://127.0.0.1:9200/testindex/doc/_search 返回结果如下:
在这里插入图片描述
在这里插入图片描述
hits采样统计:

  • total:总共搜索到的结果条数
  • max-score:值得大小表示其与搜索词条的相关程度(值越大越精准)
    在这里插入图片描述

映射与数据类型

映射(Mapping)相当于数据表的表结构。ElasticSearch中的映射(Mapping)用来 定义一个文档,可以定义所包含的字段以及字段的类型、分词器及属性等等。
映射可以分为动态映射和静态映射。

  • 动态映射 (dynamic mapping):
    • 在关系数据库中,需要事先创建数据库,然后在 该数据库实例下创建数据表,然后才能在该数据表中插入数据。而ElasticSearch中不需 要事先定义映射(Mapping),文档写入ElasticSearch时,会根据文档字段自动识别类 型,这种机制称之为动态映射。
  • 静态映射 :
    • 在ElasticSearch中也可以事先定义好映射,包含文档的各个字段及其类 型等,这种方式称之为静态映射。
字符串类型

在这里插入图片描述

整数类型

在这里插入图片描述

浮点类型

在这里插入图片描述

date类型

日期类型表示格式可以是以下几种:

  1. 日期格式的字符串,比如 “2018-01-13” 或 “2018-01-13 12:10:30”
  2. long类型的毫秒数( milliseconds-since-the-epoch,epoch就是指UNIX诞生的UTC 时间1970年1月1日0时0分0秒)
  3. integer的秒数(seconds-since-the-epoch)
Boolean类型
  • 逻辑类型(布尔类型)可以接受true/false
binary类型
  • 二进制字段是指用base64来表示索引中存储的二进制数据,可用来存储二进制形式 的数据,例如图像。默认情况下,该类型的字段只存储不索引。二进制类型只支持 index_name属性。
array类型
  • 在ElasticSearch中,没有专门的数组(Array)数据类型,但是,在默认情况下,任 意一个字段都可以包含0或多个值,这意味着每个字段默认都是数组类型,只不过,数组 类型的各个元素值的数据类型必须相同。在ElasticSearch中,数组是开箱即用的(out of box),不需要进行任何配置,就可以直接使用。
  • 在同一个数组中,数组元素的数据类型是相同的,ElasticSearch不支持元素为多个 数据类型:[ 10, “some string” ],常用的数组类型是:
    • 字符数组: [ “one”, “two” ]
    • 整数数组: productid:[ 1, 2 ]
    • 对象(文档)数组: “user”:[ { “name”: “Mary”, “age”: 12 }, { “name”: “John”, “age”: 10 }],ElasticSearch内部把对象数组展开为 {“user.name”: [“Mary”, “John”], “user.age”: [12,10]}
object类型
  • JSON天生具有层级关系,文档会包含嵌套的对象

IK分词器

什么是IK分词器

*使用postman测试 post方式提交 http://127.0.0.1:9200/testindex/_analyze提交JSON数据:{“analyzer”: “chinese”, “text”: “王富贵儿” }

  • 返回如下结果:
{
"tokens": [ 
{ "token": "王", 
"start_offset": 0, 
"end_offset": 1, 
"type": "<IDEOGRAPHIC>", 
"position": 0 
},
{ 
"token": "富", 
"start_offset": 1, 
"end_offset": 2, 
"type": "<IDEOGRAPHIC>", 
"position": 1 
},
{ 
"token": "贵", 
"start_offset": 2, 
"end_offset": 3, 
"type": "<IDEOGRAPHIC>", 
"position": 2 
},
{ 
"token": "儿", 
"start_offset": 3, 
"end_offset": 4, 
"type": "<IDEOGRAPHIC>", 
"position": 3 
},
 ] 
 }

默认的中文分词是将每个字看成一个词,这显然是不符合要求的,所以我们需要安装中 文分词器来解决这个问题。
IK分词是一款国人开发的相对简单的中文分词器。虽然开发者自2012年之后就不在维护 了,但在工程应用中IK算是比较流行的一款!我们今天就介绍一下IK中文分词器的使用。

IK分词器安装
  • 下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases
  • 下载6.5.2版\elasticsearch\elasticsearch-analysis-ik- 6.5.2.zip
  • 先将其解压,将解压后的elasticsearch文件夹重命名文件夹为ik
  • 将ik文件夹拷贝到elasticsearch/plugins 目录下。
  • 重新启动,即可加载IK分词器
    IK提供了两个分词算法ik_smart 和 ik_max_word
    • 其中 ik_smart 为最少切分,ik_max_word为最细粒度划分
      • 最小切分:使用postman测试 post方式提交 http://127.0.0.1:9200/testindex/_analyze提交:{“analyzer”: “ik_smart”, “text”: “超级程序员” }
        • 返回结果:
          在这里插入图片描述
    • 最细切分:使用postman测试 post方式提交 http://127.0.0.1:9200/testindex/_analyze 提交: {{“analyzer”: “ik_max_word”, “text”: “超级程序员” }
      • 返回结果为:
        在这里插入图片描述
自定义词库
  • 进入elasticsearch/plugins/ik/config目录
  • 新建一个my.dic文件,添加你想要分词的词语或短语
  • 修改IKAnalyzer.cfg.xml(在ik/config目录下)
    在这里插入图片描述
    当输入你自定义的字符串时ik分词器就会按照你的配置进行分词

Kibana

Kibana简介

  • Kibana 是一个开源的分析和可视化平台,旨在与 Elasticsearch 合作。Kibana 提供 搜索、查看和与存储在 Elasticsearch 索引中的数据进行交互的功能。开发者或运维人员 可以轻松地执行高级数据分析,并在各种图表、表格和地图中可视化数据。
  • 如果Kibana远程连接Elasticsearch ,可以修改config\kibana.yml
    • 执行bin\kibana.bat
    • 打开浏览器,键入http://localhost:5601 访问Kibana
    • 我们这里使用Kibana进行索引操作,Kibana与Postman相比省略了服务地址,并且有语 法提示,非常便捷。
      创建索引与映射字段

在这里插入图片描述

  • 类型名称:就是前面将的type的概念,类似于数据库中的不同表 字段名:任意填写,可以指定许多属性,例如:
    • type:类型,可以是text、long、short、date、integer、object等
    • index:是否索引,默认为true
    • store:是否单独存储,默认为false ,一般内容比较多的字段设置成true,可提 升查询性能
    • analyzer:分词器
      创建索引结构:
      静态映射方式:
      在这里插入图片描述

文档增加与修改

增加文档自动生成ID

  • 通过POST请求,可以向一个已经存在的索引库中添加数据
    语法:
POST 索引库名/类型名
{
“key”:“value”
}

实例:
在这里插入图片描述

  • 响应结果:

在这里插入图片描述
查询命令:

  • GET 索引库名/_search
    实例:
    GET sku/_search
    在这里插入图片描述
    ** 新增文档指定ID**
    语法:
PUT /索引库名/类型/id值
{
。。。。。。。。
}

实例:
在这里插入图片描述

索引查询
  • 基本语法
GET /索引库名/_search 
{ 
	"query":{ 
		"查询类型":{ 
			"查询条件":"查询条件值" 
		}
	}
}

这里的query代表一个查询对象,里面可以有不同的查询属性

  • 查询类型:
    • 例如:match_all, match, term, range 等等
  • 查询条件:查询条件会根据类型的不同,写法也有差异
查询所有(match_all)

实例:
在这里插入图片描述

  • took:查询花费时间,单位是毫秒
  • time_out:是否超时
  • _shards:分片信息
  • hits:搜索结果总览对象
  • total:搜索到的总条数
  • max_score:所有结果中文档得分的最高分
  • hits:搜索结果的文档对象数组,每个元素是一条搜索到的文档信息
  • _index:索引库
  • _type:文档类型
  • _id:文档id
  • _score:文档得分
  • _source:文档的源数据
    实例:
    在这里插入图片描述
匹配查询(match)

示例:查询名称包含手机的记录
在这里插入图片描述
这样查询他会先进行分词;即:小米;手机 so:名字包含这两个的都会被查询出来
如何避免?
在这里插入图片描述
这样只会查询出包含“小米电视”的结果

多字段查询(multi_match)

multi_match 与 match类似,不同的是它可以在多个字段中查询
实例:
在这里插入图片描述

  • 这样会查询出:名字or品牌or分类包含“小米”的文档源数据
词条匹配(term)

term查询被用于精确值 匹配,这些精确值可能是数字、时间、布尔或者那些未分词的字 符串
实例:

  • 查询价格为1000的文档源数据
    在这里插入图片描述
多词条匹配(terms)

terms 查询和 term 查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定 值中的任何一个值,那么这个文档满足条件
实例:

  • 查询价格为:1000、2000、3000的文档源数据
    在这里插入图片描述
布尔组合(bool)

bool 把各种其它查询通过 must (与)、 must_not (非)、 should (或)的方式进行 组合
示例:查询名称包含手机的,并且品牌为小米的文档源数据
在这里插入图片描述
示例:查询名称包含手机的,或者品牌为小米的。
在这里插入图片描述

过滤查询

过滤是针对搜索的结果进行过滤,过滤器主要判断的是文档是否匹配,不去计算和 判断文档的匹配度得分,所以过滤器性能比查询要高,且方便缓存,推荐尽量使用过滤 器去实现查询或者过滤器和查询共同使用。
示例:过滤品牌为小米的记录:
在这里插入图片描述

分组查询

示例:按分组名称聚合查询,统计每个分组的数量在这里插入图片描述
size为0 不会将数据查询出来,目的是让查询更快。

我们也可以一次查询两种分组统计结果:
在这里插入图片描述

JavaRest 高级客户端入门

elasticsearch 存在三种Java客户端。

  1. Transport Client
  2. Java Low Level Rest Client(低级rest客户端)
  3. Java High Level REST Client(高级rest客户端)
    这三者的区别是:
  • TransportClient没有使用RESTful风格的接口,而是二进制的方式传输数据
  • ES官方推出了Java Low Level REST Client,它支持RESTful。
    • 但是缺点是因为 TransportClient的使用者把代码迁移到Low Level REST Client的工作量比较大。
  • ES官方推出Java High Level REST Client,它是基于Java Low Level REST Client的封 装,并且API接收参数和返回值和TransportClient是一样的,使得代码迁移变得容易 并且支持了RESTful的风格,兼容了这两种客户端的优点。强烈建议ES5及其以后的 版本使用Java High Level REST Client
    准备工作:引入依赖
    在这里插入图片描述
快速入门
新增和修改数据

插入单条数据:

  • HttpHost : url地址封装
  • RestClientBuilder: rest客户端构建器
  • RestHighLevelClient: rest高级客户端
  • IndexRequest: 新增或修改请求
  • IndexResponse:新增或修改的响应结果
//1.连接rest接口 
HttpHost http=new HttpHost("127.0.0.1",9200,"http"); 
RestClientBuilder builder= RestClient.builder(http);
//rest构建器 
RestHighLevelClient restHighLevelClient=new RestHighLevelClient(builder);//高级客户端对象 
//2.封装请求对象 
IndexRequest indexRequest=new IndexRequest("sku","doc","3"); 
Map skuMap =new HashMap(); 
skuMap.put("name","华为p30pro"); 
skuMap.put("brandName","华为"); 
skuMap.put("categoryName","手机"); 
skuMap.put("price",1010221); 
skuMap.put("createTime","2019‐05‐01"); 
skuMap.put("saleNum",101021); 
skuMap.put("commentNum",10102321); 
Map spec=new HashMap(); 
spec.put("网络制式","移动4G"); 
spec.put("屏幕尺寸","5"); 
skuMap.put("spec",spec); 
indexRequest.source(skuMap); 
//3.获取响应结果 
IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT); 
int status = response.status().getStatus(); 
System.out.println(status); 
restHighLevelClient.close();

如果ID不存在则新增,如果ID存在则修改。
批处理请求:
BulkRequest: 批量请求(用于增删改操作)
BulkResponse:批量请求(用于增删改操作)

//1.连接rest接口 
HttpHost http=new HttpHost("127.0.0.1",9200,"http"); 
RestClientBuilder builder= RestClient.builder(http);
//rest构建器 
RestHighLevelClient restHighLevelClient=new RestHighLevelClient(builder);//高级客户端对象 
//2.封装请求对象 
BulkRequest bulkRequest=new BulkRequest(); 
IndexRequest indexRequest=new IndexRequest("sku","doc","4"); 
Map skuMap =new HashMap(); 
skuMap.put("name","华为p30pro 火爆上市"); 
skuMap.put("brandName","华为"); 
skuMap.put("categoryName","手机"); 
skuMap.put("price",1010221); 
skuMap.put("createTime","2019‐05‐01"); 
skuMap.put("saleNum",101021); 
skuMap.put("commentNum",10102321); 
Map spec=new HashMap(); 
spec.put("网络制式","移动4G"); 
spec.put("屏幕尺寸","5"); 
skuMap.put("spec",spec); 
indexRequest.source(skuMap); 
bulkRequest.add(indexRequest);//可以多次添加 
//3.获取响应结果 
BulkResponse response = restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT); 
int status = response.status().getStatus(); 
System.out.println(status); 
String message = response.buildFailureMessage(); System.out.println(message); 
restHighLevelClient.close();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值