日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HarmonyOS之数据管理·融合搜索的应用

發布時間:2024/5/21 编程问答 69 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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();// SearchParameter.QUERY對應用戶輸入,建議搜索域分詞。// 這里假設用戶輸入是“天空”,要在"title", "tag"這兩個域上發起搜索。JSONObject query = new JSONObject();query.put("天空", new JSONArray(Arrays.asList("title", "tag")));jsonObject.put(SearchParameter.QUERY, query);// SearchParameter.FILTER_CONDITION對應的JSONArray里可以添加搜索條件。// 對于索引庫里的一條索引,JSONArray下的每個JSONObject指定的條件都必須滿足才會命中,JSONObject里的條件組合滿足其中一個,這個JSONObject指定的條件即可滿足。JSONArray filterCondition = new JSONArray();// 第一個條件,一個域上可能取多個值。JSONObject filter1 = new JSONObject();filter1.put("bucket_id", new JSONArray(Arrays.asList(0, 1, 2))); // 一條索引在"bucket_id"的取值為0或1或2就能命中。filter1.put("id", new JSONArray(Arrays.asList(0, 1))); // 或者在"id"的取值為0或者1也可以命中。filterCondition.put(filter1);JSONObject filter2 = new JSONObject();filter2.put("tag", new JSONArray(Arrays.asList("白云")));filter2.put("ocr_text", new JSONArray(Arrays.asList("白云"))); // 一條索引只要在"tag"或者"ocr_text"上命中"白云"就能命中。filterCondition.put(filter2);jsonObject.put(SearchParameter.FILTER_CONDITION, filterCondition); // 一條索引要同時滿足第一和第二個條件才能命中。// SearchParameter.DEVICE_ID_LIST對應設備ID,匹配指定設備ID的索引才會命中。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); // 緯度必須在[-40.0f, 40.0f]JSONObject longitudeObject = new JSONObject();longitudeObject.put(SearchParameter.LOWER, -90.0);longitudeObject.put(SearchParameter.UPPER, 90.0);jsonObject.put("longitude", longitudeObject); // 經度必須在[-90.0, 90.0]// SearchParameter.ORDER_BY對應搜索結果的排序,排序字段通過SearchParameter.ASC和SearchParameter.DESC指定搜索結果在這個字段上按照升序、降序排序。// 這里填充字段的順序是重要的,比如這里兩個索引之間會先在"id"字段上升序排序,只有在"id"上相同時,才會繼續在"datetaken"上降序排序,以此類推。JSONObject order = new JSONObject();order.put("id", SearchParameter.ASC);order.put("datetaken", SearchParameter.DESC);jsonObject.put(SearchParameter.ORDER_BY, order);// SearchParameter.GROUP_FIELD_LIST對應分組搜索的域,調用groupSearch接口需要指定。jsonObject.put(SearchParameter.GROUP_FIELD_LIST, new JSONArray(Arrays.asList("tag", "ocr_text")));// 得到查詢字符串。String queryJsonStr = jsonObject.toString();
  • 上述代碼構建的 JSON 字符串如下:
// 構建的json字符串如下:/**{"SearchParameter.QUERY": {"天空": ["title","tag"]},"SearchParameter.FILTER_CONDITION": [{"bucket_id": [0,1,2],"id": [0,1]},{"tag": ["白云"],"ocr_text": ["白云"]}],"SearchParameter.DEVICE_ID_LIST": {"device_id": ["localDeviceId"]},"latitude": {"SearchParameter.LOWER": -40.0,"SearchParameter.UPPER": 40.0},"longitude": {"SearchParameter.LOWER": -90.0,"SearchParameter.UPPER": 90.0},"SearchParameter.ORDER_BY": {"id": "ASC","datetaken": "DESC"},"SearchParameter.GROUP_FIELD_LIST": ["tag","ocr_text"]}**/
  • 開始搜索會話,發起搜索:
// 開始搜索會話SearchSession searchSession = searchAbility.beginSearch(SearchParameter.DEFAULT_GROUP, bundleName);if (searchSession == null) {return;}try {int hit = searchSession.getSearchHitCount(queryJsonStr); // 獲取總命中數int batch = 50; // 每頁最多返回50個結果for (int i = 0; i < hit; i += batch) {List<IndexData> searchResult = searchSession.search(queryJsonStr, i, batch);// 處理IndexData}int groupLimit = 10; // 每個分組域上最多返回10個分組結果List<Recommendation> recommendationResult = searchSession.groupSearch(queryJsonStr, groupLimit);// 處理Recommendation} finally {// 結束搜索,釋放資源searchAbility.endSearch(SearchParameter.DEFAULT_GROUP, bundleName, searchSession);}

總結

以上是生活随笔為你收集整理的HarmonyOS之数据管理·融合搜索的应用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。