背景介绍

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.pswp.cn/pingmian/90251.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/90251.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/90251.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度分析Java内存结构

Java内存结构是JVM的核心机制&#xff0c;直接关系到程序性能、并发能力和稳定性。下面从规范、实现到实践进行深度分析&#xff1a;一、JVM规范定义的内存区域 1. 程序计数器&#xff08;Program Counter Register&#xff09; 作用&#xff1a;存储当前线程执行的字节码指令地…

vs2019 创建MFC ActiveX的详细步骤

第一步 创建1个MFC ActiveX控件工程 添加方法 输入方法名称选择返回类型点击 添加参数&#xff0c;最后点击确认&#xff0c;如下图 添加的Add方法 注意&#xff0c;如需要添加1个指针类型的参数&#xff0c;需要手动输入* 最后编译&#xff0c;如编译出现下图错误&#xf…

pyarmor加密源代码

使用低版本python 避免出现加密限制&#xff0c;无法加密情况 环境&#xff1a;python3.9.9 安装 pyinsatller 及 pyarmor pip install pyinsatller pyarmor添加 其它pyinstaller 打包参数 一定在下边正式打包命令运行前执行 具体参考 https://pyarmor.readthedocs.io/zh/stabl…

MACOS安装配置Gradle

一、概述 gradle的运行高度依赖jvm版本&#xff0c;所以在安装之前一定要先安装jdk&#xff0c;同时gradle版本必须与jdk版本对应&#xff0c;不然在项目编译的时候会报版本不兼容导致编译不成功的问题。 官方说明地址 以下是官方列出关系对应版本的关系列表&#xff1a; 本文…

1.1.2 建筑构造要求

1、建筑构造的影响因素1&#xff09;荷载因素&#xff08;受力&#xff09;&#xff1a;结构自重、活荷载、风荷载、雪荷载、地震作用2&#xff09;环境因素&#xff1a;自然因素&#xff08;风吹、日晒、雨淋、积雪、冰冻、地下水、地震等&#xff09;、人为因素&#xff08;火…

gig-gitignore工具实战开发(一):项目愿景与蓝图规划

文章目录gig-gitignore工具实战开发&#xff08;一&#xff09;&#xff1a;项目愿景与蓝图规划 &#x1f680;&#x1f631; 一、痛点&#xff1a;被忽视的.gitignore&#x1f3af; 二、愿景&#xff1a;.gitignore的全生命周期管理&#x1f6e0;️ 三、核心功能规划&#x1f…

C# 基于halcon的视觉工作流-章22-直线查找

C# 基于halcon的视觉工作流-章22-直线查找 本章目标&#xff1a; 一、创建直线卡尺工具&#xff1b; 二、测量及拟合直线&#xff1b; 三、匹配批量查找&#xff1b;寻找整图中所有直线&#xff0c;可用霍夫直线查找等算法&#xff0c;而寻找图片中指定区域的直线&#xff0c;除…

统计与大数据分析与数学金融方向课程差异有哪些?如何提升职场竞争力?

准大一新生在选择专业时&#xff0c;常常会在 “统计与大数据分析” 和 “数学金融” 之间犹豫不决。这两个专业看似都与数字、模型打交道&#xff0c;课程设置存在一定交叉&#xff0c;但核心方向又各有侧重。深入了解它们的异同&#xff0c;能为专业选择和学习规划提供更清晰…

游戏开发Unity/ ShaderLab学习路径

掌握 ShaderLab 需要循序渐进地学习&#xff0c;结合理论、实践和工具。以下是一个推荐的学习路径&#xff0c;帮助你从零基础逐步进阶&#xff1a; 阶段一&#xff1a;基础准备 (理解核心概念与环境)必备知识&#xff1a; 编程基础&#xff1a; 至少熟悉一种编程语言&#xff…

算法----二叉搜索树(BST)

系列文章目录 算法----滑动窗口 算法----二叉树 文章目录系列文章目录二叉搜索树心法&#xff08;特性篇&#xff09;二叉搜索树心法&#xff08;基操篇&#xff09;1、判断 BST 的合法性2、在 BST 中搜索元素3、在 BST 中插入一个数4、在 BST 中删除一个数二叉搜索树心法&…

