Java微服务篇4——Elastic search

Java微服务篇4——Elastic search

1、Elastic search安装配置

Elastic search官方:https://www.elastic.co/cn/products/elasticsearch

Elastic search6.2.4 百度云:https://pan.baidu.com/s/1JyQok8Nija4gYhcjh-HWcw提取码:isa2

解压即可

在config/elasticsearch.yml修改

# ----------------------------------- Paths ------------------------------------
#
# Path to directory where to store the data (separate multiple locations by comma):
#
path.data: /path/to/data
#
# Path to log files:
#
path.logs: /path/to/logs

启动bin目录下的elasticsearch.bat/elasticsearch.sh
在这里插入图片描述

访问

http://localhost:9200/

在这里插入图片描述

2、kibana安装

Kibana是一个基于Node.js的Elasticsearch索引库数据统计工具,可以利用Elasticsearch的聚合功能, 生成各种图表,如柱形图,线状图,饼图等。 而且还提供了操作Elasticsearch索引数据的控制台

kibana6.2.4 百度云:https://pan.baidu.com/s/1AlD34ZYvHqtVwaapRh3tPA提取码:p8gr

在config/kibana.yml修改

elasticsearch.url: "http://localhost:9200"

在这里插入图片描述

3、ik分词器

elasticsearch-analysis-ik-6.2.4 百度云:https://pan.baidu.com/s/1L4_fQIgLmLoLpKL8sXAAFw提取码:8k05

解压elasticsearch-analysis-ik-6.2.4.zip后,将解压后的文件夹拷贝到elasticsearch-6.2.4\plugins 下,并重命名文件夹为ik

重启即可

测试

GET /_analyze
{"text": "我是中国人"
}

在这里插入图片描述

GET /_analyze
{"analyzer": "ik_max_word","text": "我是中国人"
}

在这里插入图片描述

GET /_analyze
{"analyzer": "ik_min_word","text": "我是中国人"
}

在这里插入图片描述

4、elasticsearch-head

elasticsearch-head 百度云:https://pan.baidu.com/s/1JsOvr64gb5xNbkPPJafyag提取码:6khj
在这里插入图片描述
在这里插入图片描述

5、elastic search操作

映射属性数据类型

一级分类二级分类具体类型类型描述
核心类型字符串类型text当一个字段是要被全文搜索的,比如Email内容、产品描述,应该使用text类型
设置text类型以后,字段内容会被分析,在生成倒排索引以前,字符串会被分析器分成一个一个词项
text类型的字段不用于排序,很少用于聚合
keywordkeyword类型适用于索引结构化的字段,比如email地址、主机名、状态码和标签
如果字段需要进行过滤(比如查找已发布博客中status属性为published的文章)、排序、聚合
keyword类型的字段只能通过精确值搜索到
整数类型byte-128~127
short-32768~32767
integer-231~231-1
long-263~263-1
浮点类型float32位单精度IEEE 754浮点类型
double64位双精度IEEE 754浮点类型
half_float16位半精度IEEE 754浮点类型
scaled_float缩放类型的的浮点数
逻辑类型booleantrue,false
日期类型date(1)日期格式的字符串,比如 “2018-01-13” 或 “2018-01-13 12:10:30”
(2)long类型的毫秒数
(3)integer的秒数seconds-since-the-epoch
范围类型range
二进制类型binary进制字段是指用base64来表示索引中存储的二进制数据,可用来存储二进制形式的数据,例如图像
复合类型数组类型array(1)字符数组: [ “one”, “two” ]
(2)整数数组: productid:[ 1, 2 ]
(3)对象(文档)数组: “user”:[ { “name”: “Mary”, “age”: 12 }, { “name”: “John”, “age”: 10 }]
对象类型objectJSON对象,文档会包含嵌套的对象
嵌套类型nested用于JSON对象数组
地理类型地理坐标类型geo_point纬度/经度积分
地理地图geo_shape用于多边形等复杂形状
特殊类型IP类型ip用于存储IPv4或者IPv6的地址
范围类型completion提供自动完成建议
令牌计数类型token_count计算字符串中令牌的数量

index

是否被索引

index的默认值就是true,也就是说你不进行任何配置,所有字段都会被索引,有些字段是我们不希望被索引的,比如商品的图片信息(URL),就需要手动设置index为false

stroe

是否额外存储

在lucene里,如果一个字段的store设置为false,那么在文档列表中就不会有这个字段的 值,用户的搜索结果中不会显示出来,但是在Elasticsearch中,即便store设置为false,也可以搜索到结果

原因是Elasticsearch在创建文档索引时,会将文档中的原始数据备份,保存到一个叫做 _source 的属性 中。而且我们可以通过过滤 _source 来选择哪些要显示,哪些不显示

