当前位置: 首页 > news >正文

AWS OpenSearch 搜索排序常见用法

背景介绍

AWS OpenSearch是AWS的一个检索分析服务,是基于开源的Elasticsearch 7.x分支fork出来的独立的一个代码仓库,做了独立的维护,加入了一些自己的优化,本文在这里主要介绍是常见的基础用法

引入相关依赖

 <dependency><groupId>org.opensearch.client</groupId><artifactId>opensearch-java</artifactId><version>2.17.0</version></dependency>

查询返回指定属性字段

按照前端要求的返回字段(“productId”, “title”, “rating”, “images”,“productTags”)进行返回,而不是返回所有字段

SearchResponse<ProductVO> search = openSearchClient.search(s -> s.index("product_index").source(c -> c.filter(e -> e.includes("productId", "title", "rating",  "images","productTags"))).query(q -> q.terms(t -> t.field("productId").terms(ts -> ts.value(values)))),ProductVO.class);

分页查询返回

根据前端传入的分页参数,当前页(pageNo)和每页的条数(pageSize)执行查询

  PageResult<ProductVO> pageResult = new PageResult<>();Integer pageIndex = requestVO.getPageNo();int pageSize = requestVO.getPageSize() != null ? requestVO.getPageSize() : 10;int from = (pageIndex - 1) * pageSize;
SearchResponse<ProductVO> search = openSearchClient.search(s -> s.index("product_index").source(c -> c.filter(e -> e.includes("productId", "title", "rating",  "images","productTags"))).from(from).size(pageSize).query(q -> q.terms(t -> t.field("productId").terms(ts -> ts.value(values)))),ProductVO.class);
List<ProductVO> productList = Lists.newArrayList();                    
if (CollectionUtils.isNotEmpty(search.hits().hits())) {search.hits().hits().forEach(h -> {ProductVO productVo = h.source();productList.add(productVo);});}int total = Math.toIntExact(search.hits().total().value());pageResult.setCurrentPage(pageIndex);pageResult.setPageSize(pageSize);pageResult.setTotal(total);if (pageResult.getTotal() % pageResult.getPageSize() == 0) {pageResult.setTotalPage(pageResult.getTotal() / pageResult.getPageSize());} else {pageResult.setTotalPage((pageResult.getTotal() / pageResult.getPageSize()) + 1);}pageResult.setItems(productList);

复合查询

List<Query> mustQueryList = new ArrayList<>();
List<Query> mustNotQueryList = new ArrayList<>();List<FieldValue> values = new ArrayList<>();
List<String> languages = List.of("zh");
languages.forEach(c -> {values.add(FieldValue.of(c));
});
int rating = Integer.parseInt("4.5");
Query ratingQuery = RangeQuery.of(r -> r.field("rating").gte(JsonData.of(rating - 0.25)).lt(JsonData.of(rating + 0.75))).toQuery();List<FieldValue> categoriesValues = new ArrayList<>();
categoriesValues.add(FieldValue.of("CA0001","CA0002"));
Query nestedQuery = NestedQuery.of(n -> n.path("categories").query(q -> q.terms(r -> r.field("categories.id").terms(t -> t.value(categoriesValues)).boost(1000f)))
).toQuery();
mustQueryList.add(TermsQuery.of(t -> t.field("language").terms(new TermsQueryField.Builder().value(values).build())).toQuery());
mustQueryList.add(ratingQuery);
mustNotQueryList.add(nestedQuery);
Query complexQuery = BoolQuery.of(b -> b.must(mustQueryList).mustNot(mustNotQueryList)).toQuery();
SearchResponse<ProductVO> search = openSearchClient.search(s -> s.index("product_index").source(c -> c.filter(e -> e.includes("productId", "title", "rating",  "images","productTags"))).from(from).size(pageSize).query(complexQuery),ProductVO.class);

聚合统计

以下是聚合查询商品每个评分的数量

 Aggregation aggregation = Aggregation.of(a -> a.terms(ts -> ts.field("rating").size(1000)));
