- 软件下载链接
「es」https://www.aliyundrive.com/s/WMbUL5npwcj
点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。
- 上传到Linux
- 解压到/opt目录下
tar -zxvf elasticsearch-7.4.0-linux-x86_64.tar.gz -C /opt - 修改配置
cd /opt/elasticsearch-7.4.0/config
vim elasticsearch.yml
按G到最后, 然后i插入
cluster.name: my-application
node.name: node-1
network.host: 0.0.0.0
http.port: 9200
cluster.initial_master_nodes: [“node-1”]
Esc :wq 保存退出 - 启动es
到bin目录下
es需要的jdk是11但是我们安装的jdk是8, 所以需要配置es使用自己的jdk
再次启动发现 不能用root用户启动
所以需要创建新用户
授权es为itheima
新创建的itheima用户最大可创建文件数太小,最大虚拟内存太小,编辑下列配置文件, 添加类似如下内容
vim /etc/security/limits.conf
vim /etc/security/limits.d/20-nproc.conf
vim /etc/sysctl.conf
重新加载
sysctl -p
切换到itheima用户,启动es
报错
修改jvm配置
这次启动终于有started了,表示启动成功了
在浏览器输入
有json返回表示启动成功.
关闭防火墙
如果看不到, 查看防火墙是否关闭了
暂时关闭防火墙
systemctl stop firewalld
永久设置防火墙状态
systemctl enable firewalld.service 打开防火墙永久性生效,重启后不会复原
systemctl disable firewalld.service 关闭防火墙,永久性生效,重启后不会复原
Kibana安装
切换会root用户
解压kibana到/opt目录下
修改kibana配置
server.port: 5601
server.host: “0.0.0.0”
server.name: “kibana-itcast”
elasticsearch.hosts: [“http://127.0.0.1:9200”]
elasticsearch.requestTimeout: 99999
启动kibana(重新开一个ssh窗口,不要把es关了)
在bin目录下执行 ./kibana --allow-root
然后浏览器http://192.168.174.128:5601/就可看到kibana界面
IK分词器安装
- 准备工作
切回root用户
设置JAVA_HOME
vim /etc/profile
在profile文件末尾添加
export JAVA_HOME=/opt/elasticsearch-7.4.0/jdk
export PATH=P A T H : PATH:PATH:{JAVA_HOME}/bin
保存退出后,重新加载profile
source /etc/profile
上传解压maven安装包
设置软连接 ln -s apache-maven-3.8.6 maven
操作maven就是操作apache-maven-3.8.6,类似win的快捷方式
设置maven环境变量
vim /etc/profile.d/maven.sh
将下面的内容复制到文件,保存
export MAVEN_HOME=/opt/maven
export PATH=M A V E N H O M E / b i n : {MAVEN_HOME}/bin:MAVENHOME/bin:{PATH}
设置好Maven的路径之后,需要运行下面的命令使其生效
source /etc/profile.d/maven.sh
验证maven是否安装成功
mvn -v
- 安装ik分词器
上传并解压分词器zip包
unzip elasticsearch-analysis-ik-7.4.0.zip
打包(第一次可能需要10分钟左右)
将打包好的分词zip包复制到es插件目录中,一系列操作
cd /opt/elasticsearch-7.4.0/plugins/
mkdir analysis-ik
cd analysis-ik
cp -R /opt/elasticsearch-analysis-ik-7.4.0/target/releases/elasticsearch-analysis-ik-7.4.0.zip /opt/elasticsearch-7.4.0/plugins/analysis-ik
unzip /opt/elasticsearch-7.4.0/plugins/analysis-ik/elasticsearch-analysis-ik-7.4.0.zip
cp -R /opt/elasticsearch-analysis-ik-7.4.0/config/* /opt/elasticsearch-7.4.0/config
重启es
切换回itheima用户
启动日志中会有这么一段日志, 表示加载ik分词器成功.
再启动kibana测试ik分词器是否能用
Springboot整合es
引入依赖
<!--引入es的坐标--> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>7.4.0</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-client</artifactId> <version>7.4.0</version> </dependency> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>7.4.0</version> </dependency>
定义配置文件
定义配置类
@Configuration @ConfigurationProperties(prefix = "elasticsearch") public class ElasticSearchConfig { private String host; private int port; public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } @Bean public RestHighLevelClient client(){ return new RestHighLevelClient(RestClient.builder( new HttpHost( host, port, "http" ) )); } }
表结构
创建索引和映射
PUT goods { "mappings": { "properties": { "title": { "type": "text", "analyzer": "ik_smart" }, "price": { "type": "double" }, "createTime": { "type": "date" }, "categoryName": { "type": "keyword" }, "brandName": { "type": "keyword" }, "spec": { "type": "object" }, "saleNum": { "type": "integer" }, "stock": { "type": "integer" } } } }
批量导入数据到es中
这个一般是定时删除重新导入一次
@Test public void importData() throws IOException { //1.查询所有数据,mysql List<Goods> goodsList = goodsMapper.findAll(); //2.bulk导入 BulkRequest bulkRequest = new BulkRequest(); //2.1 循环goodsList,创建IndexRequest添加数据 for (Goods goods : goodsList) { //2.2 设置spec规格信息 Map的数据 specStr:{} //goods.setSpec(JSON.parseObject(goods.getSpecStr(),Map.class)); String specStr = goods.getSpecStr(); //将json格式字符串转为Map集合 Map map = JSON.parseObject(specStr, Map.class); //设置spec map goods.setSpec(map); //将goods对象转换为json字符串 String data = JSON.toJSONString(goods);//map --> {} IndexRequest indexRequest = new IndexRequest("goods"); indexRequest.id(goods.getId()+"").source(data, XContentType.JSON); bulkRequest.add(indexRequest); } BulkResponse response = client.bulk(bulkRequest, RequestOptions.DEFAULT); System.out.println(response.status()); }
查询所有
/** * 查询所有 * 1. matchAll * 2. 将查询结果封装为Goods对象,装载到List中 * 3. 分页。默认显示10条 */ @Test public void testMatchAll() throws IOException { //2. 构建查询请求对象,指定查询的索引名称 SearchRequest searchRequest = new SearchRequest("goods"); //4. 创建查询条件构建器SearchSourceBuilder SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); //6. 查询条件 QueryBuilder query = QueryBuilders.matchAllQuery();//查询所有文档 //5. 指定查询条件 sourceBuilder.query(query); //3. 添加查询条件构建器 SearchSourceBuilder searchRequest.source(sourceBuilder); // 8 . 添加分页信息 sourceBuilder.from(0); sourceBuilder.size(100); //1. 查询,获取查询结果 SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); //7. 获取命中对象 SearchHits SearchHits searchHits = searchResponse.getHits(); //7.1 获取总记录数 long value = searchHits.getTotalHits().value; System.out.println("总记录数:"+value); List<Goods> goodsList = new ArrayList<>(); //7.2 获取Hits数据 数组 SearchHit[] hits = searchHits.getHits(); for (SearchHit hit : hits) { //获取json字符串格式的数据 String sourceAsString = hit.getSourceAsString(); //转为java对象 Goods goods = JSON.parseObject(sourceAsString, Goods.class); goodsList.add(goods); } for (Goods goods : goodsList) { System.out.println(goods); } }
词条查询
/** * termQuery:词条查询 */ @Test public void testTermQuery() throws IOException { SearchRequest searchRequest = new SearchRequest("goods"); SearchSourceBuilder sourceBulider = new SearchSourceBuilder(); QueryBuilder query = QueryBuilders.termQuery("title","华为");//term词条查询 sourceBulider.query(query); searchRequest.source(sourceBulider); SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); SearchHits searchHits = searchResponse.getHits(); //获取记录数 long value = searchHits.getTotalHits().value; System.out.println("总记录数:"+value); List<Goods> goodsList = new ArrayList<>(); SearchHit[] hits = searchHits.getHits(); for (SearchHit hit : hits) { String sourceAsString = hit.getSourceAsString(); //转为java Goods goods = JSON.parseObject(sourceAsString, Goods.class); goodsList.add(goods); } for (Goods goods : goodsList) { System.out.println(goods); } }
词条分词查询
/** * matchQuery:词条分词查询 */ @Test public void testMatchQuery() throws IOException { SearchRequest searchRequest = new SearchRequest("goods"); SearchSourceBuilder sourceBulider = new SearchSourceBuilder(); MatchQueryBuilder query = QueryBuilders.matchQuery("title", "华为手机"); query.operator(Operator.AND);//求并集, 默认是Operator.OR sourceBulider.query(query); searchRequest.source(sourceBulider); SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); SearchHits searchHits = searchResponse.getHits(); //获取记录数 long value = searchHits.getTotalHits().value; System.out.println("总记录数:"+value); List<Goods> goodsList = new ArrayList<>(); SearchHit[] hits = searchHits.getHits(); for (SearchHit hit : hits) { String sourceAsString = hit.getSourceAsString(); Goods goods = JSON.parseObject(sourceAsString, Goods.class); goodsList.add(goods); } for (Goods goods : goodsList) { System.out.println(goods); } }
通配符模糊查询
/** * 模糊查询:WildcardQuery */ @Test public void testWildcardQuery() throws IOException { SearchRequest searchRequest = new SearchRequest("goods"); SearchSourceBuilder sourceBulider = new SearchSourceBuilder(); WildcardQueryBuilder query = QueryBuilders.wildcardQuery("title", "华*"); sourceBulider.query(query); searchRequest.source(sourceBulider); SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); SearchHits searchHits = searchResponse.getHits(); //获取记录数 long value = searchHits.getTotalHits().value; System.out.println("总记录数:"+value); List<Goods> goodsList = new ArrayList<>(); SearchHit[] hits = searchHits.getHits(); for (SearchHit hit : hits) { String sourceAsString = hit.getSourceAsString(); Goods goods = JSON.parseObject(sourceAsString, Goods.class); goodsList.add(goods); } for (Goods goods : goodsList) { System.out.println(goods); } }
正则模糊查询
/** * 模糊查询:regexpQuery */ @Test public void testRegexpQuery() throws IOException { SearchRequest searchRequest = new SearchRequest("goods"); SearchSourceBuilder sourceBulider = new SearchSourceBuilder(); RegexpQueryBuilder query = QueryBuilders.regexpQuery("title", "\\w+(.)*"); sourceBulider.query(query); searchRequest.source(sourceBulider); SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); SearchHits searchHits = searchResponse.getHits(); //获取记录数 long value = searchHits.getTotalHits().value; System.out.println("总记录数:"+value); List<Goods> goodsList = new ArrayList<>(); SearchHit[] hits = searchHits.getHits(); for (SearchHit hit : hits) { String sourceAsString = hit.getSourceAsString(); Goods goods = JSON.parseObject(sourceAsString, Goods.class); goodsList.add(goods); } for (Goods goods : goodsList) { System.out.println(goods); } }
前缀模糊查询
/** * 模糊查询:perfixQuery */ @Test public void testPrefixQuery() throws IOException { SearchRequest searchRequest = new SearchRequest("goods"); SearchSourceBuilder sourceBulider = new SearchSourceBuilder(); PrefixQueryBuilder query = QueryBuilders.prefixQuery("brandName", "三"); sourceBulider.query(query); searchRequest.source(sourceBulider); SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); SearchHits searchHits = searchResponse.getHits(); //获取记录数 long value = searchHits.getTotalHits().value; System.out.println("总记录数:"+value); List<Goods> goodsList = new ArrayList<>(); SearchHit[] hits = searchHits.getHits(); for (SearchHit hit : hits) { String sourceAsString = hit.getSourceAsString(); Goods goods = JSON.parseObject(sourceAsString, Goods.class); goodsList.add(goods); } for (Goods goods : goodsList) { System.out.println(goods); } }
范围查询&排序
/** * 1. 范围查询:rangeQuery * 2. 排序 */ @Test public void testRangeQuery() throws IOException { SearchRequest searchRequest = new SearchRequest("goods"); SearchSourceBuilder sourceBulider = new SearchSourceBuilder(); //范围查询 RangeQueryBuilder query = QueryBuilders.rangeQuery("price"); //指定下限 query.gte(2000); //指定上限 query.lte(3000); sourceBulider.query(query); //排序 sourceBulider.sort("price", SortOrder.DESC); searchRequest.source(sourceBulider); SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); SearchHits searchHits = searchResponse.getHits(); //获取记录数 long value = searchHits.getTotalHits().value; System.out.println("总记录数:"+value); List<Goods> goodsList = new ArrayList<>(); SearchHit[] hits = searchHits.getHits(); for (SearchHit hit : hits) { String sourceAsString = hit.getSourceAsString(); Goods goods = JSON.parseObject(sourceAsString, Goods.class); goodsList.add(goods); } for (Goods goods : goodsList) { System.out.println(goods); } }
多个字段查询
/** * queryString可以指定多个字段查询 */ @Test public void testQueryStringQuery() throws IOException { SearchRequest searchRequest = new SearchRequest("goods"); SearchSourceBuilder sourceBulider = new SearchSourceBuilder(); //queryString QueryStringQueryBuilder query = QueryBuilders.queryStringQuery("华为手机").field("title").field("categoryName").field("brandName").defaultOperator(Operator.AND); sourceBulider.query(query); searchRequest.source(sourceBulider); SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); SearchHits searchHits = searchResponse.getHits(); //获取记录数 long value = searchHits.getTotalHits().value; System.out.println("总记录数:"+value); List<Goods> goodsList = new ArrayList<>(); SearchHit[] hits = searchHits.getHits(); for (SearchHit hit : hits) { String sourceAsString = hit.getSourceAsString(); Goods goods = JSON.parseObject(sourceAsString, Goods.class); goodsList.add(goods); } for (Goods goods : goodsList) { System.out.println(goods); } }
布尔查询(多条件连接)
/** * 布尔查询:boolQuery * 1. 查询品牌名称为:华为 * 2. 查询标题包含:手机 * 3. 查询价格在:2000-3000 */ @Test public void testBoolQuery() throws IOException { SearchRequest searchRequest = new SearchRequest("goods"); SearchSourceBuilder sourceBulider = new SearchSourceBuilder(); //1.构建boolQuery BoolQueryBuilder query = QueryBuilders.boolQuery(); //2.构建各个查询条件 //2.1 查询品牌名称为:华为 QueryBuilder termQuery = QueryBuilders.termQuery("brandName","华为"); query.must(termQuery); //2.2. 查询标题包含:手机 QueryBuilder matchQuery = QueryBuilders.matchQuery("title","手机"); query.filter(matchQuery); //2.3 查询价格在:2000-3000 QueryBuilder rangeQuery = QueryBuilders.rangeQuery("price"); ((RangeQueryBuilder) rangeQuery).gte(2000); ((RangeQueryBuilder) rangeQuery).lte(3000); query.filter(rangeQuery); //3.使用boolQuery连接 sourceBulider.query(query); searchRequest.source(sourceBulider); SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); SearchHits searchHits = searchResponse.getHits(); //获取记录数 long value = searchHits.getTotalHits().value; System.out.println("总记录数:"+value); List<Goods> goodsList = new ArrayList<>(); SearchHit[] hits = searchHits.getHits(); for (SearchHit hit : hits) { String sourceAsString = hit.getSourceAsString(); Goods goods = JSON.parseObject(sourceAsString, Goods.class); goodsList.add(goods); } for (Goods goods : goodsList) { System.out.println(goods); } }
聚合查询
/** * 聚合查询:桶聚合,分组查询 * 1. 查询title包含手机的数据 * 2. 查询所有品牌列表 */ @Test public void testAggQuery() throws IOException { SearchRequest searchRequest = new SearchRequest("goods"); SearchSourceBuilder sourceBulider = new SearchSourceBuilder(); // 1. 查询title包含手机的数据 MatchQueryBuilder query = QueryBuilders.matchQuery("title", "手机"); sourceBulider.query(query); // 2. 查询品牌列表 /* 参数: 1. goods_brands 自定义的名称,将来用于获取数据 2. brandName 分组的字段 */ AggregationBuilder agg = AggregationBuilders.terms("goods_brands").field("brandName").size(100); sourceBulider.aggregation(agg); searchRequest.source(sourceBulider); SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); SearchHits searchHits = searchResponse.getHits(); //获取记录数 long value = searchHits.getTotalHits().value; System.out.println("总记录数:"+value); List<Goods> goodsList = new ArrayList<>(); SearchHit[] hits = searchHits.getHits(); for (SearchHit hit : hits) { String sourceAsString = hit.getSourceAsString(); Goods goods = JSON.parseObject(sourceAsString, Goods.class); goodsList.add(goods); } for (Goods goods : goodsList) { System.out.println(goods); } // 获取聚合结果 Aggregations aggregations = searchResponse.getAggregations(); Map<String, Aggregation> aggregationMap = aggregations.asMap(); // 获取聚合结果goods_brands Terms goods_brands = (Terms) aggregationMap.get("goods_brands"); List<? extends Terms.Bucket> buckets = goods_brands.getBuckets(); List brands = new ArrayList(); for (Terms.Bucket bucket : buckets) { Object key = bucket.getKey(); brands.add(key); } for (Object brand : brands) { System.out.println(brand); } }
高亮查询
/** * * 高亮查询: * 1. 设置高亮 * * 高亮字段 * * 前缀 * * 后缀 * 2. 将高亮了的字段数据,替换原有数据 */ @Test public void testHighLightQuery() throws IOException { SearchRequest searchRequest = new SearchRequest("goods"); SearchSourceBuilder sourceBulider = new SearchSourceBuilder(); // 1. 查询title包含手机的数据 MatchQueryBuilder query = QueryBuilders.matchQuery("title", "手机"); sourceBulider.query(query); //设置高亮 HighlightBuilder highlighter = new HighlightBuilder(); //设置三要素 highlighter.field("title"); highlighter.preTags("<font color='red'>"); highlighter.postTags("</font>"); sourceBulider.highlighter(highlighter); // 2. 查询品牌列表 /* 参数: 1. goods_brands 自定义的名称,将来用于获取数据 2. brandName 分组的字段 */ AggregationBuilder agg = AggregationBuilders.terms("goods_brands").field("brandName").size(100); sourceBulider.aggregation(agg); searchRequest.source(sourceBulider); SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); SearchHits searchHits = searchResponse.getHits(); //获取记录数 long value = searchHits.getTotalHits().value; System.out.println("总记录数:"+value); List<Goods> goodsList = new ArrayList<>(); SearchHit[] hits = searchHits.getHits(); for (SearchHit hit : hits) { String sourceAsString = hit.getSourceAsString(); Goods goods = JSON.parseObject(sourceAsString, Goods.class); // 获取高亮结果,替换goods中的title Map<String, HighlightField> highlightFields = hit.getHighlightFields(); HighlightField HighlightField = highlightFields.get("title"); Text[] fragments = HighlightField.fragments(); //替换 goods.setTitle(fragments[0].toString()); goodsList.add(goods); } for (Goods goods : goodsList) { System.out.println(goods); } // 获取聚合结果 Aggregations aggregations = searchResponse.getAggregations(); Map<String, Aggregation> aggregationMap = aggregations.asMap(); Terms goods_brands = (Terms) aggregationMap.get("goods_brands"); List<? extends Terms.Bucket> buckets = goods_brands.getBuckets(); List brands = new ArrayList(); for (Terms.Bucket bucket : buckets) { Object key = bucket.getKey(); brands.add(key); } for (Object brand : brands) { System.out.println(brand); } }