生活随笔
收集整理的這篇文章主要介紹了
HarmonyOS之数据管理·融合搜索的应用
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、簡介
① 基本概念
- HarmonyOS 融合搜索為開發者提供搜索引擎級的全文搜索能力,可支持應用內搜索和系統全局搜索,為用戶提供更加準確、高效的搜索體驗。
- 全文索引:記錄字或詞的位置和次數等屬性,建立的倒排索引。
- 全文搜索:通過全文索引進行匹配查找結果的一種搜索引擎技術。
- 全局搜索:可以在系統全局統一的入口進行的搜索行為。
- 全局搜索應用:HarmonyOS 上提供全局搜索入口的應用,一般為桌面下拉框或懸浮搜索框。
- 索引源應用:通過融合搜索索引接口對其數據建立索引的應用。
- 可搜索配置:每個索引源應用應該提供一個包括應用包名、是否支持全局搜索等信息的可搜索實體,以便全局搜索應用發起搜索。
- 群組:經過認證的可信設備圈,可從賬號模塊獲取群組 ID。
- 索引庫:一種搜索引擎的倒排索引庫,包含多個索引文件的整個目錄構成一個索引庫。
- 索引域:索引數據的字段名,比如一張圖片有文件名、存儲路徑、大小、拍攝時間等,文件名就是其中的一個索引域。
- 索引屬性:描述索引域的信息,包括索引類型、是否為主鍵、是否存儲、是否支持分詞等。
② 運作機制
- 索引源應用通過融合搜索接口設置可搜索實體,并為其數據內容構建全文索引。
- 全局搜索應用接收用戶發起的搜索請求,遍歷支持全局搜索的可搜索實體,解析用戶輸入并構造查詢條件,最后通過融合搜索接口獲取各應用搜索結果。
- 融合搜索運作如下圖所示:
③ 權限與限制
- 構建索引或者發起搜索前,索引源應用必須先設置索引屬性,并且必須有且僅有一個索引域設置為主鍵,且主鍵索引域不能分詞,索引和搜索都會使用到索引屬性。
- 索引源應用的數據發生變動時,開發者應同步通過融合搜索索引接口更新索引,以保證索引和應用原始數據的一致性。
- 批量創建、更新、刪除索引時,應控制單次待索引內容大小,建議分批創建索引,防止內存溢出。
- 分頁搜索和分組搜索應控制每頁返回結果數量,防止內存溢出。
- 構建和搜索本機索引時,應該使用提供的 SearchParameter.DEFAULT_GROUP 作為群組 ID,分布式索引使用通過賬號模塊獲取的群組 ID。
- 搜索時需先創建搜索會話,并務必在搜索結束時關閉搜索會話,釋放內存資源。
使用融合搜索服務接口需要在“config.json”配置文件中添加“ohos.permission.ACCESS_SEARCH_SERVICE”權限。 - 搜索時的 SearchParameter.DEVICE_ID_LIST 必須與創建索引時的 deviceId 一致。
④ 應用場景
- 索引源應用,一般為有持久化數據的應用,可以通過融合搜索接口為其應用數據建立索引,并配置全局搜索可搜索實體,幫助用戶通過全局搜索應用查找本應用內的數據。
- 應用本身提供搜索框時,也可直接在應用內部通過融合搜索接口實現全文搜索功能。
二、融合搜索 API
類名接口名描述
SearchAbilitypublic List insert(String groupId, String bundleName, List indexDataList)索引插入
public List update(String groupId, String bundleName, List indexDataList)索引更新
public List delete(String groupId, String bundleName, List indexDataList)索引刪除
SearchSessionpublic int getSearchHitCount(String queryJsonStr)搜索命中結果數量
public List search(String queryJsonStr, int start, int limit)分頁搜索
public List groupSearch(String queryJsonStr, int groupLimit)分組搜索
三、融合搜索流程
- 實例化 SearchAbility,連接融合搜索服務:
SearchAbility searchAbility
= new SearchAbility(context
);String bundleName
= context
.getBundleName();CountDownLatch lock
= new CountDownLatch(1);searchAbility
.connect(new ServiceConnectCallback() {@Overridepublic void onConnect() {lock
.countDown();}@Overridepublic void onDisconnect() {}});try {lock
.await(3000, TimeUnit.MILLISECONDS
);} catch (InterruptedException e
) {HiLog.error(LABEL
, "await failed, %{public}s", e
.getMessage());}
List<IndexForm> indexFormList
= new ArrayList<IndexForm>() { {add(new IndexForm("id", IndexType.NO_ANALYZED
, true, true, false)); add(new IndexForm("title", IndexType.ANALYZED
, false, true, true)); add(new IndexForm("tag", IndexType.SORTED
, false, true, false)); add(new IndexForm("ocr_text", IndexType.SORTED_NO_ANALYZED
, false, true, false)); add(new IndexForm("datetaken", IndexType.LONG
, false, true, false)); add(new IndexForm("bucket_id", IndexType.INTEGER
, false, true, false)); add(new IndexForm("latitude", IndexType.FLOAT
, false, true, false)); add(new IndexForm("longitude", IndexType.DOUBLE
, false, true, false)); } };int result
= searchAbility
.setIndexForm(bundleName
, 1, indexFormList
);
List<IndexData> indexDataList
= new ArrayList<>();for (int i
= 0; i
< 5; i
++) {IndexData indexData
= new IndexData();indexData
.put("id", "id" + i
);indexData
.put("title", "title" + i
);indexData
.put("tag", "tag" + i
);indexData
.put("ocr_text", "ocr_text" + i
);indexData
.put("datetaken", System.currentTimeMillis());indexData
.put("bucket_id", i
);indexData
.put("latitude", i
/ 5.0 * 180);indexData
.put("longitude", i
/ 5.0 * 360);indexDataList
.add(indexData
);}List<IndexData> failedList
= searchAbility
.insert(SearchParameter.DEFAULT_GROUP
, bundleName
, indexDataList
);
JSONObject jsonObject
= new JSONObject();JSONObject query
= new JSONObject();query
.put("天空", new JSONArray(Arrays.asList("title", "tag")));jsonObject
.put(SearchParameter.QUERY
, query
);JSONArray filterCondition
= new JSONArray();JSONObject filter1
= new JSONObject();filter1
.put("bucket_id", new JSONArray(Arrays.asList(0, 1, 2))); filter1
.put("id", new JSONArray(Arrays.asList(0, 1))); filterCondition
.put(filter1
);JSONObject filter2
= new JSONObject();filter2
.put("tag", new JSONArray(Arrays.asList("白云")));filter2
.put("ocr_text", new JSONArray(Arrays.asList("白云"))); filterCondition
.put(filter2
);jsonObject
.put(SearchParameter.FILTER_CONDITION
, filterCondition
); JSONObject deviceId
= new JSONObject();deviceId
.put("device_id", new JSONArray(Arrays.asList("localDeviceId"))); jsonObject
.put(SearchParameter.DEVICE_ID_LIST
, deviceId
);JSONObject latitudeObject
= new JSONObject();latitudeObject
.put(SearchParameter.LOWER
, -40.0f);latitudeObject
.put(SearchParameter.UPPER
, 40.0f);jsonObject
.put("latitude", latitudeObject
); JSONObject longitudeObject
= new JSONObject();longitudeObject
.put(SearchParameter.LOWER
, -90.0);longitudeObject
.put(SearchParameter.UPPER
, 90.0);jsonObject
.put("longitude", longitudeObject
); JSONObject order
= new JSONObject();order
.put("id", SearchParameter.ASC
);order
.put("datetaken", SearchParameter.DESC
);jsonObject
.put(SearchParameter.ORDER_BY
, order
);jsonObject
.put(SearchParameter.GROUP_FIELD_LIST
, new JSONArray(Arrays.asList("tag", "ocr_text")));String queryJsonStr
= jsonObject
.toString();
SearchSession searchSession
= searchAbility
.beginSearch(SearchParameter.DEFAULT_GROUP
, bundleName
);if (searchSession
== null) {return;}try {int hit
= searchSession
.getSearchHitCount(queryJsonStr
); int batch
= 50; for (int i
= 0; i
< hit
; i
+= batch
) {List<IndexData> searchResult
= searchSession
.search(queryJsonStr
, i
, batch
);}int groupLimit
= 10; List<Recommendation> recommendationResult
= searchSession
.groupSearch(queryJsonStr
, groupLimit
);} finally {searchAbility
.endSearch(SearchParameter.DEFAULT_GROUP
, bundleName
, searchSession
);}
總結
以上是生活随笔為你收集整理的HarmonyOS之数据管理·融合搜索的应用的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。