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.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(意法半導體…