ElasticSearch基础
1、什么是ElasticSearch?
- 概念
ElasticSearch是面向文档型数据库,一条数据在这里就是一个文档,用JSON作为文档序列化的格式;基于Lucene的搜索服务器。他提供了一个分布式的全文搜索引擎和数据分析引擎,能够实现全文检索,结构化检索,数据分析,对海量数据进行近实时处理,安装使用方便,本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据
- 特征特点
- 天然分片、天然集群:es把数据分成多个shard,这些shard可以分布在集群中的各个机器节点中。随着数据的不断增加,集群可以增加多个分片,把多个分片放到多个机子上,以达到负载均衡,横向扩展
- 天然索引:ES所有的数据都是默认进行索引的,这点和mysql正好相反,mysql是默认不加索引,要加索引必须特别说明,ES只有不加索引才需要说明,而ES使用的是倒排索引和Mysql的B+Tree索引
不同
- 应用场景
1、场景一:使用ElasticSearch作为主要的后端
传统项目中,搜索引擎是部署在成熟的数据存储的顶部,以提供快速且相关的搜索能力
2、场景二:在现有系统中增加ElasticSearch
由于ElasticSearch不能提供存储的所有功能,一些场景下需要在现有系统数据存储的基础上支持Es支持 *
3、场景三:使用ElasticSearch和现有的工具
在一些使用情况下,您不必写一行代码就能通过ElasticSearch完成一项工作。很多工具都可以与ElasticSearch一起工作,所以你不必到你从头开始编写
2、ElasticSearch的数据类型
如果自己的文档字段没有指定,那么es就会给我们默认配置字段类型
- 字符串类型
1、string类型: 在ElasticSearch 旧版本中使用较多,从ElasticSearch5.x开始不再支持string,由text和keyword类型替代。
2、text 类型:当一个字段是要被全文搜索的,比如Email内容、产品描述,应该使用text类型。设置text类型以后,字段内容会被分析,在生成倒排索引以前,字符串会被分析器分成一个一个词项。text类型的字段不用于排序,很少用于聚合。
3、keyword类型:keyword类型适用于索引结构化的字段,比如email地址、主机名、状态码和标签。如果字段需要进行过滤(比如查找已发布博客中status属性为published的文章)、排序、聚合。keyword类型的字段只能通过精确值搜索到。
- 整数类型
1、byte - 取值范围:-127~127
2、short - 取值范围 : -32768~32767
3、integer - 取值范围 : -231~230
4、short - 取值范围:-263~262
- 浮点类型
1、doubledoule 64位双精度IEEE 754浮点类型
2、float 32位单精度IEEE754浮点类型
3、half_float 16位半精度IEEE 754浮点类型
4、scaled_float 缩放类型的的浮点数
- 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类型
1、字符数组: [ “one”, “two” ]
2、整数数组: productid:[ 1, 2 ]
3、对象(文档)数组: “user”:[ { “name”: “Mary”, “age”: 12 }, { “name”: “John”, “age”: 10 }],
注意:lasticSearch不支持元素为多个数据类型:[ 10, “some string” ]
- object类型
JSON对象,文档会包含嵌套的对象
- ip类型
ip类型的字段用于存储IPv4或者IPv6的地址
3、ElasticSearch的关于索引的基本操作
- PUT:创建文档(指定文档id)
语法:
- 创建索引插入数据
PUT /索引名/~类型名~/文档id
{请求体}
PUT /test1/type1/1
{
"name":"zyf"
"age":3
}
- 创建索引添加约束(创建规则)
PUT /test2
{
"mappings":{
"properties":{
"name":{
"type":"text"
},
"age":{
"type":"long"
},
"birthday":{
"type":"date"
}
}
}
}
- POST:
- 创建文档(随机文档id)
- /_update:修改文档
- 推荐使用POST 后加/_update 来修改文档
POST /test3/_doc/1/_update
{
"doc":{ //固定值doc,说明你要修改哪些文档
"name":"213"
}
}
- 不推荐使用PUT命令,直接覆盖,若覆盖数据缺少会导致原始数据丢失
- /_search:查询所有数据
- DELETE:删除文档
语法
- 直接删除对应的库即可
DELETE test1(/...) //(根据你的请求来判断是删除索引还是删除文档记录)
- GET:查询文档根据文档id
语法:
- 获得规则(test2后写到表得到表的信息,写到文档得到文档的信息)
GET test2(/...)
- 查看集群健康信息
GET _cat/health
- 查看版本信息(通过_cat命令可以获得ElasticSearch的当前的很多信息)
GET _cat/indices?v
使用GET /index/_search和POST /index/_search 的区别?
post可以带body,get不能带body,post一般用于提交数据,get是获取数据,这是http协议的内容,rest是基于http的,所以在你用get时,你的body写了也没啥用,都被忽略了,而使用post的话,es会把你的数据上传到索引里。
4、ElasticSearch的关于文档的基本操作
- 添加数据
PUT /zyf/user/1
{
"name":"zyf",
"age":23,
"desc":"没有伞的孩子,必须努力奔跑!"
"tags":["高端","大气","上档次"]
}
- 获取数据GET
GET zyf/user/1
- 更新数据
- PUT(不建议使用,put如果不传递值,就会被覆盖)
PUT /zyf/user/1
{
"name":"test",
"age":23,
"desc":"没有伞的孩子,必须努力奔跑!"
"tags":["高端","大气","上档次"]
}
- POST _update(推荐使用这种方式,灵活性更好!)
POST /zyf/user/1/_update
{
"doc":{
"name":"111"
}
}
- 搜索
- 简单的搜索
GET zyf/user/1
- 简单的条件查询(可以根据默认的映射规则,产生基本的查询!)
GET zyf/user/1/_search?q=name:zyf
- 复杂操作搜索 select(排序,分页,高亮,模糊查询,精准查询!)
语法
GET 247_2018_xiaomi/_search
{
"query": {
"match": {
"rootCategoryName": "小米圈铁耳机"
}
}
}
返回结果中有一个_score属性,意思就是查询结果的匹配度,我们可以通过score判断谁更加符合结果;hits索引和文档的信息,查询的结果总数,然后就是查询出来的具体的文档,数据中的东西都可以遍历出来
- _source:结果过滤
GET 247_2018_xiaomi/_search
{
"query": {
"match": {
"rootCategoryName": "小米圈铁耳机"
}
},
"_source":["name","desc"]
}
- sort排序
GET 247_2018_xiaomi/_search
{
"query": {
"match": {
"rootCategoryName": "小米圈铁耳机"
}
},
"_source":["name","desc"]
"sort":[ // sort代表排序
"age":{ // 要排序的属性
"order":"asc" //order表示是降序还是升序
}
]
}
- from分页
GET 247_2018_xiaomi/_search
{
"query": {
"match": {
"rootCategoryName": "小米圈铁耳机"
}
}
"_source":["name","desc"]
"sort":[ // sort代表排序
"age":{ // 要排序的属性
"order":"asc" //order表示是降序还是升序
}
],
"from":0, // 从第几个数据开始
"size":20 // 返回多少条数据(单页面的数据)
}
- 多条件查询语法
GET 247_2018_xiaomi/_search
{
"query": {
"bool":{
"must":[ // 使用must来多条件精确匹配,所有的条件都要复合,相当于 and
{
"match""{
"name":"zyf"
}
},
{
"match":{
"age":23
}
}
]
}
}
}
GET 247_2018_xiaomi/_search
{
"query": {
"bool":{
"should":[ // 使用should来多条件精确匹配,两个条件满足其一即可,相当于 or
{
"match""{
"name":"zyf"
}
},
{
"match":{
"age":23
}
}
]
}
}
}
GET 247_2018_xiaomi/_search
{
"query": {
"bool":{
"must_not":[ // 使用must_not来多条件精确匹配,查询不符合条件的属性,相当于 not
{
"match""{
"name":"zyf"
}
},
{
"match":{
"age":23
}
}
]
}
}
}
- 过滤器
GET 247_2018_xiaomi/_search
{
"query": {
"bool":{
"must":[
{
"match""{
"name":"zyf"
}
}
],
"filter":{ // 可以使用filter进行数据过滤
"range":{ // 表示拦截的范围
"age":{ // 要拦截的属性值
"gte":1 // gt大于,lt小于,gte大于等于,lte小于等于,eq等于,ne、neq不等于
"lte":25 //可以使用多条件过滤,也是没有问题的
}
}
}
}
}
}
- 匹配多个条件
GET 247_2018_xiaomi/_search
{
"query": {
"match": {
"tags": "小米 圈铁 耳机" // 多个条件使用空格隔开,只要满足其中一个结果即可以被查出,这个时候可以通过分值基本的判断
}
}
}
- 精确查询(term查询是直接通过倒排索引指定的词条进程精确查找的!关于分词:term,直接查询精确的;match,会使用分词器解析!先分析文档,然后在通过分析的文档进行查询)
GET 247_2018_xiaomi/_search
{
"query": {
"term": {
"tags": "小米 圈铁 耳机" // keyword类型不会被分词器解析
}
}
}
- 两个类型text和keyword
- keyword不可以被拆分,standard可以被拆分
- 多个值精确匹配
GET 247_2018_xiaomi/_search
{
"query": {
"bool":{
"should":[ // 使用should来多条件精确匹配,两个条件满足其一即可,相当于 or
{
"match""{
"name":"zyf"
}
},
{
"match":{
"age":23
}
}
]
}
}
}
- 高亮查询
GET 247_2018_xiaomi/_search
{
"query": {
"match": {
"tags": "小米 圈铁 耳机"
}
},
"highlight":{
"pre_tags":"<p class='key' style='color:red'>", // 自定义搜索高亮条件,前缀
"post_tags":"</p>", // 后缀
"fields":{ // 搜索相关的结果可以高亮显示
"name":{}
}
}
}
- 聚合aggs
GET 247_2018_xiaomi/_search
{
"size" : 0, // 设置size=0的意思就是,仅返回聚合查询结果,不返回普通query查询结果。
"aggs" : { // 聚合查询语句的简写
"popular_colors" : { // 给聚合查询取个名字,叫popular_colors
"terms" : {// 聚合类型为,terms,terms是桶聚合的一种,类似SQL的group by的作用,根据字段分组,相同字段值的文档分为一组。 "field" : "color" // terms聚合类型的参数,这里需要设置分组的字段为color,根据color分组
}
}
}
}
GET 247_2018_xiaomi/_search
{
"hits": { // 因为size=0,所以query查询结果为空
"hits": []
},
"aggregations": { // 聚合查询结果
"popular_colors": { // 这个就是popular_colors聚合查询的结果,这就是为什么需要给聚合查询取个名字的原因,如果有多个聚合查询,可以通过名字查找结果
"buckets": [ // 因为是桶聚合,所以看到返回一个buckets数组,代表分组的统计情况,下面可以看到每一种颜色的销量情况
{
"key": "red",
"doc_count": 4 // 红色的汽车销量为4
},
{
"key": "blue",
"doc_count": 2
},
{
"key": "green",
"doc_count": 2
}
]
}
}
}