赞
踩
一、基本概念
1、Index(索引):名词,相当于 MySQL 中的 Database
2、Type(类型):类似于 MySQL 中的 Table;每一种类型的数据放在一起
3、Document(文档):文档是 JSON 格式的,Document 就像是 MySQL 中的某个 Table 里面的内容;
4、倒排索引机制
二、Docker 安装 Es
1、下载镜像文件
docker pull elasticsearch:7.4.2 存储和检索数据
docker pull kibana:7.4.2 可视化检索数
docker images :查看已经安装镜像
free -m :查看内存
2、创建实例
1)、ElasticSearch
mkdir -p /mydata/elasticsearch/config
mkdir -p /mydata/elasticsearch/data
echo "http.host: 0.0.0.0" >> /mydata/elasticsearch/config/elasticsearch.yml
cat elasticsearch.yml :查看内容
chmod -R 777 /mydata/elasticsearch/ 保证权限
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx512m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2
然后就在9200端口启动了,URL输入http://192.168.56.10:9200
重启操作: docker ps -a ;查看(包括未启动的)
docker start 18a
开机自启动:docker update 18a(id号) --restart=always
删除操作:docker stop 18a;
docker rm 18a;
docker ps -a
2)、Kibana
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.56.10:9200 -p 5601:5601 -d kibana:7.4.2
开机自启动:docker update 455(id号) --restart=always
三、初步检索
1、_cat
GET /_cat/nodes:查看所有节点
GET /_cat/health:查看 es 健康状况
GET /_cat/master:查看主节点
GET /_cat/indices:查看所有索引 相当于show databases;
2、索引一个文档(保存一条记录)
保存一个数据,保存在哪个索引的哪个类型下,指定用哪个唯一标识
http://192.168.56.10:9200/customer/external/1 :;在 customer 索引下的 external 类型下保存 1 号数据为
put请求:{ "name": "John Doe"}
PUT 和 POST保存更新 都可以,
POST 新增。如果不指定 id,会自动生成 id。指定 id 就会修改这个数据,并新增版本号
PUT 可以新增可以修改。PUT 必须指定 id;由于 PUT 需要指定 id,我们一般都用来做修改操作,不指定 id 会报错。
3、查询文档
GET customer/external/1
更新请求:http://192.168.56.10:9200/customer/external/1?if_seq_no=2&if_primary_term=1 乐观锁机制
4、更新文档
方式一:
POST customer/external/1/_update
{ "doc":{ "name": "John Doew"
}
}
方式二:
POST customer/external/1
{ "name": "John Doe2"
}
方式三:
PUT customer/external/1
{ "name": "John Doe"
}
POST和PUT不带_updata得不对比原先数据,带_updata得对比原先数据,相同就不会有任何操作
5、删除文档&索引
1、DELETE customer/extern 删除文档
2、DELETE custome 删除索引
6、bulk 批量 API
https://github.com/elastic/elasticsearch/blob/7.4/docs/src/test/resources/accounts.json?raw=true 导入测试数据
POST bank/account/_bulk
测试数据
四、进阶检索
手册官网:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html
1、SearchAPI
ES 支持两种基本方式检索 :
⭐一个是通过使用 REST request URI 发送搜索参数(uri+检索参数)
⭐另一个是通过使用 REST request body 来发送它们(uri+请求体)
第一种方式:一切检索从_search 开始 :GET bank/_search?q=*&sort=account_number:asc
第二种方式: uri+请求体进行检索:
- GET bank/_search
- {
- "query": {
- "match_all": {}
- },
- "sort": [
- {
- "account_number": {
- "order": "desc"
- }
- }
- ]
- }
2、Query DSL
1)、基本语法格式
2)、返回部分字段: "_source": ["age","balance"]
- GET bank/_search
- {
- "query": {
- "match_all": {}
- },
- "sort": [
- {
- "balance": {
- "order": "desc"
- }
- }
- ],
- "from":0
- , "size": 5,
- "_source": ["age","balance"]
- }
3)、match【匹配查询】 全文检索
⭐ 基本类型(非字符串),精确匹配
⭐ 字符串,全文检索
⭐字符串,多个单词(分词+全文检索)
- GET bank/_search
- {
- "query": {
- "match": {
- "address": "mill road"
- }
- }
- }
##全文检索按照评分进行排序,会对检索条件分词匹配
4)、match_phrase【短语匹配】
- GET bank/_search
- {
- "query": {
- "match_phrase": {
- "address": "mill road"
- }
- }
- }
5)、multi_match【多字段匹配】
###也会进行分词
- GET bank/_search
- {
- "query": {
- "multi_match": {
- "query": "mill",
- "fields": ["state","address"]
- }
- }
- }
6)、bool【复合查询】
⭐must:必须达到 must 列举的所有条件
⭐must_not 必须不是指定的情况
⭐should:应该达到 should 列举的条件,如果达到会增加相关文档的评分,并不会改变查询的结果。
- GET bank/_search
- {
- "query": {
- "bool": {
- "must": [
- {
- "match": {"address": "mill"}
- },
- {
- "match": {"gender": "M"}
- }
- ],
- "should": [
- {
- "match": {"address": "lane"}
- }
- ],
- "must_not": [
- {
- "match": {"email": "baluba.com"}
- }
- ]
- }
- }
- }
7)、filter【结果过滤】
并不是所有的查询都需要产生分数,特别是那些仅用于 “filtering”(过滤)的文档。不会产生查询分数
8)、term
和 match 一样。匹配某个属性的值。全文检索字段用 match,其他非 text 字段匹配用 term
- GET bank/_search
- {
- "query": {
- "bool": {
- "must": [
- {
- "term": {"age": {"value": "28"}}
- },
- {
- "match": {"address": "990 Mill Road"}
- }
- ]
- }
- }
- }
9)、aggregations(执行聚合)
##复杂:查出所有年龄分布,并且这些年龄段中 M 的平均薪资和 F 的平均薪资以及这个年龄段的总体平均薪资
- GET bank/account/_sea
- GET bank/_search
- {
- "query": {
- "match_all": {}
- },
- "aggs": {
- "avg_age": {
- "terms": {
- "field": "age",
- "size": 10
- },
- "aggs": {
- "male": {
- "terms": {
- "field": "gender.keyword",
- "size": 10
- },
- "aggs": {
- "avg_bal": {
- "avg": {"field": "balance"}
- }
- }
- },
- "balance_avg":{
- "avg": {
- "field": "balance"
- }
- }
- }
- }
- }
- }
3、Mapping 映射
手册官网:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html
GET bank/_mapping :查询bank索引下的属性映射
1)、创建映射
- PUT /my-index
- {
- "mappings": {
- "properties": {
- "age": {
- "type": "integer"
- },
- "email": {
- "type": "keyword" //创建的是一个精确索引
- },
- "name": {
- "type": "text" //创建的是一个全局索引
- }
- }
- }
- }
2)、添加新的字段映射
- PUT /my-index/_mapping
- {
- "properties": {
- "employee-id": {
- "type": "keyword",
- "index": false
- }
- }
- }
3)、更新映射
对于已经存在的映射字段,我们不能更新。更新必须创建新的索引进行数据迁移
4)、数据迁移
先创建出 new_twitter 的正确映射。然后使用如下方式进行数据迁移
- POST _reindex
- {
- "source": {
- "index": "twitter",
- "type": "tweet #当老版本中有类型,故还要加上这一行
- },
- "dest": {
- "index": "new_twitter"
- }
- }
4、
1)分词--安装ik分词器
将elasticsearch-analysis-ik-5.6.11.zip 解压之后放在/mydata/elasticsearch/plugins下
⭐⭐⭐一个遇到的问题,就是在plugins放入解压后的ik之后再重启elasticsearch之后,elasticsearch一直不断重启,问题解决的方案是elasticsearch
版本要和ik版本一致,我的都是7.4.2
补充:
使用MobaXterm,可以实现windos和linux的文件互传,
chmod -R 777 ik/ 改变文件夹 ik/ 的权限为可读可写可执行
docker exec -it 18a /bin/bash :进入docker中的18a项目中
exit; 退出docker
docker restart elasticsearch : 重启elasticsearch
⭐修改linux网络配置:
1、cd /etc/sysconfig/network-scripts/
2、ls
3、 ip addr 查看我们使用的是哪个网络
4、vi ifcfg-eth1
添加:
GATEWAY=192.168.56.1
DNS1=114.114.114.114
DNS2=8.8.8.8
5、重启网络 :service network restart
6、ping baidu.com
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo
更改Linux yum源:
更改方法:
1、进入yum配置文件目录
cd /etc/yum.repos.d/
2、备份配置文件
mv CentOS-Base.repo CentOS-Base.repo.bak
3、下载163的配置,并改名
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo
4、生成缓存
yum makecach2)分词--安装ik分词器
POST _analyze
{
"analyzer": "ik_smart",
"text": "我是中国山东人"
}
安装 nginx:
1、docker下载nginx: docker run -p 80:80 --name nginx -d nginx:1.10
2、在mydata\下创建 nginx文件夹
3、将docker容器内的 nginx文件夹放到mydata下:docker container cp nginx:/etc/nginx .
4、停止并移除docker里面的nginx:
docker stop nginx
docker rm nginx
5、在mydata下创建conf文件夹,将nginx文件目录里面的文件放到conf下,然后清空nginx,然后将conf放到nginx里面
6、创建新的nginx
docker run -p 80:80 --name nginx \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/logs:/var/log/nginx \
-v /mydata/nginx/conf:/etc/nginx \
-d nginx:1.10
7、cd /mydata/nginx/html
8、vi index.html输入i进入插入模式:
<h1>Guilimall</h1>
9、在/mydata/nginx/html 下mkdir es
10、cd /mydata/nginx/html/es
vi fenci.txt
加入自定义分词如:尚硅谷
10、游览器输入:http://192.168.56.10/es/fenci.txt
就可以看到效果了,之后有想加入的自定义词汇就可以加到fenci.txt文件下
11、cd /mydata/elasticsearch/plugins/ik/config
12、vi IKAnalyzer.cfg.xml
加入:
<!--用户可以在这里配置远程扩展字典 -->
<entry key="remote_ext_dict">http://192.168.56.10/es/fenci.txt</entry>
13、docker restart elasticsearch
14、
POST _analyze
{
"analyzer": "ik_max_word",
"text": "尚硅谷机构"
}
附录:
SpringBoot 整合elasticSearch:
1、创建一个springboot项目,版本为<version>2.1.8.RELEASE</version>,导入spring-web依赖和common依赖
2、导入es的rest-high-level-client
- <dependency>
- <groupId>org.elasticsearch.client</groupId>
- <artifactId>elasticsearch-rest-high-level-client</artifactId>
- <version>7.4.2</version>
- </dependency>
这个版本要和使用的elasticsearch版本对应,springboot默认给添加了elasticsearch版本,这时候需要添加
- <properties>
- <java.version>1.8</java.version>
- <elasticsearch.version>7.4.2</elasticsearch.version>
- </properties>
3、因为导入的common依赖中包括一些数据库的依赖,此时启动文件GulimallSearchApplication需要排除数据库
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
4、开启nacos注册中心,将该模块注册进入nacos注册中心
在application.properties中写入:
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.application.name=gulimall-search
并开启@EnableDiscoveryClient 注册发现
5、编写配置,给容器中注入一个RestHighLevelClient
- @Configuration
- public class GulimallElasticSearchConfig {
- @Bean
- public RestHighLevelClient esRestClient(){
-
- RestClientBuilder builder =null;
- builder = RestClient.builder(new HttpHost("192.168.56.10", 9200, "http"));
- RestHighLevelClient client = new RestHighLevelClient(builder);
- return client;
- }
- }
java测试篇:
一:测试容器中是否已经注入了RestHighLevelClient
- @RunWith(SpringRunner.class)
- @SpringBootTest
- public class GulimallSearchApplicationTests {
-
- @Autowired
- private RestHighLevelClient client;
- @Test
- public void contextLoads() {
- System.out.println(client);
- }
- }
二、测试存储、更新ES数据
参考文档API:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-index.html
- @Test
- public void indexData() throws IOException {
- //创建索引
- IndexRequest indexRequest = new IndexRequest("users");
- //数据的id
- indexRequest.id("1");
- User user = new User();
- user.setUserName("zhangsan");
- user.setAge(18);
- user.setGender("男");
-
- String jsonString = JSON.toJSONString(user);
- indexRequest.source(jsonString, XContentType.JSON);
- //执行索引保存操作
- IndexResponse index = client.index(indexRequest, GulimallElasticSearchConfig.COMMON_OPTIONS);
- //提取有用的响应数据
- System.out.println(index);
- }
-
- @Data
- class User {
- private String userName;
- private String gender;
- private Integer age;
- }
三、复杂检索:在bank中搜索address中包含mill的所有人的年龄分布以及平均年龄,平均薪资
参考文档API:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-search.html
利用在线软件将json生成java实体类:https://www.bejson.com/json2javapojo/new/
- @ToString
- @Data
- static class Account {
- private int account_number;
- private int balance;
- private String firstname;
- private String lastname;
- private int age;
- private String gender;
- private String address;
- private String employer;
- private String email;
- private String city;
- private String state;
- }
-
- @Test
- public void searchData() throws IOException {
- //1. 创建检索请求
- SearchRequest searchRequest = new SearchRequest();
- //1.1)指定索引
- searchRequest.indices("bank");
- //1.2)构造检索条件
- SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
- sourceBuilder.query(QueryBuilders.matchQuery("address", "Mill"));
- // System.out.println("检索条件:"+sourceBuilder.toString());
-
- //1.2.1)按照年龄分布进行聚合
- TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg").field("age").size(10);
- sourceBuilder.aggregation(ageAgg);
-
- //1.2.2)计算平均年龄
- AvgAggregationBuilder ageAvg = AggregationBuilders.avg("ageAvg").field("age");
- sourceBuilder.aggregation(ageAvg);
- //1.2.3)计算平均薪资
- AvgAggregationBuilder balanceAvg = AggregationBuilders.avg("balanceAvg").field("balance");
- sourceBuilder.aggregation(balanceAvg);
- // System.out.println("检索条件:" + sourceBuilder.toString());
-
- searchRequest.source(sourceBuilder);
- //2. 执行检索
- // SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
- SearchResponse searchResponse = client.search(searchRequest, GulimallElasticSearchConfig.COMMON_OPTIONS);
- System.out.println("检索结果:" + searchResponse.toString());
-
- //3. 将检索结果封装为Bean
- //得到第一层的hits
- SearchHits hits = searchResponse.getHits();
- //得到第二层的hits
- SearchHit[] searchHits = hits.getHits();
- for (SearchHit searchHit : searchHits) {
- String sourceAsString = searchHit.getSourceAsString();
- Account account = JSON.parseObject(sourceAsString, Account.class);
- System.out.println(account);
-
- }
- // //4. 获取聚合信息
- Aggregations aggregations = searchResponse.getAggregations();
-
- Terms ageAgg1 = aggregations.get("ageAgg");
- for (Terms.Bucket bucket : ageAgg1.getBuckets()) {
- String keyAsString = bucket.getKeyAsString();
- System.out.println("年龄:" + keyAsString + " ==> " + bucket.getDocCount());
- }
- Avg balanceAvg1 = aggregations.get("balanceAvg");
- System.out.println("平均薪资:" + balanceAvg1.getValue());
- }
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。