ElasticSearch

1 docker安装ElasticSearch

# 下载镜像
docker pull elasticsearch:5.6.8
# 创建并启动容器
docker run -di --name=docker_elasticsearch -p 9200:9200 -p 9300:9300 elasticsearch:5.6.8

因云服务器内存太小,无法启动docker上的elastic,此处将不再进行下去

2 windows安装ElasticSearch

  • 解压安装包如下


    elasticSearch-windows.png
  • config目录下有elasticsearch.yml配置文件,可在里面修改配置,其基本配置如下

# 集群名称
cluster.name: my-application
# 当前节点名称
node.name: node-1
# 数据存放路径,默认是在ES安装目录下的data
#path.data: /path/to/data
# 日志存放路径,默认是在ES安装目录下的logs
#path.logs: /path/to/logs
# 绑定地址 默认是本机 localhost ,如果需要允许其他机器访问,可以设置为本机IP或者 0.0.0.0
#network.host: 192.168.0.1
# ES的HTTP连接地址,默认9200
#http.port: 9200
  • 修改完成后,可双击bin目录下的elasticsearch.bat启动
  • 访问本机:9200看到以下页面即启动成功
    elasticSerach首次启动后访问.png

3 安装ik分词器

  • elasticSearch/plugin文件夹下创建ik文件夹
  • 解压elasticsearch-analysis-ik-6.2.4.zip
  • 将解压包下elasticsearch内所有文件复制到elasticSearch/plugin/ik
  • 重启elasticsearch

4 安装kibana

  • 解压安装包


    kibana.png
  • 修改配置文件config/kibana.yml
# Web界面访问地址
#server.port: 5601
# 配置ES地址
#elasticsearch.url: "http://localhost:9200"
  • 双击bin/kibana.bat启动
  • 访问http://127.0.0.1:5601/
    kibana首页.png
  • kibana测试
    在kibana左侧做到Dev Tools,输入请求命令,效果如下
POST _analyze
{
  "analyzer": "ik_max_word",
  "text": "我是中国人"
}
kibana测试.png

5 操作索引库

5.1 elastic概念

elasticSearch对比mysql

索引库(indices)---------------------------------Database 数据库
类型(type)----------------------------------Table 数据表
文档(Document)---------------------------------Row 行
字段(Field)--------------------------------Columns 列
映射配置(mappings)-------------------------------每个列的约束(类型、长度)

详细说明:

概念 说明
索引库 (indices) indices是index的复数,代表许多的索引
类型(type) 类型是模拟mysql中的table概念,一个索引库下可以有不同类型的索引,类似 数据库中的表概念。数据库表中有表结构,也就是表中每个字段的约束信息; 索引库的类型中对应表结构的叫做 映射(mapping) ,用来定义每个字段的约 束。
文档 (document) 存入索引库原始的数据。比如每一条商品信息,就是一个文档
字段(field) 文档中的属性
映射配置 (mappings) 字段的数据类型、属性、是否索引、是否存储等特性

5.2 操作索引库

  • 创建索引库,可指定参数,也可不指定,7之前默认5个分片
# 创建
PUT itheima1
{
  "settings": {
    "number_of_shards": 5
  }
}
创建索引库-1.png
  • 查看索引库
GET 索引库名 
GET itheima1
  • 删除索引库
DELETE 索引库名
DELETE itheima1

5.3 操作类型及映射

  • 创建映射关系
    语法
PUT 索引库名/_mapping/类型名称 
{
  "properties": {
    "字段名": {
      "type": "类型",
      "index": true,
      "store": true,
      "analyzer": "分词器"
    }
  }
}

类型名称:就是前面将的type的概念,类似于数据库中的表 字段名:任意填写,
在ES5.X版本中一个索引库中可以添加多个类型,相当于一个数据库添加多个表
在ES6.X版本中就不能通过REST请求在一个索引库中添加多个类型,但是从ES5.X升级到ES6.X的多个类型依旧可用
但是在ES7版本后,一个索引库只能有一个类型,为了兼容ES7,这里的类型最好设置为_doc

下面指定许多属性,例如:

  • type:类型,可以是text、long、short、date、integer、object等
  • index:是否索引,默认为true
  • store:是否存储,默认为false
  • analyzer:分词器,这里的 ik_max_word 即使用ik分词器

eg:

PUT itheima/_mapping/_doc
{
  "properties": {
    "title":{
      "type": "text",
      "analyzer": "ik_max_word"
    },
    "images":{
      "type": "keyword",
      "index": false
    },
    "price":{
      "type": "float"
    }
  }
}
  • 查看映射关系
