W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
索引源應(yīng)用,一般為有持久化數(shù)據(jù)的應(yīng)用,可以通過(guò)融合搜索接口為其應(yīng)用數(shù)據(jù)建立索引,并配置全局搜索可搜索實(shí)體,幫助用戶通過(guò)全局搜索應(yīng)用查找本應(yīng)用內(nèi)的數(shù)據(jù)。應(yīng)用本身也提供搜索框時(shí),也可直接在應(yīng)用內(nèi)部通過(guò)融合搜索接口實(shí)現(xiàn)全文搜索功能。
HarmonyOS 中的融合搜索為開(kāi)發(fā)者提供以下幾種能力,詳見(jiàn)API參考。
類(lèi)名 | 接口名 | 描述 |
---|---|---|
SearchAbility | public List<IndexData> insert(String groupId, String bundleName, List<IndexData> indexDataList) | 索引插入 |
public List<IndexData> update(String groupId, String bundleName, List<IndexData> indexDataList) | 索引更新 | |
public List<IndexData> delete(String groupId, String bundleName, List<IndexData> indexDataList) | 索引刪除 | |
SearchSession | public int getSearchHitCount(String queryJsonStr) | 搜索命中結(jié)果數(shù)量 |
public List<IndexData> search(String queryJsonStr, int start, int limit) | 分頁(yè)搜索 | |
public List<Recommendation> groupSearch(String queryJsonStr, int groupLimit) | 分組搜索 |
實(shí)例化 SearchAbility,連接融合搜索服務(wù)。
SearchAbility searchAbility = new SearchAbility(context);
CountDownLatch lock = new CountDownLatch(1);
// 連接服務(wù)
searchAbility.connect(new ServiceConnectCallback() {
@Override
public void onConnect() {
lock.countDown();
}
@Override
public void onDisconnect() {
}
});
// 等待回調(diào),最長(zhǎng)等待時(shí)間可自定義
lock.await(3000, TimeUnit.MILLISECONDS);
// 連接失敗可重試
設(shè)置索引屬性。
// 構(gòu)造索引屬性
List<IndexForm> indexFormList = new ArrayList<>();
IndexForm primaryKey = new IndexForm("id", IndexType.NO_ANALYZED, true, true, false); // 主鍵,不分詞
indexFormList.add(primaryKey);
IndexForm title = new IndexForm("title", IndexType.ANALYZED, false, true, true); // 分詞
indexFormList.add(title);
IndexForm tagType = new IndexForm("tag_type", IndexType.SORTED, false, true, false); // 分詞,同時(shí)支持排序、分組
indexFormList.add(tagType);
IndexForm ocrText = new IndexForm("ocr_text", IndexType.SORTED_NO_ANALYZED, false, true, false); // 支持排序、分組,不分詞,所以也支持范圍搜索
indexFormList.add(ocrText);
IndexForm dateTaken = new IndexForm("datetaken", IndexType.LONG, false, true, false); // 支持排序和范圍查詢
indexFormList.add(dateTaken);
IndexForm bucketId = new IndexForm("bucket_id", IndexType.INTEGER, false, true, false); // 支持排序和范圍查詢
indexFormList.add(bucketId);
IndexForm latitude = new IndexForm("latitude", IndexType.FLOAT, false, true, false); // 支持范圍搜索
indexFormList.add(latitude);
IndexForm longitude = new IndexForm("longitude", IndexType.DOUBLE, false, true, false); // 支持范圍搜索
indexFormList.add(longitude);
// 設(shè)置索引屬性
int result = searchAbility.setIndexForm(bundleName, 1, indexFormList);
// 設(shè)置失敗可重試
插入索引。
// 構(gòu)建索引數(shù)據(jù)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_type", "tag_type" + i); indexData.put("ocr_text", "ocr_text" + i); indexData.put("dat// 構(gòu)建索引數(shù)據(jù)
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_type", "tag_type" + 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);
// 失敗的記錄可以持久化,稍后重試etaken", 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);// 失敗的記錄可以持久化,稍后重試
構(gòu)建查詢。
// 構(gòu)建查詢
JSONObject jsonObject = new JSONObject();
// SearchParameter.QUERY對(duì)應(yīng)用戶輸入,搜索域應(yīng)該都是分詞的
// 這里假設(shè)用戶輸入是“天空”,要在"title", "tag_type"這兩個(gè)域上發(fā)起搜索
JSONObject query = new JSONObject();
query.put("天空", new JSONArray(Arrays.asList("title", "tag_type")));
jsonObject.put(SearchParameter.QUERY, query);
// SearchParameter.FILTER_CONDITION對(duì)應(yīng)的JSONArray里可以添加搜索條件
// 對(duì)于索引庫(kù)里的一條索引,JSONArray下的每個(gè)JSONObject指定的條件都必須滿足才會(huì)命中,JSONObject里的條件組合滿足其中一個(gè),這個(gè)JSONObject指定的條件即可滿足
JSONArray filterCondition = new JSONArray();
// 第一個(gè)條件,一個(gè)域上可能取多個(gè)值
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);
// 第二個(gè)條件,一個(gè)值可能在多個(gè)域上命中
JSONObject filter2 = new JSONObject();
filter2.put("tag_type", new JSONArray(Arrays.asList("白云")));
filter2.put("ocr_text", new JSONArray(Arrays.asList("白云"))); // 一條索引只要在"tag_type"或者"ocr_text"上命中"白云"就能命中
filterCondition.put(filter2);
jsonObject.put(SearchParameter.FILTER_CONDITION, filterCondition); // 一條索引要同時(shí)滿足第一和第二個(gè)條件才能命中
// SearchParameter.DEVICE_ID_LIST對(duì)應(yīng)設(shè)備ID,匹配指定設(shè)備ID的索引才會(huì)命中
JSONObject deviceId = new JSONObject();
deviceId.put("device_id", new JSONArray(Arrays.asList("localDeviceId")));
jsonObject.put(SearchParameter.DEVICE_ID_LIST, deviceId);
// 可以在支持范圍搜索的索引域上發(fā)起范圍搜索,一條索引在指定域的值都落在對(duì)應(yīng)的指定范圍才會(huì)命中
JSONObject latitude = new JSONObject();
latitude.put(SearchParameter.LOWER, -40.0f); // inclusive
latitude.put(SearchParameter.UPPER, 40.0.f); // inclusive
jsonObject.put("latitude", latitude); // 緯度必須在[-40.0f, 40.0f]
JSONObject longitude new JSONObject();
longitude.put(SearchParameter.LOWER, -90.0); // inclusive
longitude.put(SearchParameter.UPPER, 90.0); // inclusive
jsonObject.put("longitude", longitude); // 經(jīng)度必須在[-90.0, 90.0]
// SearchParameter.ORDER_BY對(duì)應(yīng)搜索結(jié)果的排序,排序字段通過(guò)SearchParameter.ASC和SearchParameter.DESC
// 指定搜索結(jié)果在這個(gè)字段上按照升序、降序排序,這里填充字段的順序是重要的,比如這里兩個(gè)索引之間會(huì)先在"id"
// 字段上升序排序,只有在"id"上相同時(shí),才會(huì)繼續(xù)在"datetaken"上降序排序,以此類(lèi)推
JSONObject order = new JSONObject();
order.put("id", SearchParameter.ASC);
order.put("title", SearchParameter.ASC);
order.put("datetaken", SearchParameter.DESC);
jsonObject.put(SearchParameter.ORDER_BY, order);
// SearchParameter.GROUP_FIELD_LIST對(duì)應(yīng)的群組搜索的域,調(diào)用gruopSearch接口需要指定
jsonObject.put(SearchParameter.GROUP_FIELD_LIST, new JSONArray(Arrays.asList("tag_type", "ocr_text")));
// 得到查詢字符串
String queryJsonStr = jsonObject.toString();
// 構(gòu)建的json字符串如下:
/**
{
"SearchParameter.QUERY": {
"天空": [
"title",
"tag_type"
]
},
"SearchParameter.FILTER_CONDITION": [
{
"bucket_id": [
0,
1,
2
],
"id": [
0,
1
]
},
{
"tag_type": [
"白云"
],
"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",
"title": "ASC",
"datetaken": "DESC"
},
"SearchParameter.GROUP_FIELD_LIST": [
"tag_type",
"ocr_text"
]
}
**/
開(kāi)始搜索會(huì)話,發(fā)起搜索。
// 開(kāi)始搜索會(huì)話
SearchSession searchSession = searchAbility.beginSearch(SearchParameter.DEFAULT_GROUP, bundleName);
if (searchSession == null) {
return;
}
try {
int hit = searchSession.getSearchHitCount(queryJsonStr); // 獲取總命中數(shù)
int batch = 50; // 每頁(yè)最多返回50個(gè)結(jié)果
for (int i = 0; i < hit; i += batch) {
List<IndexData> result = searchSession.search(queryJsonStr, i, batch);
...
// 處理IndexData
}
int groupLimit = 10; // 每個(gè)分組域上最多返回10個(gè)分組結(jié)果
List<Recommendation> result = searchSession.groupSearch(queryJsonStr, groupLimit);
// 處理Recommendation
for (Recommendation recommendation : result) {
HiLog.info(LABEL, "field: %{public}s, value: %{public}s, count: %{public}d", recommedation.getField(), recommendation.getValue(), recommendation.getCount());
}
} finally {
// 釋放資源
searchAbility.endSearch(SearchParameter.DEFAULT_GROUP, bundleName, searchSession);
}
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: