elasticsearch 使用
目录
RestAPI 简介
1.前提工作 -- 创建索引库
2.RestClient的简单使用
创建索引库
删除索引库
索引库是否存在
创建文档
删除文档
修改文档
批量操作文档
match_all(全部查询)
match查询
term(精准查询)
range(范围查询)
geo(坐标查询)
functionScore(算分函数)
bool(布尔查询-多条件)
排序、分页
高亮
聚合
Bucket聚合(分组)
Metric聚合函数(min、max、avg)
词条(汉字 & 拼音)自动补全
SpringBoot 整合 EleasticSearch 8.0.X 弃用high-level-client
RestAPI 简介
ES官方提供了各种不同语言的客户端,用来操作ES。这些客户端的本质就是组装DSL语句,通过http请求发送给ES。官方文档地址:Elasticsearch Clients | Elastic
1.前提工作 -- 创建索引库
我们根据一个mysql的数据库表来创建对应的索引库
CREATE TABLE `tb_hotel` (`id` bigint(20) NOT NULL COMMENT '酒店id',`name` varchar(255) NOT NULL COMMENT '酒店名称;例:7天酒店',`address` varchar(255) NOT NULL COMMENT '酒店地址;例:航头路',`price` int(10) NOT NULL COMMENT '酒店价格;例:329',`score` int(2) NOT NULL COMMENT '酒店评分;例:45,就是4.5分',`brand` varchar(32) NOT NULL COMMENT '酒店品牌;例:如家',`city` varchar(32) NOT NULL COMMENT '所在城市;例:上海',`star_name` varchar(16) DEFAULT NULL COMMENT '酒店星级,从低到高分别是:1星到5星,1钻到5钻',`business` varchar(255) DEFAULT NULL COMMENT '商圈;例:虹桥',`latitude` varchar(32) NOT NULL COMMENT '纬度;例:31.2497',`longitude` varchar(32) NOT NULL COMMENT '经度;例:120.3925',`pic` varchar(255) DEFAULT NULL COMMENT '酒店图片;例:/img/1.jpg',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
创建的索引库如下:
PUT /hotel
{"mappings": {"properties": {"id": {"type": "keyword"},"name":{"type": "text","analyzer": "ik_max_word","copy_to": "all"},"address":{"type": "keyword","index": false},"price":{"type": "integer"},"score":{"type": "integer"},"brand":{"type": "keyword","copy_to": "all"},"city":{"type": "keyword","copy_to": "all"},"starName":{"type": "keyword"},"business":{"type": "keyword"},"location":{"type": "geo_point"},"pic":{"type": "keyword","index": false},"all":{"type": "text","analyzer": "ik_max_word"}}}
}
几个特殊字段说明:
location:地理坐标,里面包含精度、纬度
all:一个组合字段,其目的是将多字段的值 利用copy_to合并,提供给用户搜索
地理坐标说明:
copy_to说明:
2.RestClient的简单使用
在elasticsearch提供的API中,与elasticsearch一切交互都封装在一个名为RestHighLevelClient的类中,必须先完成这个对象的初始化,建立与elasticsearch的连接。
分为三步:
1)引入es的RestHighLevelClient依赖:
<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>
2)因为SpringBoot默认的ES版是7.6.2,所以我们需要覆盖默认的ES版本:
<properties><java.version>1.8</java.version><elasticsearch.version>7.12.1</elasticsearch.version>
</properties>
3)初始化RestHighLevelClient:
初始化的代码如下:
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.150.101:9200")
));
创建索引库
代码分为三步:
1)创建Request对象。因为是创建索引库的操作,因此Request是CreateIndexRequest。
2)添加请求参数,其实就是DSL的JSON参数部分。因为json字符串很长,这里是定义了静态字符串常量MAPPING_TEMPLATE,让代码看起来更加优雅。
3)发送请求,client.indices()方法的返回值是IndicesClient类型,封装了所有与索引库操作有关的方法。
code:
@Testvoid createHotelIndex() throws IOException {CreateIndexRequest request = new CreateIndexRequest("hotel");request.source(MAPPING_TEMPLATE, XContentType.JSON);client.indices().create(request, RequestOptions.DEFAULT);}public class HotelConstants {public static final String MAPPING_TEMPLATE = "{\n" +" \"mappings\": {\n" +" \"properties\": {\n" +" \"id\":{\n" +" \"type\": \"keyword\"\n" +" },\n" +" \"name\":{\n" +" \"type\": \"text\",\n" +" \"analyzer\": \"ik_max_word\",\n" +" \"copy_to\": \"all\"\n" +" },\n" +" \"address\":{\n" +" \"type\": \"keyword\",\n" +" \"index\": false\n" +" },\n" +" \"price\":{\n" +" \"type\": \"integer\"\n" +" },\n" +" \"score\":{\n" +" \"type\": \"integer\"\n" +" },\n" +" \"brand\":{\n" +" \"type\": \"keyword\",\n" +" \"copy_to\": \"all\"\n" +" },\n" +" \"city\":{\n" +" \"type\": \"keyword\",\n" +" \"copy_to\": \"all\"\n" +" },\n" +" \"starName\":{\n" +" \"type\": \"keyword\"\n" +" },\n" +" \"business\":{\n" +" \"type\": \"keyword\"\n" +" },\n" +" \"location\":{\n" +" \"type\": \"geo_point\"\n" +" },\n" +" \"pic\":{\n" +" \"type\": \"keyword\",\n" +" \"index\": false\n" +" },\n" +" \"all\":{\n" +" \"type\": \"text\",\n" +" \"analyzer\": \"ik_max_word\"\n" +" }\n" +" }\n" +" }\n" +"}";
}
删除索引库
删除索引库的DSL语句非常简单
DELETE /hotel
@Test
void testDeleteHotelIndex() throws IOException {// 1.创建Request对象DeleteIndexRequest request = new DeleteIndexRequest("hotel");// 2.发送请求client.indices().delete(request, RequestOptions.DEFAULT);
}
索引库是否存在
判断索引库是否存在,本质就是查询,对应的DSL是:
GET /hotel
@Test
void testExistsHotelIndex() throws IOException {// 1.创建Request对象GetIndexRequest request = new GetIndexRequest("hotel");// 2.发送请求boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);// 3.输出System.err.println(exists ? "索引库已经存在!" : "索引库不存在!");
}
创建文档
创建文档的DSL语句如下:
POST /{索引库名}/_doc/1
{"name": "Jack","age": 21
}
code:
@Data
@NoArgsConstructor
public class HotelDoc {private Long id;private String name;private String address;private Integer price;private Integer score;private String brand;private String city;private String starName;private String business;private String location;private String pic;public HotelDoc(Hotel hotel) {this.id = hotel.getId();this.name = hotel.getName();this.address = hotel.getAddress();this.price = hotel.getPrice();this.score = hotel.getScore();this.brand = hotel.getBrand();this.city = hotel.getCity();this.starName = hotel.getStarName();this.business = hotel.getBusiness();this.location = hotel.getLatitude() + ", " + hotel.getLongitude();this.pic = hotel.getPic();}
}
@Testvoid addHotelDoc() throws IOException {Hotel hotel = hotelService.getById(36934L);HotelDoc doc= new HotelDoc(hotel);String json = JSON.toJSONString(doc);IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString());request.source(json, XContentType.JSON);client.index(request, RequestOptions.DEFAULT);}
Hotel在数据库中经纬度字段是分开的,es中经纬度是一个字段location,geo_point,所以用HotelDoc和es的属性做对应
删除文档
删除的DSL为是这样的:
DELETE /hotel/_doc/{id}
@Test
void testDeleteDocument() throws IOException {// 1.准备RequestDeleteRequest request = new DeleteRequest("hotel", "61083");// 2.发送请求client.delete(request, RequestOptions.DEFAULT);
}
修改文档
修改我们讲过两种方式:
全量修改:本质是先根据id删除,再新增
增量修改:修改文档中的指定字段值
在RestClient的API中,全量修改与新增的API完全一致,判断依据是ID:
如果新增时,ID已经存在,则修改
如果新增时,ID不存在,则新增
这里是增量修改
@Testvoid updateHotelDoc() throws IOException {UpdateRequest request = new UpdateRequest("hotel","36934");request.doc("price", 333,"starName","三钻");client.update(request, RequestOptions.DEFAULT);}
批量操作文档
批量处理BulkRequest,其本质就是将多个普通的CRUD请求组合在一起发送。
其中提供了一个add方法,用来添加其他请求:
可以看到,能添加的请求包括:
IndexRequest,也就是新增
UpdateRequest,也就是修改
DeleteRequest,也就是删除
因此Bulk中添加了多个IndexRequest,就是批量新增功能了。:
@Testvoid bulkHotelDoc() throws IOException {List<Hotel> list = hotelService.list();BulkRequest request = new BulkRequest();for (Hotel hotel : list) {HotelDoc doc = new HotelDoc(hotel);request.add(new IndexRequest("hotel").id(doc.getId().toString()).source(JSON.toJSONString(doc), XContentType.JSON));}client.bulk(request, RequestOptions.DEFAULT);}
match_all(全部查询)
@Test
void testMatchAll() throws IOException {// 1.准备RequestSearchRequest request = new SearchRequest("hotel");// 2.准备DSLrequest.source().query(QueryBuilders.matchAllQuery());// 3.发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4.解析响应handleResponse(response);
}private void handleResponse(SearchResponse response) {// 4.解析响应SearchHits searchHits = response.getHits();// 4.1.获取总条数long total = searchHits.getTotalHits().value;System.out.println("共搜索到" + total + "条数据");// 4.2.文档数组SearchHit[] hits = searchHits.getHits();// 4.3.遍历for (SearchHit hit : hits) {// 获取文档sourceString json = hit.getSourceAsString();// 反序列化HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);System.out.println("hotelDoc = " + hotelDoc);}
}
match查询
@Testvoid searchMatch() throws IOException {SearchRequest request = new SearchRequest("hotel");request.source().query(QueryBuilders.matchQuery("all", "如家"));SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);printSearchResponse(searchResponse);}
@Testvoid searchMatchMulti() throws IOException {SearchRequest request = new SearchRequest("hotel");request.source().query(QueryBuilders.multiMatchQuery("外滩", "business", "name"));SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);printSearchResponse(searchResponse);}
term(精准查询)
term:词条精确匹配
@Testvoid searchTerm() throws IOException {SearchRequest request = new SearchRequest("hotel");request.source().query(QueryBuilders.termQuery("city", "上海"));SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);printSearchResponse(searchResponse);}
range(范围查询)
@Testvoid searchRange() throws IOException {SearchRequest request = new SearchRequest("hotel");request.source().query(QueryBuilders.rangeQuery("price").lte(200));SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);printSearchResponse(searchResponse);}
geo(坐标查询)
@Testvoid searchGeo() throws IOException {SearchRequest request = new SearchRequest("hotel");request.source().query(QueryBuilders.geoDistanceQuery("location").point(31.21, 121.5).distance(15, DistanceUnit.KILOMETERS));SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);printSearchResponse(searchResponse);}
functionScore(算分函数)
@Testvoid searchFunctionScore() throws IOException {SearchRequest request = new SearchRequest("hotel");QueryBuilder queryBuilder = QueryBuilders.matchQuery("all", "外滩");FunctionScoreQueryBuilder.FilterFunctionBuilder[] filterFunctionBuilders = new FunctionScoreQueryBuilder.FilterFunctionBuilder[1];ScoreFunctionBuilder<WeightBuilder> scoreFunctionBuilder = new WeightBuilder();scoreFunctionBuilder.setWeight(10);QueryBuilder termQuery = QueryBuilders.termQuery("brand", "如家");FunctionScoreQueryBuilder.FilterFunctionBuilder category = new FunctionScoreQueryBuilder.FilterFunctionBuilder(termQuery, scoreFunctionBuilder);filterFunctionBuilders[0] = category;request.source().query(QueryBuilders.functionScoreQuery(queryBuilder,filterFunctionBuilders)
// .scoreMode(FunctionScoreQuery.ScoreMode.SUM).boostMode(CombineFunction.SUM));SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);printSearchResponse(searchResponse);}
或者:
bool 查询 搭配 算分函数
// 1.构建BooleanQueryBoolQueryBuilder boolQuery = QueryBuilders.boolQuery();// 关键字搜索String key = params.getKey();if (key == null || "".equals(key)) {boolQuery.must(QueryBuilders.matchAllQuery());} else {boolQuery.must(QueryBuilders.matchQuery("all", key));}// 城市条件if (params.getCity() != null && !params.getCity().equals("")) {boolQuery.filter(QueryBuilders.termQuery("city", params.getCity()));}// 品牌条件if (params.getBrand() != null && !params.getBrand().equals("")) {boolQuery.filter(QueryBuilders.termQuery("brand", params.getBrand()));}// 星级条件if (params.getStarName() != null && !params.getStarName().equals("")) {boolQuery.filter(QueryBuilders.termQuery("starName", params.getStarName()));}// 价格if (params.getMinPrice() != null && params.getMaxPrice() != null) {boolQuery.filter(QueryBuilders.rangeQuery("price").gte(params.getMinPrice()).lte(params.getMaxPrice()));}// 2.算分控制FunctionScoreQueryBuilder functionScoreQuery =QueryBuilders.functionScoreQuery(// 原始查询,相关性算分的查询boolQuery,// function score的数组new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{// 其中的一个function score 元素new FunctionScoreQueryBuilder.FilterFunctionBuilder(// 过滤条件QueryBuilders.termQuery("isAD", true),// 算分函数ScoreFunctionBuilders.weightFactorFunction(10)).boostMode(CombineFunction.SUM)});request.source().query(functionScoreQuery);
bool(布尔查询-多条件)
布尔查询是用must、must_not、filter等方式组合其它查询,代码示例如下:
可以看到,API与其它查询的差别同样是在查询条件的构建,QueryBuilders,结果解析等其他代码完全不变。
@Testvoid searchBool() throws IOException {SearchRequest request = new SearchRequest("hotel");QueryBuilder mustBuilder = QueryBuilders.matchQuery("name", "如家");QueryBuilder mustNotBuilder = QueryBuilders.rangeQuery("price").gt(400);QueryBuilder geoBuilder = QueryBuilders.geoDistanceQuery("location").point(31.21, 121.5).distance(10, DistanceUnit.KILOMETERS);request.source().query(QueryBuilders.boolQuery().must(mustBuilder).mustNot(mustNotBuilder).filter(geoBuilder));SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);printSearchResponse(searchResponse);}
排序、分页
搜索结果的排序和分页是与query同级的参数,因此同样是使用request.source()来设置。
@Test
void testPageAndSort() throws IOException {// 页码,每页大小int page = 1, size = 5;// 1.准备RequestSearchRequest request = new SearchRequest("hotel");// 2.准备DSL// 2.1.queryrequest.source().query(QueryBuilders.matchAllQuery());// 2.2.排序 sortrequest.source().sort("price", SortOrder.ASC);// 2.3.分页 from、sizerequest.source().from((page - 1) * size).size(5);// 3.发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4.解析响应handleResponse(response);}
距离排序
request.source().sort(SortBuilders.geoDistanceSort("location", new GeoPoint(location)).order(SortOrder.ASC).unit(DistanceUnit.KILOMETERS));
高亮
代码解读:
第一步:从结果中获取source。hit.getSourceAsString(),这部分是非高亮结果,json字符串。还需要反序列为HotelDoc对象
第二步:获取高亮结果。hit.getHighlightFields(),返回值是一个Map,key是高亮字段名称,值是HighlightField对象,代表高亮值
第三步:从map中根据高亮字段名称,获取高亮字段值对象HighlightField
第四步:从HighlightField中获取Fragments,并且转为字符串。这部分就是真正的高亮字符串了
第五步:用高亮的结果替换HotelDoc中的非高亮结果
private void handleResponse(SearchResponse response) {// 4.解析响应SearchHits searchHits = response.getHits();// 4.1.获取总条数long total = searchHits.getTotalHits().value;System.out.println("共搜索到" + total + "条数据");// 4.2.文档数组SearchHit[] hits = searchHits.getHits();// 4.3.遍历for (SearchHit hit : hits) {// 获取文档sourceString json = hit.getSourceAsString();// 反序列化HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);// 获取高亮结果Map<String, HighlightField> highlightFields = hit.getHighlightFields();if (!CollectionUtils.isEmpty(highlightFields)) {// 根据字段名获取高亮结果HighlightField highlightField = highlightFields.get("name");if (highlightField != null) {// 获取高亮值String name = highlightField.getFragments()[0].string();// 覆盖非高亮结果hotelDoc.setName(name);}}System.out.println("hotelDoc = " + hotelDoc);}
}
聚合
Bucket聚合(分组)
void searchAggs() throws IOException {SearchRequest request = new SearchRequest("hotel");//不返回文档数据request.source().size(0);request.source().aggregation(AggregationBuilders.terms("brandAgg").field("brand").size(20).order(BucketOrder.aggregation("_count",true)));SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);Aggregations aggregations = searchResponse.getAggregations();Terms brandTerms = aggregations.get("brandAgg");List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();for (Terms.Bucket bucket : buckets) {System.out.println(bucket.getKeyAsString() + " : " + bucket.getDocCount());}
}
获取多个聚合结果:
GET /hotel/_search
{"size": 0,"aggs": {"brandAgg": {"terms": {"field": "brand","size": 2}}, "cityAgg": {"terms": {"field": "city","size": 2}}}
}
request.source().aggregation(AggregationBuilders.terms("brandAgg").field("brand").size(2));request.source().aggregation(AggregationBuilders.terms("cityAgg").field("city").size(2));
Metric聚合函数(min、max、avg)
现在我们需要对桶内的酒店做运算,获取每个品牌的用户评分的min、max、avg等值。
SearchRequest request = new SearchRequest("hotel");request.source().size(0);request.source().aggregation(AggregationBuilders.terms("brandAgg").field("brand").size(20).order(BucketOrder.aggregation("score_stats.avg",false)).subAggregation(AggregationBuilders.stats("score_stats").field("score")));SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
结果:
@Testvoid searchAggsMetric() throws IOException {SearchRequest request = new SearchRequest("hotel");request.source().size(0);request.source().aggregation(AggregationBuilders.terms("brandAgg").field("brand").size(20).order(BucketOrder.aggregation("score_stats.avg",false)).subAggregation(AggregationBuilders.stats("score_stats").field("score")));SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);Aggregations aggregations = searchResponse.getAggregations();Terms brandTerms = aggregations.get("brandAgg");List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();for (Terms.Bucket bucket : buckets) {Aggregations bucketAggs = bucket.getAggregations();Stats stats = bucketAggs.get("score_stats");System.out.println(bucket.getKeyAsString() +" : " + JSON.toJSONString(stats));}}
词条(汉字 & 拼音)自动补全
目标根据酒店品牌 和 商圈的关键字,或者拼音,补全关联到的内容。
此处以(keyword)精准词语为例
1. 支持拼音关联搜索,则需要安装拼音分词器。
拼音分词器的安装请参考:elasticsearch 安装(docker)_naki_bb的博客-CSDN博客
不需要拼音补全的课参考 elasticsearch DSL命令_naki_bb的博客-CSDN博客的 自动补全
2.词条补全必须要有一个字段类型为suggestion。
索引库DSL语句如下
// 酒店数据索引库
PUT /hotel
{"settings": {"analysis": {"analyzer": {"text_anlyzer": {"tokenizer": "ik_max_word","filter": "py"},"completion_analyzer": {"tokenizer": "keyword","filter": "py"}},"filter": {"py": {"type": "pinyin","keep_full_pinyin": false,"keep_joined_full_pinyin": true,"keep_original": true,"limit_first_letter_length": 16,"remove_duplicated_term": true,"none_chinese_pinyin_tokenize": false}}}},"mappings": {"properties": {"id":{"type": "keyword"},"name":{"type": "text","analyzer": "text_anlyzer","search_analyzer": "ik_smart","copy_to": "all"},"address":{"type": "keyword","index": false},"price":{"type": "integer"},"score":{"type": "integer"},"brand":{"type": "keyword","copy_to": "all"},"city":{"type": "keyword"},"starName":{"type": "keyword"},"business":{"type": "keyword","copy_to": "all"},"location":{"type": "geo_point"},"pic":{"type": "keyword","index": false},"all":{"type": "text","analyzer": "text_anlyzer","search_analyzer": "ik_smart"},"suggestion":{"type": "completion","analyzer": "completion_analyzer"}}}
}
实体类:
HotelDoc中要添加一个字段,用来做自动补全,内容可以是酒店品牌、商圈等信息。按照自动补全字段的要求,最好是这些字段的数组。
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;@Data
@NoArgsConstructor
public class HotelDoc {private Long id;private String name;private String address;private Integer price;private Integer score;private String brand;private String city;private String starName;private String business;private String location;private String pic;private Object distance;private Boolean isAD;private List<String> suggestion;public HotelDoc(Hotel hotel) {this.id = hotel.getId();this.name = hotel.getName();this.address = hotel.getAddress();this.price = hotel.getPrice();this.score = hotel.getScore();this.brand = hotel.getBrand();this.city = hotel.getCity();this.starName = hotel.getStarName();this.business = hotel.getBusiness();this.location = hotel.getLatitude() + ", " + hotel.getLongitude();this.pic = hotel.getPic();// 组装suggestionif(this.business.contains("/")){// business有多个值,需要切割String[] arr = this.business.split("/");// 添加元素this.suggestion = new ArrayList<>();this.suggestion.add(this.brand);Collections.addAll(this.suggestion, arr);}else {this.suggestion = Arrays.asList(this.brand, this.business);}}
}
重新导入数据功能,可以看到新的酒店数据中包含了suggestion:
API 示例
结果解析示例:
案例的实现如下:
@Override
public List<String> getSuggestions(String prefix) {try {// 1.准备RequestSearchRequest request = new SearchRequest("hotel");// 2.准备DSLrequest.source().suggest(new SuggestBuilder().addSuggestion("suggestions",SuggestBuilders.completionSuggestion("suggestion").prefix(prefix).skipDuplicates(true).size(10)));// 3.发起请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4.解析结果Suggest suggest = response.getSuggest();// 4.1.根据补全查询名称,获取补全结果CompletionSuggestion suggestions = suggest.getSuggestion("suggestions");// 4.2.获取optionsList<CompletionSuggestion.Entry.Option> options = suggestions.getOptions();// 4.3.遍历List<String> list = new ArrayList<>(options.size());for (CompletionSuggestion.Entry.Option option : options) {String text = option.getText().toString();list.add(text);}return list;} catch (IOException e) {throw new RuntimeException(e);}
}
SpringBoot 整合 EleasticSearch 8.0.X 弃用high-level-client
请参考
springboot集成elasticsearch 8.0以上版本_weixin_46501729的博客-CSDN博客
elasticsearch 使用相关推荐
- Elasticsearch学习之路(一)
一.前序 1.1正向索引和倒排索引 ** 正向索引通常用于数据库中,在搜索引擎领域使用的最多的就是倒排索引 ** 通过例子表示: 我爱编程, 我爱编程,我是小码农 1.1.1 正向索引 假设我们使用m ...
- 2021年大数据ELK(二十五):添加Elasticsearch数据源
全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 添加Elasticsearch数据源 一.Kibana索引模式 添加Elast ...
- 2021年大数据ELK(十九):使用FileBeat采集Kafka日志到Elasticsearch
全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 使用FileBeat采集Kafka日志到Elasticsearch 一.需求分 ...
- 2021年大数据ELK(十七):Elasticsearch SQL 订单统计分析案例
全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 订单统计分析案例 一.案例介绍 二.创建索引 三.导入测试数据 四.统计不同支 ...
- 2021年大数据ELK(十六):Elasticsearch SQL(职位查询案例)
全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 职位查询案例 一.查询职位索引库中的一条数据 二.将SQL转换为DSL 三.职 ...
- 2021年大数据ELK(十五):Elasticsearch SQL简单介绍
全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 Elasticsearch SQL简单介绍 一.SQL与Elasticsear ...
- 2021年大数据ELK(十三):Elasticsearch编程(添加职位数据)
全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 Elasticsearch编程 一.添加职位数据 1.初始化客户端连接 2.实 ...
- 2021年大数据ELK(十二):Elasticsearch编程(环境准备)
全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 Elasticsearch编程 一.环境准备 1.准备IDEA项目结构 2.准 ...
- 2021年大数据ELK(十一):Elasticsearch架构原理
全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 Elasticsearch架构原理 一.Elasticsearch的节点类型 ...
- 2021年大数据ELK(八):Elasticsearch安装IK分词器插件
全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 安装IK分词器 一.下载Elasticsearch IK分词器 ...
最新文章
- 盘点近期重大技术成就及其将带给你的影响,与你我息息相关!
- 阿里提供中文搜索新选项!AI引擎+达摩院黑科技,你要试试吗?
- iOS开发-UISwipeGestureRecognizer滑动手势
- 3.5. Error Prompt
- tableau应用实战案例(五十)-销售业绩的tableau可视化案例
- 教小学妹学算法:搜索算法解决迷宫问题
- android 文件 c语言 jni,Android jni 调用的so文件一个函数的反汇编 高手来看看
- CORS预检请求详谈
- 大数据(1)---全球100款大数据工具汇总(前50款)
- hibernate和struts实现分页
- 电商并没有给我们创造一个就业机会
- sa结构组网方式_5G建网:先NSA还是SA?
- OpenCV实现摄像机标定和像素转换,surf寻找特征点,FLANN匹配算子进行匹配
- 190609每日一句,科比·布莱恩特:这就是我成功的原因,即使身陷低谷,也要抬头仰望星空
- CentOS 7.6 vi编辑器常用命令详解
- 攻击者视角对AntiSpam工作的分析
- crc8校验c语言程序,单片机CRC8检验C语言实现
- 写函数,返回一个扑克牌列表,里面有52项,每一项是一个元组 例如:[(‘红心’,2),(‘草花’,2), …(‘黑桃,A
- Windows沙拉:开机时自动打开NumLock键背后的故事
- 十、RabbitMQ发布确认高级