SearchResponse<ProductBO> search = openSearchClient.search(s -> s.index("product_index").source(c -> c.filter(e -> e.includes("productId", "title", "rating"))).aggregations("ratingAgg", aggregation).query(filterQuery),ProductBO.class);
if (null != search.aggregations()) {Collection<Aggregate> aggregateCollection = search.aggregations().values();List<FacetHit> facetHitsList = Lists.newArrayList();aggregateCollection.forEach(aggregate -> {String kind = aggregate._kind().name();log.info("The aggregation type is {}", kind);switch (kind) {case "Nested" -> {Collection<Aggregate> nestedAggregateCollection = aggregate.nested().aggregations().values();nestedAggregateCollection.forEach(nestedAggregate -> {addFacetHits(nestedAggregate, facetHitsList);});}case "Sterms" -> {addFacetHits(aggregate, facetHitsList);}case "Dterms" -> {Buckets<DoubleTermsBucket> buckets = aggregate.dterms().buckets();buckets.array().forEach(bucket -> {String key = String.valueOf(bucket.key());FacetHit facetHit = new FacetHit();facetHit.setCount(Math.toIntExact(bucket.docCount()));facetHit.setValue(key);facetHitsList.add(facetHit);});}default -> log.warn("Unrecognized type:{} cannot be processed", kind);}});
}private void addFacetHits(Aggregate aggregate, List<FacetHit> facetHitsList) {Buckets<StringTermsBucket> buckets = aggregate.sterms().buckets();List<StringTermsBucket> stringTermsBuckets = buckets.array();stringTermsBuckets.forEach(s -> {String key = s.key();long docCount = s.docCount();FacetHit facetHit = new FacetHit();facetHit.setCount(Math.toIntExact(docCount));Aggregate parentAggregate = s.aggregations().get("parent_docs");if (null != parentAggregate && AggregateConstants.KIND_REVERSE_NESTED.equals(parentAggregate._kind().name())) {ReverseNestedAggregate reverseNested = parentAggregate.reverseNested();if (reverseNested != null) {long parentDocCount = reverseNested.docCount();facetHit.setCount(Math.toIntExact(parentDocCount));}}facetHit.setValue(key);facetHitsList.add(facetHit);});
}

基础排序

按照定义的排序字段进行排序

SearchResponse<ProductVO> search = openSearchClient.search(s -> s.index("product_index").source(c -> c.filter(e -> e.includes("productId", "title", "rating",  "images","productTags"))).from(from).size(pageSize).query(q -> q.terms(t -> t.field("productId").terms(ts -> ts.value(values)))).sort(t -> t.field(f -> f.field("publishDate").order(SortOrder.Desc))) .sort(t -> t.field(f -> f.field("rating").order(SortOrder.Desc))),ProductVO.class);

高阶排序

按照特定的一批商品排在查询结果的最前面

List<String> topProductIdList = List.of("1","2");//特定的商品编号
SearchResponse<ProductVO> search = openSearchClient.search(s -> s.index("product_index").source(c -> c.filter(e -> e.includes("productId", "title", "rating",  "images","productTags"))).from(from).size(pageSize).query(q -> q.terms(t -> t.field("productId").terms(ts -> ts.value(values)))).sort(getHightSortOptions(topProductIdList)), ProductVO.class);private List<SortOptions> getHightSortOptions(List<String> topProductIdList) {List<SortOptions> sortOptions = Lists.newArrayList();sortOptions.add(SortOptions.of(f -> f.script(st -> st.type(ScriptSortType.Number).script(Script.of(sf -> sf.inline(ie -> ie.source("params.topProductIds.indexOf(doc['productId'].value) >= 0 ? params.topProductIds.indexOf(doc['productId'].value) : params.topProductIds.size()").lang("painless").params(Map.of("topProductIds", JsonData.of(topProductIdList)))))).order(SortOrder.Asc))));sortOptions.add(SortOptions.of(t -> t.field(f -> f.field("rating").order(SortOrder.Desc))));sortOptions.add(SortOptions.of(t -> t.field(f -> f.field("publishDate").order(SortOrder.Desc))));return sortOptions;}

查看OpenSearch的数据

可以通过OpenSearch dashboard查看,如下图所示:
在这里插入图片描述

http://www.dtcms.com/a/292804.html

相关文章:

  • 2️⃣tuple(元组)速查表
  • C语言面向对象编程
  • Java函数式编程深度解析:从基础到高阶应用
  • Leetcode题解:209长度最小的子数组,掌握滑动窗口从此开始!!!
  • 光伏电站智能数据采集系统解决方案
  • SpringBoot PO VO BO POJO实战指南
  • 十进制小数转换为二进制表示 ← 除2取余法+乘2取整法
  • csp基础知识——递推
  • SMTP+VRRP实验
  • Markdown 转 PDF API 数据接口
  • REASONING ELICITATION IN LANGUAGE MODELSVIA COUNTERFACTUAL FEEDBACK
  • 高性能线程安全的时间有序 UUID 生成器 —— 基于 ThreadLocal 的实现
  • 实操:AWS CloudFront的动态图像转换
  • Cadence 原理图如何给网络名称添加页码
  • 『React』条件渲染的7种方法
  • 基于Prompt 的DevOps 与终端重塑
  • 装备数字孪生底座平台探索
  • HTTP 协议常见字段(请求头/响应头)
  • 虚幻5入门教程:如何在虚幻5中创建一个C++的Plugin
  • android 12 的 aidl for HAL 开发示例
  • VR技术在元宇宙游戏中的作用及发展前景深度分析
  • Fluent许可与网络安全策略
  • 基于JSP的快递管理系统/快递寄出管理系统
  • 初识opencv01——基本api操作
  • Transactional事务不生效案例与解决方案?
  • 基于深度学习Transform的steam游戏特征分析与可视化【词云-情感词典分析-主题分析-词频分析-关联分析】
  • Android 自动的文件管理器存在以下问题,文件管理器横竖屏切换会停止运行,如何解决
  • 多维基分析求导法则
  • DNS应用层协议
  • OEC 刷机Armbain 25.05后配置说明