如果设置store为true,就会在 _source 以外额外存储一份数据,多余,因此一般我们都会将store设 置为false,事实上,store的默认值就是false

在某些情况下,这对 store 某个领域可能是有意义的。例如,如果您的文档包含一个 title ,一个 date 和一个非常大的 content 字段,则可能只想检索the title 和the date 而不必从一个大 _source 字段中提取这些字段

boost

网站权重:网站权重是指搜索引擎给网站(包括网页)赋予一定的权威值,对网站(含网页)权威的评估评价。一 个网站权重越高,在搜索引擎所占的份量越大,在搜索引擎排名就越好。提高网站权重,不但利于网站(包括网 页)在搜索引擎的排名更靠前,还能提高整站的流量,提高网站信任度。所以提高网站的权重具有相当重要的意 义。 权重即网站在SEO中的重要性,权威性。英文:Page Strength。

  • 权重不等于排名
  • 权重对排名有着 非常大的影响
  • 整站权重的提高有利于内页的排名

5.1、库操作(database)

# 添加索引库
PUT /索引库名
# 获取索引库信息
GET /索引库名
# 删除索引库
DELETE /索引库名

5.2、类型及映射操作(表)

创建数据库表需要设置字段约束,索引库也一样,在创建索引库的类型时,需要知道这个类型下 有哪些字段,每个字段有哪些约束信息,这就叫做 字段映射(mapping)

# 添加类型及映射1(向索引库追加类型及映射)
PUT winkto/_mapping/goods
{"properties": {"title": {"type": "text","analyzer": "ik_max_word"},"images": {"type": "keyword","index": "false"},"price": {"type": "float"}}
}
# 添加类型及映射2(在索引库创建时添加类型及映射)
PUT /winkto2
{"settings": {},"mappings": {"goods": {"properties": {"title": {"type": "text","analyzer": "ik_max_word"}}}}
}
# 查看类型及映射
GET winkto/_mapping
GET winkto/_mapping/goods

5.3、追加数据

# 追加数据(随机id)
POST /winkto/goods/
{"title":"小米10","images":"http://image.lagou.com/12479122.jpg","price":2699.00
}

在这里插入图片描述

# 追加数据(指定id)
POST /winkto/goods/sadhsahduashfusahdi
{"title":"华为","images":"http://image.lagou.com/12479122.jpg","price":4699.00
}

在这里插入图片描述

# 获取数据
GET /winkto/goods/xqurVHsB1mHhNfuBSw0p

在这里插入图片描述

5.4、删除数据

DELETE /winkto/goods/sadhsahduashfusahdi

5.5、查询

语法

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

5.5.1、查询所有

GET /winkto/_search
{"query":{"match_all":{}}
}
{"took": 2,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 2,"max_score": 1,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 1,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699}},{"_index": "winkto","_type": "goods","_id": "kBFMWHsBy-koX7e_VW4W","_score": 1,"_source": {"title": "华为pro30","images": "http://image.lagou.com/12479122.jpg","price": 5699}}]}
}

5.5.2、条件查询

GET /winkto/_search
{"query":{"match":{"title": "小米"}}
}
{"took": 16,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 1,"max_score": 0.2876821,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 0.2876821,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699}}]}
}

match 类型查询,会把查询条件进行分词,然后进行查询,多个词条之间是or的关系

GET /winkto/_search
{"query":{"match":{"title": "小米华为"}}
}
{"took": 355,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 2,"max_score": 0.2876821,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 0.2876821,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699}},{"_index": "winkto","_type": "goods","_id": "kBFMWHsBy-koX7e_VW4W","_score": 0.2876821,"_source": {"title": "华为pro30","images": "http://image.lagou.com/12479122.jpg","price": 5699}}]}
}

但是有些时候我们希望分词关系为and

GET /winkto/_search
{"query":{"match":{"title": {"query": "小米华为","operator": "and"}}}
}
{"took": 8,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 1,"max_score": 0.5753642,"hits": [{"_index": "winkto","_type": "goods","_id": "kRFWWHsBy-koX7e_DW5_","_score": 0.5753642,"_source": {"title": "小米华为plusplus","images": "http://image.lagou.com/12479122.jpg","price": 2699}}]}
}

5.5.3、词条匹配

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

GET /winkto/_search
{"query":{"term": {"price": 2699}}
}
{"took": 7,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 2,"max_score": 1,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 1,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699}},{"_index": "winkto","_type": "goods","_id": "kRFWWHsBy-koX7e_DW5_","_score": 1,"_source": {"title": "小米华为plusplus","images": "http://image.lagou.com/12479122.jpg","price": 2699}}]}
}

5.5.4、布尔组合

bool 把各种其它查询通过 must (与)、 must_not (非)、 should (或)的方式进行组合

