一、概述
ElasticSearch,简称为ES, ES是一个开源的高扩展的分布式全文搜索引擎。它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。
物理设计:
ElasticSearch 在后台把每个索引划分成多个分片,每份分片可以在集群中的不同服务器间迁移。
逻辑设计:
一个索引类型中,包含多个文档,比如说文档1,文档2,文档3。当我们索引一篇文档时,可以通过这样的一个顺序找到它: 索引 -▷ 类型 -▷ 文档ID ,通过这个组合我们就能索引到某个具体的文档。
二、环境搭建
下载安装elasticsearch-6.8.13、es-head-chrome插件。
下载ES相关插件,将插件放置plugins目录下:
三、ES启动
启动命令:elasticsearch.bat
若能成功访问 http://loaclhost:9200,则启动成功
可通过 es-head-chrome插件查看ES后台:
启动kibana:
访问:http://localhost:5601
在开发工具中,可执行Rest命令
四、Springboot项目搭建
创建Springboot项目:
五、添加ES依赖
设置ES版本:
1.8 6.8.13
导入ES依赖,JSON依赖:
com.alibaba fastjson 1.2.54 org.elasticsearch.client elasticsearch-rest-high-level-client org.elasticsearch.client elasticsearch-rest-client org.elasticsearch elasticsearch
六、编写配置类
@Configuration public class config { @Bean public RestHighLevelClient restHighLevelClient() { RestHighLevelClient client = new RestHighLevelClient( RestClient.builder(new HttpHost("127.0.0.1", 9200, "http"))); return client; } }
七、创建索引
@Test void testCreateIndex() throws IOException { HttpHost host = HttpHost.create("http://localhost:9200"); RestClientBuilder builder = RestClient.builder(host); client = new RestHighLevelClient(builder); CreateIndexRequest request = new CreateIndexRequest("user"); client.indices().create(request, RequestOptions.DEFAULT); client.close(); }
八、增删改操作
1、基本Rest命令说明(增、删、改、查命令):
menthod | ur地址 | 描述 |
---|---|---|
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/索引名称/类型名称/_search | 查询所有数据 |
2、添加文档记录
添加单条记录
@Test void testAddDoc() throws IOException { // 1.要在指定索引下创建文档,所以要先创建索引,再创建文档 IndexRequest request=new IndexRequest(); // index()方法设置索引名;id()方法设置唯一id标识 request.index("user").id("10001").type("text"); // 2.创建实体类对象,填充数据 User user=new User(); user.setName("张三丰"); user.setAge(30); // 3.利用jackson将实体类对象转换成JSON格式字符串 request.source(JSON.toJSONString(user), XContentType.JSON); // 5.发送请求,获取响应结果 IndexResponse response = client.index(request, RequestOptions.DEFAULT); System.out.println("_index: "+response.getIndex()); System.out.println("_id: "+response.getId()); System.out.println("_result: "+response.getResult()); }
批量添加记录
@Test void testBulkRequest()throws IOException{ BulkRequest bulkRequest = new BulkRequest(); ArrayListusers = new ArrayList<>(); // users.add(new Employee("李文",23,"研发工程师","2352")); // users.add(new Employee("罗文",17,"测试工程师","8732")); // users.add(new Employee("徐洁",22,"算法工程师","8791")); // users.add(new Employee("罗辑",31,"高级研发工程师","8765")); // users.add(new Employee("叶文洁",70,"资深研发工程师","8551")); users.add(new Employee("小猪佩奇",23,"猪","2")); users.add(new Employee("小猪",17,"佩奇","4")); users.add(new Employee("测试",22,"小","6")); users.add(new Employee("xiaozhubeiqi",31,"peiqi","8")); users.add(new Employee("小猪佩佩",70,"小猪佩祺过大年","10")); users.add(new Employee("小猪珮奇",23,"小猪佩祺过大年","12")); users.add(new Employee("小猪佩奇",23,"小猪佩奇过大年","14")); for(int i = 0;i< users.size();i++){ bulkRequest.add(new IndexRequest("pig").id(""+(i+1)).type("pinyin") .source(JSON.toJSONString(users.get(i)),XContentType.JSON)); } BulkResponse bulkResponse = client.bulk(bulkRequest,RequestOptions.DEFAULT); System.out.println(!bulkResponse.hasFailures()); }
3、更新文档记录
@Test void testUpdateDoc() throws IOException { UpdateRequest request = new UpdateRequest("test_index","random","1"); User user = new User("张三",18,"003"); request.doc(JSON.toJSONString(user), XContentType.JSON); UpdateResponse updateResponse = client.update(request, RequestOptions.DEFAULT); System.out.println(updateResponse.status() == RestStatus.OK); }
4、删除文档记录
@Test void testDelete() throws IOException { HttpHost host = HttpHost.create("http://localhost:9200"); client = new RestHighLevelClient(RestClient.builder(host)); DeleteRequest request = new DeleteRequest("test_index","random","1"); DeleteResponse deleteResponse = client.delete(request, RequestOptions.DEFAULT); System.out.println(deleteResponse.status() == RestStatus.OK); }
九、高级查询
1、排序查询
/** * 排序查询(sort) 代码同matchAllQuery * 匹配查询符合条件的所有数据,并设置分页 */ @Test public void sortQuery() { try { // 构建查询条件 MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery(); // 创建查询源构造器 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(matchAllQueryBuilder); // // 设置分页 // searchSourceBuilder.from(0); // searchSourceBuilder.size(3); // 设置排序 searchSourceBuilder.sort("id", SortOrder.ASC); // 创建查询请求对象,将查询对象配置到其中 SearchRequest searchRequest = new SearchRequest("employee_alias"); searchRequest.source(searchSourceBuilder); // 执行查询,然后处理响应结果 SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); // 根据状态和数据条数验证是否返回了数据 if (RestStatus.OK.equals(searchResponse.status())) { SearchHits hits = searchResponse.getHits(); for (SearchHit hit : hits) { // 将 JSON 转换成对象 Employee userInfo = JSON.parseObject(hit.getSourceAsString(), Employee.class); // 输出查询信息 log.info(userInfo.toString()); } } } catch (IOException e) { log.error("", e); } }
2、聚合查询(一)
查询30岁以上、30岁及以下员工的平均年龄:
@Test public void bucketQuery() { // 创建查询源构造器 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); // 创建查询请求对象,将查询对象配置到其中 SearchRequest searchRequest = new SearchRequest("employee"); RangeAggregationBuilder rangeAggregationBuilder = AggregationBuilders.range("age_ranges_avg") .field("age") .addRange(0, 30) .addRange(31, 100).subAggregation(AggregationBuilders.avg("avgAge").field("age")); searchSourceBuilder.aggregation(rangeAggregationBuilder); searchRequest.source(searchSourceBuilder); SearchResponse response; try { //发起请求,获取响应结果 response = client.search(searchRequest, RequestOptions.DEFAULT); //获取聚合的结果 Aggregations aggregations = response.getAggregations(); Aggregation aggregation = aggregations.get("age_ranges_avg"); System.out.println(JSON.toJSONString(aggregation)); //获取桶聚合结果 List extends Range.Bucket> buckets = ((Range) aggregation).getBuckets(); //循环遍历各个桶结果 for (Range.Bucket bucket : buckets) { //分组的key String key = bucket.getKeyAsString(); //分组的值 long docCount = bucket.getDocCount(); ParsedAvg avgAge = bucket.getAggregations().get("avgAge"); System.out.println(key + "======平均年龄:" + avgAge.getValue() + "======数量:" + docCount); } } catch (IOException e) { e.printStackTrace(); } }
3、聚合查询(二)
/** * 聚合查询 * Metric 指标聚合分析 */ @Test public void metricQuery() { try { // 构建查询条件 MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery(); // 创建查询源构造器 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(matchAllQueryBuilder); // 获取最贵的商品 AggregationBuilder maxAge = AggregationBuilders.max("maxAge").field("age"); searchSourceBuilder.aggregation(maxAge); // 获取最便宜的商品 AggregationBuilder minAge = AggregationBuilders.min("minAge").field("age"); searchSourceBuilder.aggregation(minAge); // 创建查询请求对象,将查询对象配置到其中 SearchRequest searchRequest = new SearchRequest("employee"); searchRequest.source(searchSourceBuilder); // 执行查询,然后处理响应结果 SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); Aggregations aggregations = searchResponse.getAggregations(); ParsedMax max = aggregations.get("maxAge"); log.info("最年长:" + max.getValue()); ParsedMin min = aggregations.get("minAge"); log.info("最年轻:" + min.getValue()); } catch (IOException e) { log.error("", e); } }
4、模糊查询
//模糊查询,原理是构建DFA,查询名字中含有“文”的员工 @Test public void fuzzyQuery() { try { // 构建查询条件 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.fuzzyQuery("name", "洁").fuzziness(Fuzziness.AUTO)); // 创建查询请求对象,将查询对象配置到其中 SearchRequest searchRequest = new SearchRequest("employee"); searchRequest.source(searchSourceBuilder); // 执行查询,然后处理响应结果 SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); // 根据状态和数据条数验证是否返回了数据 if (RestStatus.OK.equals(searchResponse.status())) { SearchHits hits = searchResponse.getHits(); for (SearchHit hit : hits) { // 将 JSON 转换成对象 Employee userInfo = JSON.parseObject(hit.getSourceAsString(), Employee.class); // 输出查询信息 log.info(userInfo.toString()); } } } catch (IOException e) { log.error("", e); } }
5、范围查询
//查询20岁以上的员工 @Test public void rangeQuery() { try { // 构建查询条件 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.rangeQuery("age").gte(20)); // 创建查询请求对象,将查询对象配置到其中 SearchRequest searchRequest = new SearchRequest("employee"); searchRequest.source(searchSourceBuilder); // 执行查询,然后处理响应结果 SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); // 根据状态和数据条数验证是否返回了数据 if (RestStatus.OK.equals(searchResponse.status()) ) { SearchHits hits = searchResponse.getHits(); //log.info(hits.getTotalHits().value + ""); for (SearchHit hit : hits) { // 将 JSON 转换成对象 Employee userInfo = JSON.parseObject(hit.getSourceAsString(), Employee.class); // 输出查询信息 log.info(userInfo.toString()); } } } catch (IOException e) { log.error("", e); } }
6、多字段查询
multi_match进行多字段匹配查询,进行权重控制
GET pig/_search { "query": { "multi_match": { "query": "小猪佩奇", "fields": ["name^3","occupation"] } } }
@Test public void matchQuery() { try { // 构建查询条件 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); Mapfields = new HashMap(2); fields.put("name", 1.0f); fields.put("occupation", 1.0f); // QueryBuilder queryBuilder = null; // queryBuilder.must(QueryBuilders.multiMatchQuery("name","小猪佩奇").fields(fields).analyzer("ik_smart")); searchSourceBuilder.query(QueryBuilders.multiMatchQuery("小猪佩奇","name","occupation").fields(fields).analyzer("pinyin")); // 创建查询请求对象,将查询对象配置到其中 SearchRequest searchRequest = new SearchRequest("pig"); searchRequest.source(searchSourceBuilder); // 执行查询,然后处理响应结果 SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); // 根据状态和数据条数验证是否返回了数据 if (RestStatus.OK.equals(searchResponse.status()) ) { SearchHits hits = searchResponse.getHits(); for (SearchHit hit : hits) { // 将 JSON 转换成对象 Employee userInfo = JSON.parseObject(hit.getSourceAsString(), Employee.class); // 输出查询信息 log.info(userInfo.toString()); } } } catch (IOException e) { log.error("", e); } }
还没有评论,来说两句吧...