# 查看索引库中所有映射关系
GET /索引库名/_mapping
# 查看索引库中指定映射关系
GET /索引库名/_mapping/映射名

5.4 创建索引库和类型

put 索引库名
{
  "settings": {
    "索引库属性名": "索引库属性值"
  },
  "mappings": {
    "类型名": {
      "properties": {
        "字段名": {
          "映射属性名": "映射属性值"
        }
      }
    }
  }
}

5.5 操作文档

  • 新增文档:向索引库中类型下新增数据,类比数据库下的一行数据
POST /索引库名/类型名
{
  "key": "value"
}
  • 查看文档
GET 索引库/类型/文档编码
根据编码查询文档.png
  • 新增文档并指定id
POST /索引库名/类型名/自己指定id
{
  "key": "value"
}
  • 更新文档(若原类型中有该id的文档则更新,没有则新增),默认为全量更新(原来3个属性都有值,更新时只传两个属性,那么第三个属性会被置空)
PUT 索引库名/类型名/_id
{
    "key":"value"
}
  • 删除文档
DELETE 索引库名/类型名/_id

5.6 查询

5.6.1 基本查询

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

这里query代表一个查询对象
查询类型:match_all,math,term,range等
查询条件:根据查询类型不同有较大的差异

5.6.1.1 查询所有match_all

  • 语法
GET 索引库名/_search
{
  "query": {
    "match_all": {}
  }
}
  • EG
GET itheima/_search
{
  "query": {
    "match_all": {}
  }
}
  • 查询结果
{
  "took": 3,  # 查询花费时间,单位ms
  "timed_out": false, 是否超时
  "_shards": {  分片信息
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {  搜索结果总览对象
    "total": 4, 搜索到的总条数
    "max_score": 1, 所有结果中文档得分的最高分
    "hits": [ 搜索结果文档对象数组,每个元素是一条搜索到的文档信息
      {
        "_index": "itheima", 索引库
        "_type": "_doc", 文档类型
        "_id": "FdfauXMB7B8ED9LAPGn6", 文档id
        "_score": 1, 文档得分
        "_source": { 文档源数据
          "title": "小米手机",
          "images": "http://image.leyou.com/12479122.jpg",
          "price": 2699
        }
      },
      {
        "_index": "itheima",
        "_type": "_doc",
        "_id": "1",
        "_score": 1,
        "_source": {
          "title": "华为手机",
          "images": "http://image.leyou.com/12479122.jpg",
          "price": 4799
        }
      },
      {
        "_index": "itheima",
        "_type": "_doc",
        "_id": "OANswXMBIeDNWb4_bSfG",
        "_score": 1,
        "_source": {
          "title": "小米电视4A",
          "images": "http://image.leyou.com/12479122.jpg",
          "price": 3899
        }
      },
      {
        "_index": "itheima",
        "_type": "_doc",
        "_id": "3",
        "_score": 1,
        "_source": {
          "title": "超大米手机",
          "images": "http://image.leyou.com/12479122.jpg",
          "price": 3299,
          "stock": 200,
          "saleable": true,
          "subTitle": "哈哈"
        }
      }
    ]
  }
}

5.6.1.2 匹配查询match

  • 语法
GET 索引库名/_search
{
  "query":{
    "match": {
      "条件": "条件值"
    }
  }
}
  • EG
GET itheima/_search
{
  "query":{
    "match": {
      "title": "小米"
    }
  }
}

场景:查询分词的属性
默认情况下,会对用户输入的条件值进行分词然后使用or连接来查询.如用户输入""小米手机",会查询出"小米"、"手机"、"小米手机"的数据.
如需精确查找可以指定使用and连接,如下

  • 条件值精确查找(类似不对用户输入分词)
# match指定指定对输入分词指定对输入分词使用连接
GET itheima/_search
{
  "query":{
    "match": {
      "title":
      {"query": "小米手机",
        "operator": "and"
      }
    }
  }
}

5.6.1.3 词条匹配term

  • 语法
GET 索引库名/_search
{
  "query":{
    "term": {
      "条件": "条件值"
    }
  }
}

-EG

GET itheima/_doc/_search
{
  "query":{
    "term": {
      "price": 2699
    }
  }
}

适用条件:查询被用于精确值 匹配,这些精确值可能是数字、时间、布尔或者那些未分词的字符串 ,一般是在keyword上进行查询
需注意如果term查询的条件字段为string类型的,若这个字段做了分词,可能会查询不到如下

# 因为title为text类型,且进行了分词,形成的索引有"小米","电视","小米电视",但是没有"小米电视4A",无法进行精确匹配.所以对于分词的字段建议使用match
GET itheima/_search
{
  "query": {
    "term": {
      "title": "小米电视4A"
    }
  }  
}

5.6.1.4 bool组合

  • 语法
must:多个查询条件完全匹配,相当于and
must_not:多个查询条件,必须完全不匹配,相当于not
should:多个查询条件做并集,相当于or
  • EG
GET itheima/_search
{
  "query": {
    "bool": {
      "must": {
        "match": {
          "title": "小米"
        }
      },
      "must_not": {
        "match": {
          "title": "电视"
        }
      }
    }
  }
}

GET itheima/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": "小米"
          }
        },
        {
          "match": {
            "title": "手机"
          }
        }
      ]
    }
  }
}