GET /winkto/_search
{"query":{"bool": {"must": [{"match": {"title": "小米"}}],"must_not": [{"match": {"title": "华为"}}],"should": [{"match": {"title": "10"}}]}}
}
{"took": 2,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 1,"max_score": 0.5753642,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 0.5753642,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699}}]}
}

5.5.5、范围查询

GET /winkto/_search
{"query":{"range": {"price": {"gte": 2000,"lte": 6000}}}
}
{"took": 4,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 3,"max_score": 1,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 1,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699}},{"_index": "winkto","_type": "goods","_id": "kBFMWHsBy-koX7e_VW4W","_score": 1,"_source": {"title": "华为pro30","images": "http://image.lagou.com/12479122.jpg","price": 5699}},{"_index": "winkto","_type": "goods","_id": "kRFWWHsBy-koX7e_DW5_","_score": 1,"_source": {"title": "小米华为plusplus","images": "http://image.lagou.com/12479122.jpg","price": 2699}}]}
}

5.6、结果过滤

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

5.6.1、直接指定字段

GET /winkto/_search
{"_source": ["title","price"], "query":{"match": {"title": "小米"}}
}
{"took": 9,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 2,"max_score": 0.2876821,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 0.2876821,"_source": {"price": 2699,"title": "小米10"}},{"_index": "winkto","_type": "goods","_id": "kRFWWHsBy-koX7e_DW5_","_score": 0.2876821,"_source": {"price": 2699,"title": "小米华为plusplus"}}]}
}

5.6.2、includes和excludes

  • includes:来指定想要显示的字段
  • excludes:来指定不想要显示的字段
GET /winkto/_search
{"_source": {"includes": ["title","images"],"excludes": ["price"]}, "query":{"match": {"title": "小米"}}
}
{"took": 2,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 2,"max_score": 0.2876821,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 0.2876821,"_source": {"images": "http://image.lagou.com/12479122.jpg","title": "小米10"}},{"_index": "winkto","_type": "goods","_id": "kRFWWHsBy-koX7e_DW5_","_score": 0.2876821,"_source": {"images": "http://image.lagou.com/12479122.jpg","title": "小米华为plusplus"}}]}
}

5.6.3、Filter

GET /winkto/_search
{"query":{"bool": {"must": [{"match": {"title": "小米"}}],"filter": {"range": {"price": {"gte": 1000,"lte": 3000}}}}}
}
{"took": 1,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 2,"max_score": 0.2876821,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 0.2876821,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699}},{"_index": "winkto","_type": "goods","_id": "kRFWWHsBy-koX7e_DW5_","_score": 0.2876821,"_source": {"title": "小米华为plusplus","images": "http://image.lagou.com/12479122.jpg","price": 2699}}]}
}

如果一次查询只有过滤,没有查询条件,不希望进行评分,可以使用 constant_score 取代只有 filter 语句的 bool 查询

GET /winkto/_search
{"query":{"constant_score": {"filter": {"range": {"price": {"gte": 1000,"lte": 3000}}}}}
}
{"took": 4,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 2,"max_score": 1,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 1,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699}},{"_index": "winkto","_type": "goods","_id": "kRFWWHsBy-koX7e_DW5_","_score": 1,"_source": {"title": "小米华为plusplus","images": "http://image.lagou.com/12479122.jpg","price": 2699}}]}
}

5.7、排序

GET /winkto/_search
{"query":{"match_all": {}},"sort": [{"price": {"order": "desc"}}]
}
{"took": 141,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 3,"max_score": null,"hits": [{"_index": "winkto","_type": "goods","_id": "kBFMWHsBy-koX7e_VW4W","_score": null,"_source": {"title": "华为pro30","images": "http://image.lagou.com/12479122.jpg","price": 5699},"sort": [5699]},{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": null,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699},"sort": [2699]},{"_index": "winkto","_type": "goods","_id": "kRFWWHsBy-koX7e_DW5_","_score": null,"_source": {"title": "小米华为plusplus","images": "http://image.lagou.com/12479122.jpg","price": 2699},"sort": [2699]}]}
}

5.8、分页

GET /winkto/_search
{"query":{"match_all": {}},"from": 0,"size": 2
}
{"took": 5,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 3,"max_score": 1,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 1,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699}},{"_index": "winkto","_type": "goods","_id": "kBFMWHsBy-koX7e_VW4W","_score": 1,"_source": {"title": "华为pro30","images": "http://image.lagou.com/12479122.jpg","price": 5699}}]}
}

5.9、高亮显示

