好玩的ES--第三篇之过滤查询,整合SpringBoot

  • 过滤查询
    • 过滤查询
    • 使用
    • 类型
      • term 、 terms Filter
      • ranage filter
      • exists filter
      • ids filter
  • 整合应用
    • 引入依赖
    • 配置客户端
    • 客户端对象
      • ElasticsearchOperations
        • 索引文档
        • 删除文档
        • 查询文档
        • 更新文档
        • 删除所有
        • 查询所有
      • RestHighLevelClient
        • 创建索引映射
        • 索引文档
        • 更新文档
        • 删除文档
        • 基于 id 查询文档
        • 查询所有
        • 综合查询
        • 过滤查询
        • 思路扩展

好玩的ES—第一篇之安装和基本CRUD

好玩的ES–第二篇之高级查询,索引原理和分词器


过滤查询

过滤查询

过滤查询,其实准确来说,ES中的查询操作分为2种: 查询(query)过滤(filter)。查询即是之前提到的query查询,它 (查询)默认会计算每个返回文档的得分,然后根据得分排序。而过滤(filter)只会筛选出符合的文档,并不计算 得分,而且它可以缓存文档 。所以,单从性能考虑,过滤比查询更快。 换句话说过滤适合在大范围筛选数据,而查询则适合精确匹配数据。一般应用时, 应先使用过滤操作过滤数据, 然后使用查询匹配数据。

使用

GET /ems/emp/_search
{"query": {"bool": {"must": [{"match_all": {}} //查询条件],"filter": {....} //过滤条件}
}
  • 注意:

    • 在执行 filter 和 query 时,先执行 filter 在执行 query
    • Elasticsearch会自动缓存经常使用的过滤器,以加快性能。

类型

常见过滤类型有: term 、 terms 、ranage、exists、ids等filter。

term 、 terms Filter

GET /ems/emp/_search   # 使用term过滤
{"query": {"bool": {"must": [{"term": {"name": {"value": "小黑"}}}],"filter": {"term": {"content":"框架"}}}}
}
GET /dangdang/book/_search  #使用terms过滤
{"query": {"bool": {"must": [{"term": {"name": {"value": "中国"}}}],"filter": {"terms": {"content":["科技","声音"]}}}}
}

ranage filter

GET /ems/emp/_search
{"query": {"bool": {"must": [{"term": {"name": {"value": "中国"}}}],"filter": {"range": {"age": {"gte": 7,"lte": 20}}}}}
}

exists filter

过滤存在指定字段,获取字段不为空的索引记录使用

GET /ems/emp/_search
{"query": {"bool": {"must": [{"term": {"name": {"value": "中国"}}}],"filter": {"exists": {"field":"aaa"}}}}
}

ids filter

过滤含有指定字段的索引记录

GET /ems/emp/_search
{"query": {"bool": {"must": [{"term": {"name": {"value": "中国"}}}],"filter": {"ids": {"values": ["1","2","3"]}}}}
}

整合应用

引入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

配置客户端

@Data
@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {@Value("${es.host}")private String ES_HOST;@Override@Beanpublic RestHighLevelClient elasticsearchClient() {final ClientConfiguration clientConfiguration = ClientConfiguration.builder().connectedTo(ES_HOST).build();return RestClients.create(clientConfiguration).rest();}
}

es默认开放了两个端口进行访问,一个是9200的rest方式访问,一个是9300的tcp方式访问,这里推荐使用9200rest方式的访问


客户端对象

  • ElasticsearchOperations
  • RestHighLevelClient 推荐

ElasticsearchOperations

  • 特点: 始终使用面向对象方式操作 ES

    • 索引: 用来存放相似文档集合
    • 映射: 用来决定放入文档的每个字段以什么样方式录入到 ES 中 字段类型 分词器…
    • 文档: 可以被索引最小单元 json 数据格式

相关注解

@Data
@Document(indexName = "products", createIndex = true)
public class Product {@Idprivate Integer id;@Field(type = FieldType.Keyword)private String title;@Field(type = FieldType.Float)private Double price;@Field(type = FieldType.Text)private String description;
}
//1. @Document(indexName = "products", createIndex = true) 用在类上 作用:代表一个对象为一个文档-- indexName属性: 创建索引的名称-- createIndex属性: 是否创建索引
//2. @Id 用在属性上  作用:将对象id字段与ES中文档的_id对应
//3. @Field(type = FieldType.Keyword) 用在属性上 作用:用来描述属性在ES中存储类型以及分词情况-- type: 用来指定字段类型

索引文档

    @Testpublic void testCreate() throws IOException {Product product = new Product();product.setId(1); //存在id指定id  不存在id自动生成idproduct.setTitle("怡宝矿泉水");product.setPrice(129.11);product.setDescription("我们喜欢喝矿泉水....");//文档不存在会创建文档,文档存在会更新文档elasticsearchOperations.save(product);}

删除文档

    @Testpublic void testDelete() {Product product = new Product();product.setId(1);String delete = elasticsearchOperations.delete(product);System.out.println(delete);}

查询文档

    @Testpublic void testGet() {Product product = elasticsearchOperations.get("1", Product.class);System.out.println(product);}

更新文档

 @Test
public void testUpdate() {Product product = new Product();product.setId(1);product.setTitle("怡宝矿泉水");product.setPrice(129.11);product.setDescription("我们喜欢喝矿泉水,你们喜欢吗....");elasticsearchOperations.save(product);//不存在添加,存在更新
}

删除所有

@Test
public void testDeleteAll() {elasticsearchOperations.delete(Query.findAll(), Product.class);
}

查询所有

@Test
public void testFindAll() {SearchHits<Product> productSearchHits = elasticsearchOperations.search(Query.findAll(), Product.class);productSearchHits.forEach(productSearchHit -> {System.out.println("id: " + productSearchHit.getId());System.out.println("score: " + productSearchHit.getScore());Product product = productSearchHit.getContent();System.out.println("product: " + product);});
}

RestHighLevelClient

创建索引映射

    @Testpublic void testCreateIndex() throws IOException {CreateIndexRequest createIndexRequest = new CreateIndexRequest("fruit");createIndexRequest.mapping("{\n" +"    \"properties\": {\n" +"      \"title\":{\n" +"        \"type\": \"keyword\"\n" +"      },\n" +"      \"price\":{\n" +"        \"type\": \"double\"\n" +"      },\n" +"      \"created_at\":{\n" +"        \"type\": \"date\"\n" +"      },\n" +"      \"description\":{\n" +"        \"type\": \"text\"\n" +"      }\n" +"    }\n" +"  }\n" , XContentType.JSON);CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);System.out.println(createIndexResponse.isAcknowledged());restHighLevelClient.close();}


索引文档

    @Testpublic void testIndex() throws IOException {IndexRequest indexRequest = new IndexRequest("fruit");indexRequest.source("{\n" +"          \"id\" : 1,\n" +"          \"title\" : \"蓝月亮\",\n" +"          \"price\" : 123.23,\n" +"          \"description\" : \"这个洗衣液非常不错哦!\"\n" +"        }",XContentType.JSON);IndexResponse index = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);System.out.println(index.status());}

更新文档

    @Testpublic void testUpdate() throws IOException {UpdateRequest updateRequest = new UpdateRequest("fruit","qJ0R9XwBD3J1IW494-Om");updateRequest.doc("{\"title\":\"好月亮\"}",XContentType.JSON);UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);System.out.println(update.status());}

删除文档

    @Testpublic void testDelete() throws IOException {DeleteRequest deleteRequest = new DeleteRequest("fruit","1");DeleteResponse delete = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);System.out.println(delete.status());}