5.6.1.5 范围查询 range

range 查询找出那些落在指定区间内的数字或者时间

  • 语法
    range 可以使用一下参数:
操作符 说明
gte 大于等于
gt 大于
lte 小于等于
lt 小于
  • EG
#  1000<price<3000
GET itheima/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 1000,
        "lte": 3000
      }
    }
  }
}

5.6.1.6 模糊查询 fuzzy

  • 场景,但只允许偏差值为2


    elasticSearch_fuzzy.png
  • 语法
GET itheima/_search
{
  "query": {
    "fuzzy": {
      "title": "电视3"
    }
  }
}
elasticSearch_fuzzy_result.png

5.6.2 结果过滤

默认情况下,elasticsearch在搜索的结果中,会把文档中保存在 _source 的所有字段都返回。
如果我们只想获取其中的部分字段,我们可以添加 _source 的过滤

5.6.2.1 直接指定字段

-EG

GET itheima/_search
{
  "_source": [
    "title",
    "price"
  ],
  "query": {
    "match": {
      "title": "小米"
    }
  }
}

5.6.2.2 指定include和exclude

  • EG
# include
GET itheima/_search
{
  "_source": {
    "includes": ["title","images"]
  },
  "query": {
    "match": {
      "title": "小米"
    }
  }
}
# exclude
GET itheima/_search
{
  "_source": {
    "excludes": "images"
  },
  "query": {
    "match": {
      "title": "小米"
    }
  }
}

5.6.3 filter过滤

注意过滤的字段不能分词,只能是keyword或数值类型

  • eg:只能放在bool里,其他的查询都会对查询的结果评分造成影响,而filter不会
GET itheima/_search
{
  "query": {
    "bool": {
      "filter": {
        "range": {
          "price": {
            "gte": 1000,
            "lte": 5000
          }
        }
      }
    }
  }
}

5.6.4 排序

5.6.4.1 单字段排序

  • EG
GET itheima/_search
{
  "query": {
    "match": {
      "title": "小米"
    }
  },
  "sort": [
    {
      "price": {
        "order": "asc"
      }
    }
  ]
}

5.6.4.2 多字段排序

GET itheima/_search
{
  "query": {
    "match": {
      "title": "手机"
    }
  },
  "sort": [
    {
      "price": {
        "order": "asc"
      }
    },{
      "_score":{
        "order": "desc"
      }
    }
  ]
}

5.6.5 分页

-EG

GET itheima/_search
{
  "query": {
    "match": {
      "title": "手机"
    }
  },
  "sort": [
    {
      "price": {
        "order": "asc"
      }
    }
  ],
  "from": 2, 开始位置(并非开始页)
  "size": 2 每页大小
}

5.6.6 高亮

  • 高亮原理:搜索结果中关键字加上约定好的标签
GET itheima/_search
{
  "query": {
    "match": {
      "title": "手机"
    }
  },
  "highlight": {
    "pre_tags": "<em>",
    "post_tags": "</em>",
    "fields": {
      "title": {}
    }
  }
}
elasticSearch-highlight.png

5.7 聚合aggregations

聚合可以让我们极其方便的实现对数据的统计、分析。例如:

  • 什么品牌的手机最受欢迎?
  • 这些手机的平均价格、最高价格、最低价格?
  • 这些手机每月的销售情况如何?

实现这些统计功能的比数据库的sql要方便的多,而且查询速度非常快,可以实现近实时搜索效果。

5.7.1 聚合的基本概念

桶(bucket) 类似于 group by