GET /winkto/_search
{"query":{"match": {"title": "小米"}},"highlight": {"pre_tags": "<em>","post_tags": "</em>","fields": {"title": {}}}
}
{"took": 69,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 2,"max_score": 0.2876821,"hits": [{"_index": "winkto","_type": "goods","_id": "xqurVHsB1mHhNfuBSw0p","_score": 0.2876821,"_source": {"title": "小米10","images": "http://image.lagou.com/12479122.jpg","price": 2699},"highlight": {"title": ["<em>小米</em>10"]}},{"_index": "winkto","_type": "goods","_id": "kRFWWHsBy-koX7e_DW5_","_score": 0.2876821,"_source": {"title": "小米华为plusplus","images": "http://image.lagou.com/12479122.jpg","price": 2699},"highlight": {"title": ["<em>小米</em>华为plusplus"]}}]}
}

5.10、聚合

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

  • 桶(group by):是按照某种方式对数据进行分组,每一组数据在ES中称为一个 桶
  • 度量(聚合的结果):求平均值、最大、最小、求和等

预准备

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

5.10.1、聚合为桶

GET /car/_search
{"size": 0,"aggs": {"popular_colors": {"terms": {"field": "color"}}}
}
{"took": 48,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 8,"max_score": 0,"hits": []},"aggregations": {"popular_colors": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": [{"key": "红","doc_count": 4},{"key": "绿","doc_count": 2},{"key": "蓝","doc_count": 2}]}}
}

5.10.2、聚合操作

GET /car/_search
{"size": 0,"aggs": {"popular_colors": {"terms": {"field": "color"},"aggs": {"avg_price": {"avg": {"field": "price"}}}}}
}
{"took": 8,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 8,"max_score": 0,"hits": []},"aggregations": {"popular_colors": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": [{"key": "红","doc_count": 4,"avg_price": {"value": 32500}},{"key": "绿","doc_count": 2,"avg_price": {"value": 21000}},{"key": "蓝","doc_count": 2,"avg_price": {"value": 20000}}]}}
}

6、Elastic search集群

6.1、集群解决的问题

  • 单台机器存储容量有限,无法实现高存储
  • 单服务器容易出现单点故障,无法实现高可用
  • 单服务的并发处理能力有限,无法实现高并发

6.2、数据分片

第一个问题就是数据量太大,单点存储量有限的问题,可以把数据拆分成多份,每一份存储到不同机器节点(node),从而实现减少每个节点数 据量的目的。这就是数据的分布式存储,也叫做: 数据分片(Shard)

数据分片解决了海量数据存储的问题,但是如果出现单点故障,那么分片数据就不再完整

给每个分片数据进行备 份,存储到其它节点,防止数据丢失,这就是数据备份,也叫 数据副本(replica)

数据备份可以保证高可用,但是每个分片备份一份,所需要的节点数量就会翻一倍,成本实在是太高

为了在高可用和成本间寻求平衡,首先对数据分片,存储到不同节点 然后对每个分片进行备份,放到对方节点,完成互相备份
在这里插入图片描述

6.3、集群搭建

在这里插入图片描述

node-0配置文件(node-1,node-2只需要修改node.name、http.port,transport.tcp.port,path.data,path.logs即可)

# ---------------------------------- Cluster -----------------------------------
# Use a descriptive name for your cluster:
cluster.name: my-application
# ------------------------------------ Node ------------------------------------
# Use a descriptive name for the node:
node.name: node-0
# Add custom attributes to the node:
#node.attr.rack: r1
# 是否可以为主节点
node.master: true
# ----------------------------------- Paths ------------------------------------
# Path to directory where to store the data (separate multiple locations by comma):
path.data: D:\es\elasticsearch-6.2.4-0\data
# Path to log files:
path.logs: D:\es\elasticsearch-6.2.4-0\data
# ----------------------------------- Memory -----------------------------------
# Lock the memory on startup:
#bootstrap.memory_lock: true
# Make sure that the heap size is set to about half the memory available
# on the system and that the owner of the process is allowed to use this
# limit.
# Elasticsearch performs poorly when the system is swapping the memory.
# ---------------------------------- Network -----------------------------------
# Set the bind address to a specific IP (IPv4 or IPv6):
network.host: 0.0.0.0
# Set a custom port for HTTP:
http.port: 9200
# For more information, consult the network module documentation.
# TCP协议对外端口 每个节点不一样,默认:9300
transport.tcp.port: 9201
# --------------------------------- Discovery ----------------------------------
# Pass an initial list of hosts to perform discovery when new node is started:
# The default list of hosts is ["127.0.0.1", "[::1]"]
#discovery.zen.ping.unicast.hosts: ["host1", "host2"]
# Prevent the "split brain" by configuring the majority of nodes (total number of master-eligible nodes / 2 + 1):
#discovery.zen.minimum_master_nodes: 
# For more information, consult the zen discovery module documentation.
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9201","127.0.0.1:9301","127.0.0.1:9401"]
discovery.zen.minimum_master_nodes: 2
# ---------------------------------- Gateway -----------------------------------
# Block initial recovery after a full cluster restart until N nodes are started:
#gateway.recover_after_nodes: 3
# For more information, consult the gateway module documentation.
# ---------------------------------- Various -----------------------------------
# Require explicit names when deleting indices:
#action.destructive_requires_name: true
# ---------------------------------- Http -----------------------------------
#允许跨域名访问
http.cors.enabled: true
#当设置允许跨域,默认为*,表示支持所有域名
http.cors.allow-origin: "*"

