这里写自定义目录标题
一、环境搭配
分别下载:ElasticSearch、kibana、elasticsearch-head-master
- ElasticSearch:
下载地址:https://www.elastic.co/cn/downloads/
历史版本下载:https://www.elastic.co/cn/downloads/past-releases/
在这里插入代码片
- kibana:
1.下载地址:https://www.elastic.co/cn/downloads/
2.历史版本下载:https://www.elastic.co/cn/downloads/past-releases/
汉化:编辑打开kibana解压目录/config/kibana.yml,添加
i18n.locale: "zh-CN"
- elasticsearch-head-master:
1.下载地址:https://github.com/mobz/elasticsearch-head
2.启动:cd elasticsearch-head
#安装依赖
npm install
#启动
npm run start
#访问
localhost:9100
二、ElasticSearch核心概念
概述
1.索引
- 包含多个分片
2.字段类型(映射)
- 字段类型映射(字段是整型,还是字符串。。。)
3.文档
4.分片(Luncene索引、倒排索引)
ElasticSearch是面向文档,关系行数据库和ElasticSearch客观对比!一切都是JSON!
关系型数据库 | ElasticSearch |
---|---|
数据库(database | 索引(indices) |
表(table) | types |
行(rows) | documents |
字段(columns) | fields |
elasticsearch(集群)中可以包含多个索引(数据库) ,
每个索引中可以包含多个类型(表) ,每个类型下又包含多个文档(行) ,
每个文档中又包含多个字段(列)。
三、Rest风格
method | url地址 | 描述 |
---|---|---|
PUT (创建、修改) | localhost:9200/索引名称/类型名称/文档id | 随机文档id) |
POST(创建) | localhost:9200/索引名称/类型名称 | 创建文档(随机文档id) |
POST(修改) | localhost:9200/索引名称/类型名称/文档id/_update | 修改文档 |
DELETE(删除) | localhost:9200/索引名称/类型名称/文档id | 删除文档 |
GET(查询) | localhost:9200/索引名称/类型名称/文档id | 查询文档通过文档ID |
POST(查询) | localhost:9200/索引名称/类型名称/文档id/_search | 查询所有数据 |
四、索引操作
数据库结构和ElasticSearch关系对比
public class Movie {
String id;
String name;
Double doubanScore;
List<Actor> actorList;
}
public class Actor{
String id;
String name;
}
这两个对象如果放在关系型数据库保存,会被拆成2张表,但是elasticsearch是用一个json来表示一个document
{
“id”:”1”,
“name”:”operation red sea”,
“doubanScore”:”8.5”,
“actorList”:[
{“id”:”1”,”name”:”zhangyi”},
{“id”:”2”,”name”:”haiqing”},
{“id”:”3”,”name”:”zhanghanyu”}
]
}
1.查询索引
GET /_cat/indices?v
表头含义
字段名 | 含义说明 |
---|---|
health | green(集群完整) yellow(单点正常、集群不完整) red(单点不正常) |
status | 是否能使用 |
index | 索引名字 |
UUID | 索引统一编号 |
pri | 主节点有几个 |
rep | 从节点有几个 |
docs.count | 文档数 |
ocs.deleted | 文档被删了多少 |
store.size | 整体占空间大小 |
i.store.size | 主节点占空间大小 |
2.创建索引
语法
PUT /index(索引名)
PUT test
{
"settings": {
"number_of_shards": 5
, "number_of_replicas": 1
}
}
3.查看索引具体信息
语法
GET /index(索引名)
如GET /test
结果:
{
"test" : {
"aliases" : { },
"mappings" : { },
"settings" : {
"index" : {
"creation_date" : "1578479474178",
"number_of_shards" : "5",
"number_of_replicas" : "1",
"uuid" : "yRNcgHe8SWmPO83_AF7k6Q",
"version" : {
"created" : "6080199"
},
"provided_name" : "test"
}
}
}
}
4.删除索引
DELETE /index(索引名)
五、映射配置
1.创建映射字段
- 语法:
PUT /索引库名/_mapping/类型名称
{
"properties": {
"字段名": {
"type": "类型",
"index": true,
"store": true,
"analyzer": "分词器"
}
}
}
-
类型名称:就是前讲的type的概念,类似于数据库中的不同表
-
字段名:类似于列名,properties下可以指定许多字段。
每个字段可以有很多属性。例如: type:类型,可以是text、long、short、date、integer、object等 index:是否索引,默认为true store:是否存储,默认为false analyzer:分词器,这里使用ik分词器:ik_max_word或者ik_smart
示例:
PUT test/_mapping/goods
{
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word"
},
"images": {
"type": "keyword",
"index": "false"
},
"price": {
"type": "long"
}
}
}
2.查看映射关系
语法:
GET /索引库名/_mapping
示例:
GET /test/_mapping
结果:
{
"test" : {
"mappings" : {
"goods" : {
"properties" : {
"images" : {
"type" : "keyword",
"index" : false
},
"price" : {
"type" : "long"
},
"title" : {
"type" : "text",
"analyzer" : "ik_max_word"
}
}
}
}
}
}
3.字段属性详解
type:
-
-
String类型:分两种
-
text:可分词,不能参与聚合
keyword:不可分词,数据会作为完整字段进行匹配,可以参与聚合
-
text:可分词,不能参与聚合
-
-
Numerical:数值类型,分两种
-
基本数据类型:long、interger、short、byte、double、float、half_float
浮点数的高精度类型:scaled_float
需要指定一个精度因子,比如10或100。elasticsearch会把真实值乘以这个因子后存储,取出时再还原
-
基本数据类型:long、interger、short、byte、double、float、half_float
-
-
Date:日期类型
- elasticsearch可以对日期格式化为字符串存储,但是建议我们存储为毫秒值,存储为long,节省空间。
六、新增文档(document、相当于数据库中的行)
1.自动生成id
- 语法:
POST /索引库名/类型名
{
"key":"value"
}
- 示例:
POST /test/goods
{
"title": "华为手机",
"images": "http://image.jd.com/12479122.jpg",
"price": 4288
}
- 结果:
{
"_index" : "test",
"_type" : "goods",
"_id" : "BsfnhG8By16f6dCmPuVN",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
2.自定义id
- 语法:
POST /索引库名/类型/id值
{
"key":"value"
}
- 示例:
POST /test/goods/1
{
"title": "华为手机",
"images": "http://image.jd.com/12479122.jpg",
"price": 5288
}
- 结果:
{
"took" : 4,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 1.0,
"hits" : [
{
"_index" : "test",
"_type" : "goods",
"_id" : "BsfnhG8By16f6dCmPuVN",
"_score" : 1.0,
"_source" : {
"title" : "华为手机",
"images" : "http://image.jd.com/12479122.jpg",
"price" : 4288
}
},
{
"_index" : "test",
"_type" : "goods",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"title" : "华为手机",
"images" : "http://image.jd.com/12479122.jpg",
"price" : 5288
}
}
]
}
}
3.智能判断
- 添加一条数据
POST /test/goods/2
{
"title":"小米手机",
"images":"http://image.jd.com/12479122.jpg",
"price":2899,
"stock": 200,
"saleable":true,
"attr": {
"category": "手机",
"brand": "小米"
}
}
- 查询一下结果
GET /test/goods/2
{
"_index" : "test",
"_type" : "goods",
"_id" : "2",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"title" : "小米手机",
"images" : "http://image.jd.com/12479122.jpg",
"price" : 2899,
"stock" : 200,
"saleable" : true,
"attr" : {
"category" : "手机",
"brand" : "小米"
}
}
}
七、修改数据
-
-
1.整体覆盖
-
必须指定id
- id对应文档存在,则修改
- id对应文档不存在,则新增
- 可以使用POST、PUT
-
必须指定id
PUT /test/goods/2
{
"title":"小米手机",
"images":"http://image.jd.com/12479122.jpg",
"price":2899,
"stock": 200,
"saleable":true,
"attr": {
"category": "手机",
"brand": "大米"
}
}
结果:
{
"_index" : "test",
"_type" : "goods",
"_id" : "2",
"_version" : 6,
"_seq_no" : 5,
"_primary_term" : 1,
"found" : true,
"_source" : {
"title" : "小米手机",
"images" : "http://image.jd.com/12479122.jpg",
"price" : 2899,
"stock" : 200,
"saleable" : true,
"attr" : {
"category" : "手机",
"brand" : "大米"
}
}
}
- 2.更新字段
语法:
POST /{index}/{type}/{id}/_update
{
"doc": {
字段名: 字段值
}
}
示例:
POST /test/goods/2/_update
{
"doc": {
"price":1999
}
}
八、删除数据
语法:
```sql在这里插入代码片
DELETE /索引库名/类型名/id值
**示例:**
```sql
DELETE /atguigu/goods/3
九、查询*
1.简单查询
- 查询所有
GET /{index}/_search
- 根据id查询
GET /{index}/{type}/{id}
2.查询结果参数说明
took:查询花费时间,单位是毫秒
time_out:是否超时
_shards:分片信息
hits:搜索结果总览对象
total:搜索到的总条数
max_score:所有结果中文档得分的最高分
hits:搜索结果的文档对象数组,每个元素是一条搜索到的文档信息
_index:索引库
_type:文档类型
_id:文档id
_score:文档得分
_source:文档的源数据
- 数据准备
POST /test/goods/_bulk
{"index":{"_id":1}}
{ "title":"小米手机", "images":"http://image.jd.com/12479122.jpg", "price":1999, "stock": 200, "attr": { "category": "手机", "brand": "小米" } }
{"index":{"_id":2}}
{"title":"超米手机", "images":"http://image.jd.com/12479122.jpg", "price":2999, "stock": 300, "attr": { "category": "手机", "brand": "小米" } }
{"index":{"_id":3}}
{ "title":"小米电视", "images":"http://image.jd.com/12479122.jpg", "price":3999, "stock": 400, "attr": { "category": "电视", "brand": "小米" } }
{"index":{"_id":4}}
{ "title":"小米笔记本", "images":"http://image.jd.com/12479122.jpg", "price":4999, "stock": 200, "attr": { "category": "笔记本", "brand": "小米" } }
{"index":{"_id":5}}
{ "title":"华为手机", "images":"http://image.jd.com/12479122.jpg", "price":3999, "stock": 400, "attr": { "category": "手机", "brand": "华为" } }
{"index":{"_id":6}}
{ "title":"华为笔记本", "images":"http://image.jd.com/12479122.jpg", "price":5999, "stock": 200, "attr": { "category": "笔记本", "brand": "华为" } }
{"index":{"_id":7}}
{ "title":"荣耀手机", "images":"http://image.jd.com/12479122.jpg", "price":2999, "stock": 300, "attr": { "category": "手机", "brand": "华为" } }
{"index":{"_id":8}}
{ "title":"oppo手机", "images":"http://image.jd.com/12479122.jpg", "price":2799, "stock": 400, "attr": { "category": "手机", "brand": "oppo" } }
{"index":{"_id":9}}
{ "title":"vivo手机", "images":"http://image.jd.com/12479122.jpg", "price":2699, "stock": 300, "attr": { "category": "手机", "brand": "vivo" } }
{"index":{"_id":10}}
{ "title":"华为nova手机", "images":"http://image.jd.com/12479122.jpg", "price":2999, "stock": 300, "attr": { "category": "手机", "brand": "华为" } }
3.匹配查询(match)
- 匹配所有
GET /test/_search
{
"query":{
"match_all": {}
}
}
- 条件匹配
GET /test/_search
{
"query": {
"match": {
"title": "华为手机"
}
}
}
查询出很多数据,不仅包括小米手机,而且与小米或者手机相关的都会查询到,说明多个词之间是or的关系。
某些情况下,我们需要更精确查找,我们希望这个关系变成and,可以这样做
GET /test/_search
{
"query": {
"match": {
"title": {
"query": "华为手机",
"operator": "and"
}
}
}
}
- 子属性匹配
GET /test/_search
{
"query": {
"match": {
"attr.brand": "小米"
}
}
}
- 短句匹配
按短语查询,不再利用分词技术,直接用短语在原始数据中匹配
GET /test/_search
{
"query": {
"match_phrase": {
"title": "小米手机"
}
}
}
- 多字段匹配
match只能根据一个字段匹配查询,如果要根据多个字段匹配查询可以使用multi_match
GET /test/_search
{
"query": {
"multi_match": {
"query": "小米",
"fields": ["title","attr.brand"]
}
}
}
4.词条查询(term)
- 单词条查询
term查询被用于精确值 匹配,这些精确值可能是数字、时间、布尔或者那些未分词的字符串
GET /test/_search
{
"query": {
"term": {
"price": {
"value": "2999"
}
}
}
}
- 多词条查询
terms 查询和 term 查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件
GET /test/_search
{
"query": {
"terms": {
"price": [
"2999",
"3999"
]
}
}
}
5.范围查询(range)
range 查询找出那些落在指定区间内的数字或者时间
GET /test/_search
{
"query": {
"range": {
"price": {
"gte": 2000,
"lte": 4000
}
}
}
}
range查询允许以下字符:
操作符 | 说明 |
---|---|
gt | 大于 |
gte | 大于等于 |
lt | 小于 |
lte | 小于等于 |
6.模糊查询(fuzzy)
fuzzy允许用户搜索词条与实际词条的拼写出现偏差,但是偏差的编辑距离不得超过2
编辑距离:从错误的词到正确词条需要修改的次数。例如:oppe— >oppo,需要修改一次,编辑距离就是1。 编辑距离默认是1
GET /test/_search
{
"query": {
"fuzzy": {
"attr.brand": "oppe"
}
}
}
我们可以手动将编辑距离改为2
GET /test/_search
{
"query": {
"fuzzy": {
"attr.brand": {
"value": "eppe",
"fuzziness": 2
}
}
}
}
7、过滤(filter)
所有的查询都会影响到文档的评分及排名。如果我们需要在查询结果中进行过滤,并且不希望过滤条件影响评分,那么就不要把过滤条件作为查询条件来用。而是使用filter方式:
GET /test/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"title": "小米"
}
}
],
"filter": {
"range": {
"price": {
"gte": 1000,
"lte": 3000
}
}
}
}
}
}
注意: filter中还可以再次进行bool组合条件过滤。
8、排序(sort)
sort 可以让我们按照不同的字段进行排序,并且通过order指定排序的方式
GET /test/_search
{
"query": {
"match": {
"title": "小米"
}
},
"sort": [
{
"price": {
"order": "desc"
},
"stock": {
"order": "asc"
}
}
]
}
9、分页(from/size)
from从哪一条开始(第一条是0)
size取多少条
GET /test/_search
{
"query": {
"match": {
"title": "小米"
}
},
"from": 1,
"size": 2
}
10、 高亮(highlight)
高量显示 的做法是给需要高亮显示的词加上标签,然后在设置的样式,我们需要做的就是为需要高亮显示的词加上标签
GET /test/_search
{
"query": {
"match": {
"title": "小米"
}
},
"highlight": {
"fields": {"title": {}},
"pre_tags": "<em>",
"post_tags": "</em>"
}
}
查询结果是这个样子:
{
"_index" : "test",
"_type" : "goods",
"_id" : "4",
"_score" : 0.94566005,
"_source" : {
"title" : "小米笔记本",
"images" : "http://image.jd.com/12479122.jpg",
"price" : 4999,
"stock" : 200,
"attr" : {
"category" : "笔记本",
"brand" : "小米"
}
},
"highlight" : {
"title" : [
"<em>小米</em>笔记本"
]
}
}
11、结果过滤(_source)
默认情况下,elasticsearch在搜索的结果中,会把文档中保存在_source的所有字段都返回。
如果我们只想获取其中的部分字段,可以添加_source的过滤
GET /test/_search
{
"_source": ["title","price"],
"query": {
"match": {
"title": "小米"
}
}
}