GitHub Actions打包容器,推送 AWS ECR 并使 EKS 自动拉取以完成发版部署

以下是关于 EKS 直接拉取 ECR 镜像的解答&#xff0c;以及如何通过 GitHub Actions 将项目打包为容器、推送至 AWS ECR 并使 EKS 自动拉取以完成发版部署的详细步骤。当前时间为 2025 年 7 月 23 日下午 12:27 HKT&#xff0c;基于最新技术实践提供方案。1. EKS 直接拉取 ECR 镜…

洛谷刷题7.24

P1087 [NOIP 2004 普及组] FBI 树 - 洛谷 简单的二叉树遍历 #include<bits/stdc.h> #define ll long long using namespace std; int n; char show(string s){if(s.find(1)string::npos) return B;if(s.find(0)string::npos) return I;return F; } void dfs(string s){…

FreeRTOS—二值信号量

文章目录一、二值信号量简介二、二值信号量相关的API函数2.1.动态方式创建二值信号量2.2.获取信号量2.3.释放信号量三、实验3.1.实验设计3.2.软件设计一、二值信号量简介 二值信号量的本质是一个队列长度为 1 的队列&#xff0c;该队列就只有空和满两种情况&#xff0c;也就是…

挖掘录屏宝藏:Screenity 深度解析与使用指南

挖掘录屏宝藏&#xff1a;Screenity 深度解析与使用指南 在数字内容创作与信息分享日益频繁的今天&#xff0c;录屏软件成为了众多创作者、教育者和办公族的必备工具。今天&#xff0c;我要给大家介绍一款在 GitHub 上收获了大量关注的开源录屏软件 ——Screenity。它功能强大…

4.1.2 XmlInclude 在 C# 中的作用及示例

xmlInclude 是 .NET 中用于 XML 序列化的一个重要特性,XmlInclude 的主要作用是: 1.告知 XML 序列化器可能遇到的派生类型 2.解决多态类型的序列化和反序列化问题 3.允许基类序列化时包含派生类信息 当你有基类引用指向派生类对象时,如果不使用 XmlInclude,序列化器…

ARM汇编常见伪指令及其用法示例

伪指令不是指令&#xff0c;伪指令和指令的根本区别是经过编译后会不会生成机器码。 伪指令的意义在于指导编译过程。 伪指令是和具体的编译器相关的&#xff0c;我们使用gnu工具链&#xff0c;因此学习gnu环境下的汇编伪指令。在 ARM 汇编中&#xff0c;伪指令&#xff08;Pse…

算法调试技巧

引言算法调试常比编写更耗时&#xff0c;尤其是动态规划、递归等逻辑复杂的代码。本文分享一套系统化的调试方法&#xff0c;帮助快速定位问题。一、调试前的准备代码格式化使用统一缩进&#xff08;4 空格&#xff09;和命名规范&#xff0c;避免因格式混乱导致的逻辑误读。边…

每日功能分享|让观看者体验“无缝链接”观看的功能——视频自动续播功能

你是否遇到过这样的困扰——看到一半的视频&#xff0c;关闭后却忘记进度&#xff0c;再打开时需要手动拖拽寻找上次的观看位置&#xff1f;如今&#xff0c;“视频自动续播功能”完美解决了这一痛点&#xff01;无论是在线教育课程、影视剧集还是企业内部员工培训&#xff0c;…

AWS: 云上侦探手册,七步排查ALB与EC2连接疑云

今天&#xff0c;咱们来聊一个对于许多刚接触AWS的运维同学来说&#xff0c;既常见又有点头疼的话题&#xff1a;如何优雅地排查和解决AWS上ALB&#xff08;Application Load Balancer&#xff09;暴露EC2服务时遇到的种种疑难杂症。 最近&#xff0c;我刚帮一个朋友解决了类似…

EIDE 创建基于STM32-HD的项目快速创建流程

EIDE 创建基于STM32-HD的项目流程芯片系列定义宏Flash 大小RAM 大小STM32F10x_HD#define STM32F10X_HD256KB~512KB48KB~64KBSTM32F10x_MD#define STM32F10X_MD64KB~128KB20KBSTM32F10x_LD#define STM32F10X_LD16KB~32KB4KB~10KB 新建项目远程仓库获取裸机开发程序STM(意法半导体…