在这里插入图片描述
在这里插入图片描述
创建索引winkto

PUT /winkto
{"settings": {"number_of_shards": 3,"number_of_replicas": 1},"mappings": {"items":{"properties": {"id": {"type": "keyword"},"title":{"type": "text","analyzer": "ik_max_word"},"category":{"type": "keyword"},"brand": {"type": "keyword"},"images":{"type": "keyword","index": false},"price":{"type": "double"}}}}
}

在这里插入图片描述

7、Elastic search API

预准备

PUT /winkto
{"settings": {"number_of_shards": 3,"number_of_replicas": 1},"mappings": {"items":{"properties": {"id": {"type": "keyword"},"title":{"type": "text","analyzer": "ik_max_word"},"category":{"type": "keyword"},"brand": {"type": "keyword"},"images":{"type": "keyword","index": false},"price":{"type": "double"}}}}
}

7.1、添加数据

导入依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></dependency><!--ES高级Rest Client--><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>6.5.4</version></dependency><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>6.5.4</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency>
</dependencies>

实体类

public class Product {private Long id;private String title;private String category;private String brand;private Double price;private String images;
}

config

@Configuration
public class WinktoConfig {@Beanpublic ObjectMapper jackson(){return new ObjectMapper();}
}

测试

@SpringBootTest
class ElasticSearchApplicationTests {@AutowiredObjectMapper jackson;@Testvoid contextLoadsinsert() throws IOException {// 初始化HighLevel客户端RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200),new HttpHost("127.0.0.1",9300),new HttpHost("127.0.0.1",9400)));// 文档数据Product product = new Product(1L,"华为P50、新款发布","手机","华为",5999.9,"http://image.huawei.com/1.jpg");IndexRequest indexRequest = new IndexRequest("winkto", "items", product.getId().toString());indexRequest.source(jackson.writeValueAsString(product), XContentType.JSON);IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);System.out.println(response);// 关闭客户端restHighLevelClient.close();}
}

结果

IndexResponse[index=winkto,type=items,id=1,version=3,result=created,seqNo=2,primaryTerm=1,shards={"total":2,"successful":2,"failed":0}]

在这里插入图片描述

7.2、查询数据

@Test
void contextLoadsSelect() throws IOException {// 初始化HighLevel客户端RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200),new HttpHost("127.0.0.1",9300),new HttpHost("127.0.0.1",9400)));GetRequest getRequest = new GetRequest("winkto","items","1");GetResponse documentFields = restHighLevelClient.get(getRequest,RequestOptions.DEFAULT);String sourceAsString = documentFields.getSourceAsString();Product product = jackson.readValue(sourceAsString, Product.class);System.out.println(product.toString());// 关闭客户端restHighLevelClient.close();
}
Product{id=1, title='华为P50、新款发布', category='手机', brand='华为', price=5999.9, images='http://image.huawei.com/1.jpg'}

7.3、修改文档

新增时,如果传递的id是已经存在的,则会完成修改操作,如果不存在,则是新增

7.4、删除文档

@Test
void contextLoadsDelete() throws IOException {// 初始化HighLevel客户端RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200),new HttpHost("127.0.0.1",9300),new HttpHost("127.0.0.1",9400)));DeleteRequest deleteRequest = new DeleteRequest("winkto", "items", "1");DeleteResponse delete = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);// 关闭客户端restHighLevelClient.close();
}

7.5、match_all

@Test
void contextLoadsMatchAll() throws IOException {// 初始化HighLevel客户端RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200),new HttpHost("127.0.0.1",9300),new HttpHost("127.0.0.1",9400)));SearchRequest searchRequest = new SearchRequest();SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.matchAllQuery());searchRequest.source(searchSourceBuilder);SearchResponse search = restHighLevelClient.search(searchRequest);SearchHits hits = search.getHits();SearchHit[] hits1 = hits.getHits();for (SearchHit documentFields : hits1) {String sourceAsString = documentFields.getSourceAsString();Product product = jackson.readValue(sourceAsString, Product.class);System.out.println(product);}// 关闭客户端restHighLevelClient.close();
}

7.6、match

@Test
void contextLoadsMatch() throws IOException {// 初始化HighLevel客户端RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200),new HttpHost("127.0.0.1",9300),new HttpHost("127.0.0.1",9400)));SearchRequest searchRequest = new SearchRequest();SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.matchQuery("title","新款"));searchRequest.source(searchSourceBuilder);SearchResponse search = restHighLevelClient.search(searchRequest);SearchHits hits = search.getHits();SearchHit[] hits1 = hits.getHits();for (SearchHit documentFields : hits1) {String sourceAsString = documentFields.getSourceAsString();Product product = jackson.readValue(sourceAsString, Product.class);System.out.println(product);}// 关闭客户端restHighLevelClient.close();
}

7.7、range

@Test
void contextLoadsRange() throws IOException {// 初始化HighLevel客户端RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200),new HttpHost("127.0.0.1",9300),new HttpHost("127.0.0.1",9400)));SearchRequest searchRequest = new SearchRequest();SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.rangeQuery("price").gt(2000).lt(4000));searchRequest.source(searchSourceBuilder);SearchResponse search = restHighLevelClient.search(searchRequest);SearchHits hits = search.getHits();SearchHit[] hits1 = hits.getHits();for (SearchHit documentFields : hits1) {String sourceAsString = documentFields.getSourceAsString();Product product = jackson.readValue(sourceAsString, Product.class);System.out.println(product);}// 关闭客户端restHighLevelClient.close();
}

7.8、source过滤

默认情况下,索引库中所有数据都会返回,如果我们想只返回部分字段,可以通过source filter来控制

@Test
void contextLoadsSource() throws IOException {// 初始化HighLevel客户端RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200),new HttpHost("127.0.0.1",9300),new HttpHost("127.0.0.1",9400)));SearchRequest searchRequest = new SearchRequest();SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.rangeQuery("price").gt(2000).lt(4000));// 第一个参数想要包含的字段,第二个参数不想要包含的字段searchSourceBuilder.fetchSource(new String[]{"title","price"},null);searchRequest.source(searchSourceBuilder);SearchResponse search = restHighLevelClient.search(searchRequest);SearchHits hits = search.getHits();SearchHit[] hits1 = hits.getHits();for (SearchHit documentFields : hits1) {String sourceAsString = documentFields.getSourceAsString();Product product = jackson.readValue(sourceAsString, Product.class);System.out.println(product);}// 关闭客户端restHighLevelClient.close();
}

7.9、排序

@Test
void contextLoadsSort() throws IOException {// 初始化HighLevel客户端RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200),new HttpHost("127.0.0.1",9300),new HttpHost("127.0.0.1",9400)));SearchRequest searchRequest = new SearchRequest();SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.rangeQuery("price").gt(2000).lt(4000));// 降序排序searchSourceBuilder.sort("price", SortOrder.DESC);searchRequest.source(searchSourceBuilder);SearchResponse search = restHighLevelClient.search(searchRequest);SearchHits hits = search.getHits();SearchHit[] hits1 = hits.getHits();for (SearchHit documentFields : hits1) {String sourceAsString = documentFields.getSourceAsString();Product product = jackson.readValue(sourceAsString, Product.class);System.out.println(product);}// 关闭客户端restHighLevelClient.close();
}

7.10、分页

@Test
void contextLoadsSort() throws IOException {// 初始化HighLevel客户端RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1",9200),new HttpHost("127.0.0.1",9300),new HttpHost("127.0.0.1",9400)));SearchRequest searchRequest = new SearchRequest();SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.matchAllQuery());// 降序排序searchSourceBuilder.sort("price", SortOrder.DESC);//searchSourceBuilder.from(0);searchSourceBuilder.size(2);searchRequest.source(searchSourceBuilder);SearchResponse search = restHighLevelClient.search(searchRequest);SearchHits hits = search.getHits();SearchHit[] hits1 = hits.getHits();for (SearchHit documentFields : hits1) {String sourceAsString = documentFields.getSourceAsString();Product product = jackson.readValue(sourceAsString, Product.class);System.out.println(product);}// 关闭客户端restHighLevelClient.close();
}

8、Spring Data Elastic search

Spring Data 的使命是给各种数据访问提供统一的编程接口,不管是关系型数据库(如MySQL),还是 非关系数据库(如Redis),或者类似Elasticsearch这样的索引数据库。从而简化开发人员的代码,提 高开发效率。