基于 id 查询文档

    @Testpublic void testGet() throws IOException {GetRequest getRequest = new GetRequest("fruit","aPbmV38BvtuRfHsTIvNo");GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);System.out.println(getResponse.getSourceAsString());}

查询所有

    public void commonExampleSearch(String indice, QueryBuilder queryBuilder) throws IOException {SearchRequest searchRequest = new SearchRequest(indice);SearchSourceBuilder sourceBuilder=new SearchSourceBuilder();sourceBuilder.query(queryBuilder);searchRequest.source(sourceBuilder);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);System.out.println("总记录数: "+searchResponse.getHits().getTotalHits().value);System.out.println("最大得分: "+searchResponse.getHits().getMaxScore());SearchHit[] hits = searchResponse.getHits().getHits();for (SearchHit hit : hits) {System.out.println(hit.getSourceAsString());}}@Testpublic void testSearch() throws IOException {String indice="fruit";//查询所有commonExampleSearch(indice,QueryBuilders.matchAllQuery());//term查询commonExampleSearch(indice,QueryBuilders.termQuery("description","不错哦!"));//prefix查询commonExampleSearch(indice,QueryBuilders.prefixQuery("description","这个"));//通配符查询commonExampleSearch(indice,QueryBuilders.wildcardQuery("title","好*"));//ids查询--多id查询commonExampleSearch(indice,QueryBuilders.idsQuery().addIds("1","2"));//多字段查询commonExampleSearch(indice,QueryBuilders.multiMatchQuery("不错","title","description"));}

综合查询

    @Testpublic void testSearch1() throws IOException {SearchRequest searchRequest = new SearchRequest("fruit");SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();sourceBuilder//分页查询.from(0)//起始位置 start=(page-1)*size.size(2)//每页显示条数,默认返回10条//指定排序字段,参数一:根据哪个字段进行排序,参数二:排序方式.sort("price", SortOrder.DESC)//返回的结果中排除或者包含哪些字段//参数1:包含的字段数组//参数2:排除字段数组.fetchSource(new String[]{"title"},new String[]{})//高亮设置.highlighter(new HighlightBuilder()//高亮显示的字段.field("description")//多字段高亮开启.requireFieldMatch(false)//自定义高亮html标签.preTags("<span style='color:red;'>").postTags("</span>"))//查询.query(QueryBuilders.termQuery("description","错"));searchRequest.source(sourceBuilder);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);System.out.println("总条数: "+searchResponse.getHits().getTotalHits().value);SearchHit[] hits = searchResponse.getHits().getHits();for (SearchHit hit : hits) {System.out.println(hit.getSourceAsString());//显示当前查询结果中出现的高亮字段Map<String, HighlightField> highlightFields = hit.getHighlightFields();highlightFields.forEach((k,v)-> System.out.println("key: "+k + " value: "+v.fragments()[0]));}}

过滤查询

    /*** query: 精确查询,查询计算文档得分,并根据文档得分进行返回* filter query: 过滤查询,用来在大量数据中筛选出本地查询相关数据,不会计算文档得分,经常使用filter query结果进行缓存* 注意: 一旦使用query和filterQuery es优先执行filter query 然后再执行 query*/@Testpublic void testFilterQuery() throws IOException {SearchRequest searchRequest=new SearchRequest("fruit");SearchSourceBuilder sourceBuilder=new SearchSourceBuilder();sourceBuilder.query(QueryBuilders.termQuery("description","不错"))//指定过滤条件.postFilter(QueryBuilders.idsQuery().addIds("1","2","3"));searchRequest.source(sourceBuilder);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);System.out.println("符合条件的总数为: "+searchResponse.getHits().getTotalHits().value);}

思路扩展

ElasticsearchOperations面向对象的查询方式,有其优点所在,那么我们能否将其和RestHighLevelClient 进行互补呢 ?

看下面的例子:

@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class Fruit implements Serializable {private String title;private Double price;private Date create_at;private String description;
}
/*** @author 大忽悠* @create 2022/3/5 11:34*/
public class AllTest extends EsApplicationTests{ObjectMapper objectMapper=new ObjectMapper();/*** 添加文档*/@Testpublic void addIndice() throws IOException {Fruit fruit = Fruit.builder().id(5).title("大忽悠").price(520.521).description("大忽悠喜欢小朋友").build();IndexRequest indexRequest=new IndexRequest("fruit");indexRequest.id(fruit.getId().toString()).source(objectMapper.writeValueAsString(fruit),XContentType.JSON);IndexResponse index = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);System.out.println(index.status());}public void commonExampleSearch(String indice, QueryBuilder queryBuilder) throws IOException {SearchRequest searchRequest = new SearchRequest(indice);SearchSourceBuilder sourceBuilder=new SearchSourceBuilder();sourceBuilder.query(queryBuilder);searchRequest.source(sourceBuilder);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);System.out.println("总记录数: "+searchResponse.getHits().getTotalHits().value);System.out.println("最大得分: "+searchResponse.getHits().getMaxScore());SearchHit[] hits = searchResponse.getHits().getHits();for (SearchHit hit : hits) {System.out.println("返回的结果为: "+hit.getSourceAsString());//JSON格式转换Fruit fruit = objectMapper.readValue(hit.getSourceAsString(), Fruit.class);System.out.println("得到的结果为: "+fruit);}}/*** 查询全部*/@Testpublic void searchAll() throws IOException {String indice="fruit";//查询所有commonExampleSearch(indice, QueryBuilders.matchAllQuery());}
}

注意: 两者的区别,因此我们在上传文档的时候,一定要通过objectMapper.writeValueAsString(fruit)的方式先转换为JSON串的原因

        Fruit fruit = Fruit.builder().id(5).title("大忽悠").price(520.521).description("大忽悠喜欢小朋友").build();System.out.println(objectMapper.writeValueAsString(fruit));System.out.println(fruit);

好玩的ES--第三篇之过滤查询,整合SpringBoot相关推荐

  1. mysql怎么分组计算逾期率_转行数据分析第三篇:mysql查询入门练习题

    这篇练习题是我在学sql入门的时候做的,应该算是在网上能找到的习题里最基础的一篇,非常适合新手练习,如果你接触sql不超过半个月,建议可以看一下<sql必知必会>或<mysql必知必 ...

  2. MySQL代做题_转行数据分析第三篇:mysql查询入门练习题

    这篇练习题是我在学sql入门的时候做的,应该算是在网上能找到的习题里最基础的一篇,非常适合新手练习,如果你接触sql不超过半个月,建议可以看一下<sql必知必会>或<mysql必知必 ...

  3. 第三篇:Spring Boot整合Servlet

    一.Springboot整合Servlet 第一种方案: 1.创建一个自定义的servlet,继承HttpServlet添加@WebServlet注解 以前ssm中的web.xml配置文件中的serv ...

  4. 电力负荷预测三篇综述总结

    三篇综述链接: 深度学习方法在负荷预测中的应用综述(论文阅读) 光伏发电量和用电量的概率预测研究综述(1) 光伏发电量和用电量的概率预测研究综述(2) 光伏发电量和用电量的概率预测研究综述(3) 能源 ...

  5. ElasticSearch查询 第四篇:匹配查询(Match)

    <ElasticSearch查询>目录导航: ElasticSearch查询 第一篇:搜索API ElasticSearch查询 第二篇:文档更新 ElasticSearch查询 第三篇: ...

  6. 第三篇 KinectV2骨骼获取原理和获取方法及源代码

    第三篇  KinectV2骨骼获取原理和获取方法及源代码 首先声明一下,本系统所使用的开发环境版本是计算机系统Windows 10.Visual Studio 2013.Opencv3.0和Kinec ...

  7. 【数字智能三篇】之二: 一页纸说清楚“什么是推荐系统?”

    按:[数字智能三篇] 目前"大数据"."推荐系统"."深度学习"是数字智能领域的热点研究方向,相关的书籍也很火热,比如"大数据&q ...

  8. PHP 性能分析第三篇: 性能调优实战

    注意:本文是我们的 PHP 性能分析系列的第三篇,点此阅读 PHP 性能分析第一篇: XHProf & XHGui 介绍 ,或  PHP 性能分析第二篇: 深入研究 XHGui. 在本系列的 ...

  9. 幼儿园体育游戏电子计算机教案,幼儿园体育游戏《学会跳绳》教案三篇

    [导语]让幼儿体验创造性玩绳的乐趣,引导幼儿能变换多种花样玩绳,发展幼儿动作的协调能力.增强身体机能,教幼儿抡长绳,跳大绳,锻炼孩子的跳跃能力以及孩子的节奏感.无忧考网准备了以下教案,希望对你有帮助! ...

最新文章

  1. 节后综合征疗愈神器,这个开源项目帮你10分钟上手AI算法开发!
  2. ibm服务器报错代码大全_微信认证订阅号开发者模式服务器配置自定义菜单PHP独立完整版...
  3. FPGA逻辑设计回顾(12)RAM以及ROM的RTL设计及其验证
  4. 关于sqlite数据库在使用过程中应该注意以下几点
  5. java同名过滤器_Gateway Redis令牌桶请求限流过滤器
  6. 如何写一个Python万能装饰器,既可以装饰有参数的方法,也可以装饰无参数方法,或者有无返回值都可以装饰
  7. 系统防止绕过程序直接数据库修改数据(金额等敏感数据)
  8. 常见的爬虫分析库(1)-Python3中Urllib库基本使用
  9. can总线报文是固定的吗_CAN总线负载率的计算方式
  10. Atitit it系列书籍列表 C:\Users\Administrator\Documents\it 软件系列书籍\itlist.txt C:\Users\Administrator\Docume
  11. 恐怖的死亡艺术,稻川淳二为自己办了场VR葬礼
  12. 【线性分类器】线性分类器理论知识
  13. python初学入门教程_初学python编程入门教程
  14. [软件笔试] 2014暴风影音校招技术笔试题(长春站)
  15. 的概念产生于计算机芯片,是指采用光导原位合成或微量点样等方法,,微阵列芯片...
  16. 通过自定义注解+反射的形式,使用POI实现excel的导入导出
  17. 全球计算机病毒损失报告,世界十大计算机病毒 CIH的危险被公认,第二经济损失26亿美元...
  18. 使用git push没有报错,但是远程仓库没有更新的问题
  19. MT8173芯片资料,MT8173处理器参数介绍
  20. Java基础知识系列之-抽象abstract

热门文章

  1. QQ 键盘加密保护分析
  2. 干辣椒和鲜辣椒的区别
  3. Python+OpenCV实用案例应用教程:建立自定义物体检测器
  4. iOS 15 UITableView Section间距变大
  5. 优美图案c语言程序,C语言编程之一个最优美的图案
  6. ImageMagick将多张图片拼接成一张图片_word转存技巧:如何将每页文档转换为图片保存?...
  7. git克隆项目带用户名密码
  8. 水平垂直居中的几种方式
  9. 商业模式笔记以及体悟
  10. vue动态加载图片问题