创新互联鸿蒙OS教程:鸿蒙OS融合搜索开发指导

场景介绍

索引源应用,一般为有持久化数据的应用,可以通过融合搜索接口为其应用数据建立索引,并配置全局搜索可搜索实体,帮助用户通过全局搜索应用查找本应用内的数据。应用本身也提供搜索框时,也可直接在应用内部通过融合搜索接口实现全文搜索功能。

接口说明

HarmonyOS 中的融合搜索为开发者提供以下几种能力,详见API参考。

类名 接口名 描述
SearchAbility public 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) 索引删除
SearchSession public 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);
CountDownLatch lock = new CountDownLatch(1);
// 连接服务
searchAbility.connect(new ServiceConnectCallback() {
    @Override
    public void onConnect() {
        lock.countDown();
    }

        
    @Override
    public void onDisconnect() {
    }
});
// 等待回调,最长等待时间可自定义
lock.await(3000, TimeUnit.MILLISECONDS);
// 连接失败可重试

设置索引属性。

// 构造索引属性
List 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); // 分词,同时支持排序、分组
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);

 
// 设置索引属性
int result = searchAbility.setIndexForm(bundleName, 1, indexFormList);
// 设置失败可重试

插入索引。

// 构建索引数据List 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// 构建索引数据
List 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 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 failedList = searchAbility.insert(SearchParameter.DEFAULT_GROUP, bundleName, indexDataList);// 失败的记录可以持久化,稍后重试

构建查询。

// 构建查询
JSONObject jsonObject = new JSONObject();

    
// SearchParameter.QUERY对应用户输入,搜索域应该都是分词的
// 这里假设用户输入是“天空”,要在"title", "tag_type"这两个域上发起搜索
JSONObject query = new JSONObject();
query.put("天空", new JSONArray(Arrays.asList("title", "tag_type")));
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_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); // 一条索引要同时满足第一和第二个条件才能命中

 
// 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 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); // 经度必须在[-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("title", SearchParameter.ASC);
order.put("datetaken", SearchParameter.DESC);
jsonObject.put(SearchParameter.ORDER_BY, order);

 
// SearchParameter.GROUP_FIELD_LIST对应的群组搜索的域,调用gruopSearch接口需要指定
jsonObject.put(SearchParameter.GROUP_FIELD_LIST, new JSONArray(Arrays.asList("tag_type", "ocr_text")));

 
// 得到查询字符串
String queryJsonStr = jsonObject.toString();
// 构建的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"
    ]
}
**/

开始搜索会话,发起搜索。

// 开始搜索会话
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 result = searchSession.search(queryJsonStr, i, batch);
        ...
        // 处理IndexData
    }
    int groupLimit = 10; // 每个分组域上最多返回10个分组结果
    List 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);
}

网站名称:创新互联鸿蒙OS教程:鸿蒙OS融合搜索开发指导
网站网址:http://www.shufengxianlan.com/qtweb/news13/452663.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联