桶的作用,是按照某种方式对数据进行分组,每一组数据在ES中称为一个 桶 ,
例如我们根据国籍对人划分,可以得到 中国桶 、 英国桶 , 日本桶
或者我们按照年龄段对人进行划分:010,1020,2030,3040等。
Elasticsearch中提供的划分桶的方式有很多:

  • Date Histogram Aggregation:根据日期阶梯分组,例如给定阶梯为周,会自动每周分为一组
  • Histogram Aggregation:根据数值阶梯分组,与日期类似,需要知道分组的间隔(interval)
  • Terms Aggregation:根据词条内容分组,词条内容完全匹配的为一组
  • Range Aggregation:数值和日期的范围分组,指定开始和结束,然后按段分组

综上所述,我们发现bucket aggregations 只负责对数据进行分组,并不进行计算,因此往往bucket中
往往会嵌套另一种聚合:metrics aggregations即度量

度量(metrics) 相当于聚合的结果

分组完成以后,我们一般会对组中的数据进行聚合运算,例如求平均值、最大、最小、求和等,这些在
ES中称为 度量
比较常用的一些度量聚合方式:

  • Avg Aggregation:求平均值
  • Max Aggregation:求最大值
  • Min Aggregation:求最小值
  • Percentiles Aggregation:求百分比
  • Stats Aggregation:同时返回avg、max、min、sum、count等
  • Sum Aggregation:求和
  • Top hits Aggregation:求前几
  • Value Count Aggregation:求总数

5.7.2 测试

添加测试数据

PUT car
{
  "mappings": {
    "orders": {
      "properties": {
        "color": {
          "type": "keyword"
        },
        "make": {
          "type": "keyword"
        }
      }
    }
  }
}

POST car/orders/_bulk
{"index":{}}
{"price":10000,"color":"红","make":"本田","sold":"2014-10-28"}
{"index":{}}
{"price":20000,"color":"红","make":"本田","sold":"2014-11-05"}
{"index":{}}
{"price":30000,"color":"绿","make":"福特","sold":"2014-05-18"}
{"index":{}}
{"price":15000,"color":"蓝","make":"丰田","sold":"2014-07-02"}
{"index":{}}
{"price":12000,"color":"绿","make":"丰田","sold":"2014-08-19"}
{"index":{}}
{"price":20000,"color":"红","make":"本田","sold":"2014-11-05"}
{"index":{}}
{"price":80000,"color":"红","make":"宝马","sold":"2014-01-01"}
{"index":{}}
{"price":25000,"color":"蓝","make":"福特","sold":"2014-02-12"}

5.7.2.1 聚合为桶

  • 按照颜色聚合为bucket
GET car/_search
{
  "size": 0, //设置为0,不显示原文档,只显示聚合结果
  "aggs": {
    "popular_colors": {
      "terms": {
        "field": "color"
      }
    }
  }
}

查询参数说明:
size: 查询条数,这里设置为0,因为我们不关心搜索到的数据,只关心聚合结果,提高效率
aggs:声明这是一个聚合查询,是aggregations的缩写
popular_colors:给这次聚合起一个名字,可任意指定。
terms:聚合的类型,这里选择terms,是根据词条内容(这里是颜色)划分
field:划分桶时依赖的字段

elasticSearch-aggegation-result.png

查询结果参数说明:
hits:查询结果为空,因为我们设置了size为0
aggregations:聚合的结果
popular_colors:我们定义的聚合名称
buckets:查找到的桶,每个不同的color字段值都会形成一个桶
key:这个桶对应的color字段的值
doc_count:这个桶中的文档数量

5.7.2.2 度量

前面的例子告诉我们每个桶里面的文档数量,这很有用。 但通常,我们的应用需要提供更复杂的文档度量。 例如,每种颜色汽车的平均价格是多少?因此,我们需要告诉Elasticsearch使用哪个字段 ,使用何种度量方式 进行运算,这些信息要嵌套在 桶内,度量的运算会基于桶内的文档进行 .

GET car/_search
{
  "size": 0,
  "aggs": {
    "popular_colors": {
      "terms": {
        "field": "color"
      },
      "aggs": {
        "avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    }
  }
}

参数说明:
aggs:我们在上一个aggs(popular_colors)内添加新的aggs。可见度量也是一个聚合
avg_price:聚合的名称
avg:度量的类型,这里是求平均值
field:度量运算的字段

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,063评论 6 510
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,805评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,403评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,110评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,130评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,877评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,533评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,429评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,947评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,078评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,204评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,894评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,546评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,086评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,195评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,519评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,198评论 2 357

推荐阅读更多精彩内容