  • 支持Spring的基于 @Configuration 的java配置方式,或者XML配置方式
  • 提供了用于操作ES的便捷工具类 ElasticsearchTemplate 。包括实现文档到POJO之间的自动智能映射
  • 利用Spring的数据转换服务实现的功能丰富的对象映射
  • 基于注解的元数据映射方式,而且可扩展以支持更多不同的数据格式,可以定义JavaBean:类名、属性
  • 根据持久层接口自动生成对应实现方法,无需人工编写基本操作代码(类似mybatis,根据接口自 动得到实现)。当然,也支持人工定制查询

8.1、创建索引库

导入依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies>
@Document(indexName = "winkto", type = "product", shards = 3, replicas = 1)
public class Product {@Idprivate Long id;@Field(type = FieldType.Text,analyzer = "ik_max_word")private String title;@Field(type = FieldType.Keyword)private String category;@Field(type = FieldType.Keyword)private String brand;@Field(type = FieldType.Double)private Double price;@Field(type = FieldType.Keyword)private String images;
}
@SpringBootTest
class EsDataApplicationTests {@Autowiredprivate ElasticsearchTemplate elasticsearchTemplate;@Testvoid contextLoadsIndex() {elasticsearchTemplate.createIndex(Product.class);}
}

application.yaml

spring:data:elasticsearch:cluster-name: my-applicationcluster-nodes: 127.0.0.1:9201,127.0.0.1:9301,127.0.0.1:9401

在这里插入图片描述
在这里插入图片描述

8.2、创建类型映射

@Test
void contextLoadsMapping() {elasticsearchTemplate.putMapping(Product.class);
}

在这里插入图片描述

8.3、索引数据CRUD

添加数据(单条)

@Test
void contextLoadsInsert() {Product product = new Product(1L, "小米手机7", "手机", "小米", 3299.00, "/13123.jpg");productMapper.save(product);
}

在这里插入图片描述
添加数据(多条)

@Test
void contextLoadsInsertAll() {List<Product> list = new ArrayList<>();list.add(new Product(2L, "坚果手机R1", "手机", "锤子", 3699.00, "/13123.jpg"));list.add(new Product(3L, "华为META10", "手机", "华为", 4499.00, "/13123.jpg"));list.add(new Product(4L, "小米Mix2S", "手机", "小米", 4299.00, "/13123.jpg"));list.add(new Product(5L, "荣耀V10", "手机", "华为", 2799.00, "/13123.jpg"));productMapper.saveAll(list);
}

在这里插入图片描述
根据id查询

@Test
void contextLoadsSelect() {Optional<Product> optionalProduct = productMapper.findById(1L);System.out.println(optionalProduct.orElse(null));
}

查询所有

@Test
void contextLoadsSelectAll() {Iterable<Product> all = productMapper.findAll();all.forEach(System.out::println);
}

根据id删除

@Test
void contextLoadsDelete() {productMapper.deleteById(1L);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/557428.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ftp文件服务器杀毒,FTP远程查杀网页木马方法

感谢使用护卫神云查杀系统&#xff0c;该软件专门查杀网页木马&#xff0c;完全免费&#xff0c;欢迎大家使用。远程FTP查杀部分&#xff1a;1、点击【远程查杀】图标&#xff0c;如上图所示&#xff0c;进入远程FTP查杀页面&#xff1a;1、首先要求输入远程FTP连接信息&#x…

Java微服务篇5——Docker

Java微服务篇5——Docker 1、虚拟化技术 虚拟化技术是一种计算机资源管理技术&#xff0c;是将计算机的各种实体资源&#xff0c;如服务器、网络、内存及存储 等&#xff0c;予以抽象、转换后呈现出来。虚拟化技术打破了计算机实体结构间的&#xff0c;不可切割的障碍。使用户…

文件服务器 说明,文件服务器搭建说明.pdf

文件共享服务器搭建 责任人 姜 源 起讫时间 2010 11 15 至 2010 12 19 编号 JY001 0 目录目录 一 确定实现方案 1 二 方案实现方法 4 三 参考资料 12 1 文件服务器搭建说明与经验总结文件服务器搭建说明与经验总结 一 一 确定实现方案确定实现方案 方案方案 A Windows Server E…

Shiro 实战教程

Shiro 实战教程 1.权限的管理 1.1 什么是权限管理 ​ 基本上涉及到用户参与的系统都要进行权限管理&#xff0c;权限管理属于系统安全的范畴&#xff0c;权限管理实现对用户访问系统的控制&#xff0c;按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源…

货车定位服务器维护是什么意思,有关货车日常维护的主要内容

有关货车日常维护的主要内容货车日常维护的主要内容1)汽车日常维护以清洗、补给和检查为主要内容&#xff0c;如图1-47所示。2)行车前的检查有驾驶室内检查、发动机舱检查、车辆外部检查和轮胎检查。3)行车前发动机舱的检查包括玻璃清洗液、机油、冷却液、蓄电池液、制动液和风…

MySQL的INSERT ··· ON DUPLICATE KEY UPDATE使用的几种情况

MySQL的INSERT ON DUPLICATE KEY UPDATE使用的几种情况 在MySQL数据库中&#xff0c;如果在insert语句后面带上ON DUPLICATE KEY UPDATE 子句&#xff0c;而要插入的行与表中现有记录的惟一索引或主键中产生重复值&#xff0c;那么就会发生旧行的更新&#xff1b;如果插入的行…

mybatis笔记之一次插入多条数据sql语句写法

mybatis笔记之一次插入多条数据sql语句写法

Idea插件——Translation 翻译插件安装与使用

Translation 安装 实现步骤如下: file——setting——plugin——marketplace——输入Translation——点击install——安装完成点击apply应用—ok确认——重启idea才能生效 Translation 使用 选中单词或者段落ctrlshifty翻译&#xff0c;ctrlshifts切换翻译源 ctrlshifty翻译…

INSERT IGNORE 与INSERT INTO的区别

INSERT IGNORE 与INSERT INTO的区别 INSERT IGNORE 与INSERT INTO的区别就是INSERT IGNORE会忽略数据库中已经存在 的数据&#xff0c;如果数据库没有数据&#xff0c;就插入新的数据&#xff0c;如果有数据的话就跳过这条数据。这样就可以保留数据库中已经存在数据&#xff0…

java中Date日期类型的大小比较

java中Date日期类型的大小比较 方法一: java.util.Date类实现了Comparable接口&#xff0c;可以直接调用Date的compareTo()方法来比较大小 String beginTime "2018-07-28 14:42:32"; String endTime "2018-07-29 12:26:32";SimpleDateFormat format …

Java8 中 List 转 Map(Collectors.toMap) 使用技巧

Java8 中 List 转 Map(Collectors.toMap) 使用技巧 在实际项目中我们经常会用到 List 转 Map 操作&#xff0c;在过去我们可能使用的是 for 循环遍历的方式。举个例子&#xff1a; 先定义类&#xff1a; // 简单对象 Accessors(chain true) // 链式方法 lombok.Data clas…

BeautifulSoup入门案例

import beautifulsoup4 as bsimport requestsurl "http://www.baidu.com"html requests.get(url) # 获取网页响应对象html.encoding utf-8 # 修改网页响应对象&#xff08;requests.models.Response&#xff09;的编码格式content html.text # 获取网页的内容…

MySQL中concat函数(连接字符串)

MySQL中concat函数&#xff08;连接字符串&#xff09; MySQL中concat函数 使用方法&#xff1a; concat(str1,str2,…) 返回结果为连接参数产生的字符串。如有任何一个参数为NULL &#xff0c;则返回值为 NULL。 mysql> select concat(‘11’,‘22’,‘33’); ---------…

复制Linux虚拟机后的网卡问题解决

以CentOS为例&#xff1a; 首先修改&#xff1a; /etc/sysconfig/network-scripts/ifcfg-eth0 此文件中的DEVICEeth0要与文件名中的网卡名一致&#xff0c;并且此文件中的网卡的HWADDR要与下面文件中对应的网卡的HWADDR一致 再修改&#xff1a; /etc/udev/rules.d/70-persiste…

模糊查询 LIKE CONCAT()的使用

模糊查询 LIKE CONCAT()的使用 LIKE CONCAT() 根据学生名称模糊查询学生信息 sql语句实现 select stuName from student where stuName LIKE CONCAT(’%’, ‘张’, ‘%’)mybatis实现&#xff1a; select stuName from student where stuName LIKE CONCAT (’%’,#{stuNa…

Linux中的shell正则表达式详解

Shell中使用正则表达式处理文本的命令有如下工具&#xff1a; 命令描述grep默认不支持扩展表达式&#xff0c;加-E选项开启ERE。如果不加-E&#xff0c;此时使用花括号时要加转义符&#xff1a;\{\}egrep支持基础和扩展表达式awk支持基础和扩展表达式sed默认不支持扩展表达式&…

java编码问题详解

import java.io.UnsupportedEncodingException; import java.util.Arrays;/*编码&#xff1a; 字符变成字节数组解码&#xff1a; 字节数组变成字符串String --> byte[] : str.getBytes()byte[] --> String : new String(byte[])*/public class EncodeDemo {public…

JDK1.8 新特性(全)

JDK1.8 新特性 本文主要介绍了JDK1.8版本中的一些新特性&#xff0c;乃作者视频观后笔记&#xff0c;仅供参考。 jdk1.8新特性知识点&#xff1a; Lambda表达式函数式接口方法引用和构造器调用Stream API接口中的默认方法和静态方法新时间日期API 在jdk1.8中对hashMap等map集…

Java中BigDecimal类介绍及用法

Java中BigDecimal类介绍及用法 Java中提供了大数字(超过16位有效位)的操作类,即 java.math.BinInteger 类和 java.math.BigDecimal 类,用于高精度计算.   其中 BigInteger 类是针对大整数的处理类,而 BigDecimal 类则是针对大小数的处理类.   BigDecimal 类的实现用到了 B…

java中的生产者消费者模式详解

方式 一&#xff1a; Synchronized方式 注&#xff1a;此种方式会造成资源的浪费&#xff1a; 利用锁的notifyAll()方法会将所有的线程都唤醒&#xff0c;会造成资源的浪费 class Resource {private String name;private int count 1;private boolean flag false;public syn…