历史消息

云信支持在客户端本地与云端存储历史消息,供后续查询。

本地历史消息

本地历史消息查询

SDK 提供了一个根据锚点查询本地消息历史记录的接口,根据提供的方向 (direct),查询比 anchor(锚点消息) 更老 (QUERY_OLD) 或更新 (QUERY_NEW) 的最靠近 anchor 的 limit 条数据。调用者可使用 asc 参数指定结果排序规则,结果使用 time 作为排序字段。

异步版本

/**
 * 根据锚点和方向从本地消息数据库中查询消息历史。
 * 根据提供的方向(direct),查询比anchor更老(QUERY_OLD)或更新(QUERY_NEW)的最靠近anchorlimit条数据。
 * 调用者可使用asc参数指定结果排序规则,结果使用time作为排序字段。
 * 注意:查询结果不包含锚点。
 *
 * @return 调用跟踪,可设置回调函数,接收查询结果
 */
public InvocationFuture<List<IMMessage>> queryMessageListEx(IMMessage anchor, QueryDirectionEnum direction, int limit, boolean asc);

同步版本

/**
 * 根据锚点和方向从本地消息数据库中查询消息历史。(同步函数)<br>
 * 根据提供的方向(direct),查询比anchor更老(QUERY_OLD)或更新(QUERY_NEW)的最靠近anchorlimit条数据。<br>
 * 调用者可使用asc参数指定结果排序规则,结果使用time作为排序字段。<br>
 * 注意:查询结果不包含锚点。
 *
 * @param anchor    查询锚点
 * @param direction 查询方向
 * @param limit     查询结果的条数限制
 * @param asc       查询结果的排序规则,如果为true,结果按照时间升序排列,如果为false,按照时间降序排列
 * @return 调用跟踪,可设置回调函数,接收查询结果
 */
List<IMMessage> queryMessageListExBlock(IMMessage anchor, QueryDirectionEnum direction, int limit, boolean asc);
参数 说明
anchor 查询锚点
direction 查询方向
limit 查询结果的条数限制
asc 查询结果的排序规则

anchor参数表示查询锚点,也就是作为查询起点的那条消息,查询结果不包含锚点。不能设置为null。

当进行首次查询时可以使用MessageBuilder.createEmptyMessage(...)方法生成空消息作为锚点。如要查询与accid001这个账号的点对点聊天消息记录,并将2019-01-15 17:00:00 (对应的时间戳为1547542800000) 作为查询起点,则可以配置锚点:

IMMessage msg = MessageBuilder.createEmptyMessage("accid001", SessionTypeEnum.P2P, 1547542800000L);

direction表示查询方向,QueryDirectionEnum.QUERY_OLD表示比锚点更旧的消息,QueryDirectionEnum.QUERY_NEW表示比锚点更新的消息。例如,以2019-01-15 17:00:00 (对应的时间戳为1547542800000) 为锚点:

asc参数表示对查询结果按照时间进行排序的方式,true表示按照时间戳从小到大,false表示按照时间戳从大到小。

// 查询比 anchor时间更早的消息,查询20条,结果按照时间降序排列
NIMClient.getService(MsgService.class).queryMessageListEx(anchor, QueryDirectionEnum.QUERY_OLD,
    20, false).setCallback(new RequestCallbackWrapper<List<IMMessage>>() {
            @Override
            public void onResult(int code, List<IMMessage> result, Throwable exception) {
                ...
            }
});

按起止时间查询

该接口使用方法与 queryMessageListEx 类似,增加了一个参数 toTime 作为查询方向上的的截止时间。

查询结果的范围由 toTime 和 limit 共同决定,以先到为准。如果从 anchor 到 toTime 之间消息大于 limit 条,返回 limit 条记录,如果小于 limit 条,返回实际条数。

/**
 * 根据起始、截止时间点以及查询方向从本地消息数据库中查询消息历史。
 * 根据提供的方向 (direction),以 anchor 为起始点,往前或往后查询由 anchortoTime 之间靠近 anchorlimit 条消息。
 * 查询范围由 toTime 和 limit 共同决定,以先到为准。如果到 toTime 之间消息大于 limit 条,返回 limit 条记录,如果小于 limit 条,返回实际条数。
 * 查询结果排序规则:direction 为 QUERY_OLD 时 按时间降序排列,direction 为 QUERY_NEW 时按照时间升序排列。
 * 注意:查询结果不包含锚点。
 *
 * @return 调用跟踪,可设置回调函数,接收查询结果
 */
public InvocationFuture<List<IMMessage>> queryMessageListExTime(IMMessage anchor, long toTime, QueryDirectionEnum direction, int limit);
参数 说明
anchor 查询锚点。关于锚点消息,见上文queryMessageListEx方法中的介绍
toTime 查询截止时间,若方向为 QUERY_OLD,toTime 应小于 anchor.getTime()。
方向为 QUERY_NEW,toTime 应大于 anchor.getTime()
direction 查询方向
limit 查询结果的条数限制
// 以P2P类型为例,testAccount为测试帐号
IMMessage msg = MessageBuilder.createEmptyMessage("testAccount", SessionTypeEnum.P2P, System.currentTimeMillis());

// 查询anchor往前10s的数据,10条
NIMClient.getService(MsgService.class).queryMessageListExTime(msg, System.currentTimeMillis() - 10000, QueryDirectionEnum.QUERY_OLD, 10).setCallback(...);

查询最近一条消息

查询同指定会话的最近一条消息

/**
* @param account 对方的id/群id
* @param sessionType 会话类型
*/ 
IMMessage queryLastMessage(java.lang.String account,
                           SessionTypeEnum sessionType)

按消息id查询

异步版本:

/**
 * 通过消息id批量获取IMMessage
 *
 * @param uuids 消息id列表
 * @return
 */
public InvocationFuture<List<IMMessage>> queryMessageListByUuid(List<String> uuids);

同步版本:

/**
 * 通过消息id批量获取IMMessage(同步版本)
 *
 * @param uuids 消息的uuid列表
 * @return
 */
public List<IMMessage> queryMessageListByUuidBlock(List<String> uuids);
// 通过消息id批量获取IMMessage(异步版本)
List<String> uuids = new ArrayList<>();
uuids.add(message.getUuid());
NIMClient.getService(MsgService.class).queryMessageListByUuid(uuids);

// 通过消息id批量获取IMMessage(同步版本)
NIMClient.getService(MsgService.class).queryMessageListByUuidBlock(uuids);

按消息类型查询

根据起始、截止时间点以及查询方向从本地消息数据库中查询指定消息类型的消息历史。

根据提供的方向 (direction),以 anchor 为起始点,往前或往后查询由 anchor 到 toTime 之间靠近 anchor 的 limit 条消息。

查询范围由 toTime 和 limit 共同决定,以先到为准。如果到 toTime 之间消息大于 limit 条,返回 limit 条记录,如果小于 limit 条,返回实际条数。

查询结果排序规则:如果asc为true,结果按照时间升序排列,如果为false,按照时间降序排列

注意:查询结果不包含锚点。

/**
 *  @param types 查询的消息类型集合, 传入null表示所有消息类型
 *  @param anchor 查询锚点
 *  @param toTime 查询截止时间,若方向为 QUERY_OLD,toTime 应小于 anchor.getTime()。方向为 QUERY_NEW,toTime 应大于 anchor.getTime(), 填0表示没有时间限制,以 limit限制为主
 *  @param direction  查询方向
 *  @param limit  查询结果的条数限制
 *  @param asc  查询结果的排序规则,如果为true,结果按照时间升序排列,如果为false,按照时间降序排列
 *  返回: 调用跟踪,可设置回调函数,接收查询结果
 */
InvocationFuture<java.util.List<IMMessage>> queryMessageListByTypes(java.util.List<MsgTypeEnum> types,
                                                                    IMMessage anchor,
                                                                    long toTime,
                                                                    QueryDirectionEnum direction,
                                                                    int limit,
                                                                    boolean asc);

按消息子类型查询

根据起始时间、消息类型从本地消息数据库中查询指定消息子类型的消息历史。

以 anchor 为起始点,往前查询由 anchor 开始 的 limit 条消息。

注意:查询结果不包含锚点。

异步版本:

/**
 * 通过消息子类型查询本地消息记录(异步版本)
 *
 * @param msgTypeEnum   消息类型
 * @param anchor        搜索的消息锚点
 * @param limit         搜索结果的条数限制
 * @param subtype       子类型
 * @return InvocationFuture
 */
InvocationFuture<List<IMMessage>> queryMessageListBySubtype(MsgTypeEnum msgTypeEnum, IMMessage anchor, int limit, int subtype);

同步版本:

/**
 * 通过消息子类型查询本地消息记录(同步版本)
 *
 * @param msgTypeEnum   消息类型
 * @param anchor        搜索的消息锚点
 * @param limit         搜索结果的条数限制
 * @param subtype       子类型
 * @return 子类型和subtype一致的消息的列表
 */
List<IMMessage> queryMessageListBySubtypeBlock(MsgTypeEnum msgTypeEnum, IMMessage anchor, int limit, int subtype);
参数 说明
msgTypeEnum 消息类型
anchor 搜索的消息锚点
limit 搜索结果的条数限制
subtype 子类型
NIMClient.getService(MsgService.class)
  .queryMessageListBySubtype(getMsgTypes().get(0), msg, msgCount, subtype).setCallback(callback);

删除本地消息

删除单条消息

指定一条消息进行本地删除

/**
 * 删除一条消息记录
 *
 * @param message 待删除的消息记录
 * @param ignore true: 本地不记录清除操作; false: 本地记录清除操作
 *               从云端拉取消息时,如果本地有删除该消息的操作记录,则该消息不会入库
 *               删除标记会被清除标记覆盖
 */
void deleteChattingHistory(IMMessage message, boolean ignore);
参数 说明
message 待删除的消息记录
Ignore true: 本地不记录清除操作; false: 本地记录清除操作
从云端拉取消息时,如果本地有删除该消息的操作记录,则该消息不会入库
删除标记会被清除标记覆盖
// 删除单条消息
NIMClient.getService(MsgService.class).deleteChattingHistory(message, false);

删除指定会话内消息

将某会话的所有消息从本地数据库中移除,且可以配置是否记录此次清除操作进数据库。若记录,则当从云端把该部分消息拉取下来后,将无法同步至本地数据库中。

/**
 * 清除与指定用户的所有本地消息记录
 *
 * @param account     用户帐号
 * @param sessionType 聊天类型
 * @param ignore true: 本地不记录清除操作; false: 本地记录清除操作
 */
void clearChattingHistory(String account, SessionTypeEnum sessionType, boolean ignore);
参数 说明
account 用户账号
sessionType 聊天对象的 ID,如果是单聊,为用户帐号,如果是群聊,为群组 ID
ignore true(默认): 本地不记录清除操作; false: 本地记录清除操作
// 本地记录清除操作
NIMClient.getService(MsgService.class).clearChattingHistory(sessionId, sessionType, false);

若要删除指定时间区段内的消息,可以使用以下接口:

/**
*  根据时间范围删除本地历史消息(startTime, entTime), 开区间,不包括两个端点,大于startTime, 小于endTime
*  @param account 对方的id/群id
*  @param sessionType 会话的类型
*  @param startTime 开始时间
*  @param endTime 结束时间
*/
void deleteRangeHistory(java.lang.String account,
                        SessionTypeEnum sessionType,
                        long startTime,
                        long endTime);

删除所有消息

SDK 支持删除数据库内所有消息。

/**
* 清空消息数据库的所有消息记录。
* 可选择是否要同时清空本地最近会话列表。
* 若最近联系人列表也被清空,会触发MsgServiceObserve.observeRecentContactDeleted(Observer, boolean)通知
* @param clearRecent 是否同时清除本地最近会话列表
*/
void clearMsgDatabase(boolean clearRecent);

云端历史消息

云端历史消息查询

SDK 提供了查询云端消息历史的接口,查询以锚点 anchor 作为起始点(不包含锚点),根据 direction 参数,往前或往后查询由锚点到 toTime 之间的最多 limit 条消息。查询范围由 toTime 和 limit 共同决定,以先到为准。如果到 toTime 之间消息大于 limit 条,返回 limit 条记录,如果小于 limit 条,返回实际条数。当已经查询到头时,返回的结果列表的 size 可能会比 limit 小。

当进行首次查询时,锚点可以用使用 MessageBuilder#createEmptyMessage 接口生成。查询结果不包含锚点。该接口的最后一个参数可用于控制是否要将拉取到的消息记录保存到本地数据库,如果选择保存到了本地,再使用拉取本地消息记录的接口时,也能取到这些消息。

/**
 * 从服务器拉取消息历史记录,可以指定查询的消息类型,结果不存本地消息数据库。
 * <p>
 * 以锚点anchor作为起始点(不包含锚点),根据direction参数,往前或往后查询由锚点到toTime之间的最多limit条消息。<br>
 * 查询范围由toTime和limit共同决定,以先到为准。如果到toTime之间消息大于limit条,返回limit条记录,如果小于limit条,返回实际条数。
 * 当已经查询到头时,返回的结果列表的size可能会比limit小
 *
 * @param anchor    起始时间点的消息,不能为null。<br>
 *                  设置自定义锚点时,使用 {@link MessageBuilder#createEmptyMessage(String, SessionTypeEnum, long)} 创建一个空对象即可<br>
 * @param toTime    结束时间点单位毫秒
 * @param limit     本次查询的消息条数上限(最多100条)
 * @param direction 查询方向,QUERY_OLD按结束时间点逆序查询,逆序排列;QUERY_NEW按起始时间点正序起查,正序排列
 * @param msgTypes  消息类型,数组。消息类型仅支持 0:文本,1:图片,2:语音,3:视频,4:地理位置,5:通知,6:文件,10:提示,100:自定义,其它为非法参数
 * @param persist   通过该接口获取的漫游消息记录,要不要保存到本地消息数据库。
 * @param persistClear 是否保存被清除的消息到本地数据库,在persist==true时生效
 * @param customFilter 过滤器回调,如果返回true则被忽略,即视为没有拉到这条消息
 * @return InvocationFuture
 */
InvocationFuture<List<IMMessage>> pullMessageHistoryExType(IMMessage anchor, long toTime, int limit,
                                                           QueryDirectionEnum direction, MsgTypeEnum[] msgTypes, boolean persist,
                                                           boolean persistClear, IMMessageFilter customFilter);
参数 说明
anchor 起始时间点的消息,不能为 null。
设置自定义锚点时,使用 MessageBuilder#createEmptyMessage 创建一个空对象即可
toTime 结束时间点单位毫秒
limit 本次查询的消息条数上限(最多 100 条)
direction 查询方向,QUERY_OLD 按结束时间点逆序查询,逆序排列;
QUERY_NEW 按起始时间点正序起查,正序排列
persist 通过该接口获取的漫游消息记录,要不要保存到本地消息数据库。
persistClear 是否保存被清除的消息到本地数据库,在persist==true时生效
customFilter 过滤器回调,如果返回true则被忽略,即视为没有拉到这条消息
// 服务端拉取历史消息100条
long newTime = System.currentTimeMillis();
long oldTime = newTime - 1000 * 60 * 60; // 一小时前
IMMessage anchor = MessageBuilder.createEmptyMessage("testAccount", SessionTypeEnum.P2P, newTime);
NIMClient.getService(MsgService.class).pullMessageHistoryEx(anchor, oldTime, 100, QueryDirectionEnum.QUERY_OLD, false, false, message -> false)                    .setCallback(callback);

此外,还提供如下简单接口:

从服务器拉取消息历史记录。该接口查询方向为从后往前。以锚点anchor作为起始点(不包含锚点),往前查询最多limit条消息。 当已经查询到头时,返回的结果列表的size可能会比limit小。

/**
* @param anchor 查询锚点
* @param limit 本次查询的消息条数上限(最多100条)
* @param persist 通过该接口获取的历史消息记录,是否保存到本地消息数据库。
* @param persistClear 是否保存清除记录之前的消息到本地数据库,在persist==true时生效
*/
InvocationFuture<java.util.List<IMMessage>> pullMessageHistory(IMMessage anchor,
                                                               int limit,
                                                               boolean persist,
                                                               boolean persistClear);

按消息类型查询

从服务器拉取历史消息时,可以指定查询的消息类型。

/**
 * 
 * @param anchor    起始时间点的消息,不能为null。
 * @param toTime    结束时间点,单位毫秒。
 * @param limit     本次查询的消息条数上限(最多100条)
 * @param direction 查询方向,QUERY_OLD按结束时间点逆序查询,逆序排列;QUERY_NEW按起始时间点正序起查,正序排列
 * @param msgTypes  消息类型,数组。消息类型仅支持 0:文本,1:图片,2:语音,3:视频,4:地理位置,5:通知,6:文件,10:提示,100:自定义,其它为非法参数
 * @param persist   通过该接口获取的历史消息记录,要不要保存到本地消息数据库。
 * @param persistClear   是否保存被清除的消息到本地数据库
 * @return InvocationFuture
 */
InvocationFuture<java.util.List<IMMessage>> pullMessageHistoryExType(IMMessage anchor,
                                                                     long toTime,
                                                                     int limit,
                                                                     QueryDirectionEnum direction,
                                                                     MsgTypeEnum[] msgTypes,
                                                                     boolean persist,
                                                                     boolean persistClear);

按消息id查询

通过 Server ID 批量获取IMMessage(同步版本) 注意:一个ServerId可能对应多条消息。

/**
*  @param serverIds 消息的Server ID列表
*  返回 ServerId在参数列表中的消息组成的列表
*/
java.util.List<IMMessage> queryMessageListByServerIdBlock(java.util.List<java.lang.String> serverIds);

删除云端历史消息

删除单会话云端历史消息

/**
*  清空点对点聊天历史消息,暂不支持群聊
*  @param account 用户账号
*  @param sessionType 会话类型
*  @param deleteRoam  是否一起删除漫游
*/
void clearServerHistory(java.lang.String account,
                        SessionTypeEnum sessionType,
                        boolean deleteRoam);

删除单条云端历史消息

用户单向删除一条消息成功后,该账号下不再能从服务端拉取到该条消息。而且,本端登录此账号的其他端都会删除本地的该消息记录。其他账号不受到该操作影响。删除成功后,会触发 MsgServiceObserve#observeDeleteMsgSelf 回调。

/**
 * 删除本地某条消息,并同时删除服务端历史、漫游
 * @param msg 被单向删除的消息
 * @param ext 扩展字段
 */
InvocationFuture<Long> deleteMsgSelf(IMMessage msg, String ext);
参数 说明
msg 要被单向删除的消息
ext 扩展字段,选填
NIMClient.getService(MsgService.class).deleteMsgSelf(selectedItem, "").setCallback(new RequestCallback<Long>() {
    @Override
    public void onSuccess(Long param) {
        deleteItem(selectedItem, true);
    }

    @Override
    public void onFailed(int code) {
        ToastHelper.showToast(NimUIKit.getContext(), container.activity.getString(R.string.delete_msg_self_failed) + ", code=" + code);
    }

    @Override
    public void onException(Throwable exception) {
        NimLog.i("delete msg self", exception.getMessage());
    }
});

消息检索

SDK当前支持关键字检索,可以通过 lucene插件 进行检索,也可以通过 SDK 本身自带的检索功能。

本地消息检索

单会话检索

SDK 提供了按照关键字搜索聊天记录的功能,可以对指定的聊天对象,输入关键字进行消息内容搜索。查询方向为从后往前。以锚点 anchor 作为起始点开始查询,返回最多 limit 条匹配 keyword 的记录。该接口目前仅搜索文本类型的消息,匹配规则为文本内容包含 keyword,目前仅支持精确匹配,不支持模糊匹配和拼音匹配。

/**
 * 从本地消息数据库搜索消息历史。查询范围由anchor的sessionId和sessionType决定。
 * 按查询方向返回最多limit条匹配key的记录。
 * 该接口目前仅搜索文本类型的消息,匹配规则为文本内容包含keyword,仅支持精确匹配,不支持模糊匹配和拼音匹配。
 * 注意:搜索结果不包含anchor
 * @return InvocationFuture
 */
InvocationFuture<java.util.List<IMMessage>>    searchMessageHistory(java.lang.String keyword, java.util.List<java.lang.String> fromAccounts, IMMessage anchor, QueryDirectionEnum direction, int limit);
参数 说明
keyword 文本消息的搜索关键字
fromAccounts 消息说话者帐号列表
anchor 搜索的消息锚点
direction 查询方向
limit 搜索结果的条数限制
// 搜索『关键字』20条
NIMClient.getService(MsgService.class).searchMessageHistory("关键字", fromAccounts, anchor, direction,20)
     .setCallback(new RequestCallbackWrapper<List<IMMessage>>(){ ... });

全局检索

此外,SDK 还提供了按照关键字全局搜索聊天记录的接口:MsgService#searchAllMessageHistory,用法与上述类似。目前暂不提供索引方式的全文检索功能,该全局搜索接口需要开发者评估大数据情况下的性能开销。

根据时间点搜索消息历史。该接口查询方向以某个时间点为基准从后往前,返回最多 limit 条匹配 key 的记录。该接口目前仅搜索文本类型的消息,匹配规则为文本内容包含 keyword,仅支持精确匹配,不支持模糊匹配和拼音匹配。

/**
 * 从本地消息数据库搜索消息历史。
 * 该接口查询方向以某个时间点为基准从后往前,返回最多limit条匹配key的记录。
 * 该接口目前仅搜索文本类型的消息,匹配规则为文本内容包含keyword,仅支持精确匹配,不支持模糊匹配和拼音匹配。
 * @return InvocationFuture
 */
public InvocationFuture<List<IMMessage>> searchAllMessageHistory(String keyword, List<String> fromAccounts, long time, int limit);
参数 说明
keyword 文本消息的搜索关键字
fromAccounts 消息说话者帐号列表。
time 以该时间点为基准从后往前查
limit 搜索结果的条数限制
NIMClient.getService(MsgService.class).searchAllMessageHistory(keyword, fromAccounts, time, limit)
    .setCallback(new RequestCallbackWrapper<List<IMMessage>>(){ ... });

查询命中消息数

通过以下接口可以返回命中关键字的消息数:

/*
* @param query 待检索的字符串
* @param limit 最多返回多少条记录
*/
// 异步
InvocationFuture<java.util.List<MsgIndexRecord>>  searchAllSession(java.lang.String query, int limit);
// 同步
java.util.List<MsgIndexRecord>    searchAllSessionBlock(java.lang.String query, int limit);

若要返回所有的命中消息记录,可以使用如下接口:

/**
* 检索指定的会话,返回该会话中与检索串匹配的所有消息记录。
*/ 

// 异步
InvocationFuture<java.util.List<MsgIndexRecord>> searchSession(java.lang.String query, SessionTypeEnum sessionType, java.lang.String sessionId);
// 同步
java.util.List<MsgIndexRecord>    searchSessionBlock(java.lang.String query, SessionTypeEnum sessionType, java.lang.String sessionId);

单聊云端消息检索

/**
 * 云端聊天记录关键词查询
 *
 * @param otherAccid 对方的account
 * @param fromTime 起始时间点单位毫秒
 * @param endTime 结束时间点单位毫秒
 * @param keyword 搜索的关键词
 * @param limit 本次查询的消息条数上限(最多100条)
 * @param reverse 可选参数,不传默认false,true是表示反向查询(按时间正序起查,正序排列),默认false表示按时间逆序起查,逆序排列
 */
InvocationFuture<ArrayList<IMMessage>> searchRoamingMsg(String otherAccid, long fromTime, long endTime, String keyword, int limit, boolean reverse);
参数 说明
otherAccid 对方的account
fromTime 起始时间点单位毫秒
endTime 结束时间点单位毫秒
keyword 搜索的关键词
limit 本次查询的消息条数上限(最多100条)
reverse 可选参数,不传默认false,true是表示反向查询(按时间正序起查,正序排列),默认false表示按时间逆序起查,逆序排列
NIMClient.getService(MsgService.class).searchRoamingMsg(
        accidEdit.getText().toString(),
        startTime,
        endTime,
        keywordEdit.getText().toString(),
        queryAmount,
        true).setCallback(new RequestCallback<ArrayList<IMMessage>>() {
    @Override
    public void onSuccess(ArrayList<IMMessage> param) {
        StringBuilder roamingmsg = new StringBuilder();
        for (IMMessage RoamingMsg:param){
            roamingmsg.append("sessionid:"+ RoamingMsg.getSessionId());
            roamingmsg.append(" ,消息内容:" + RoamingMsg.getContent());
            roamingmsg.append(" ,发生时间:" + RoamingMsg.getTime());
            roamingmsg.append(" ,会话类型:" + RoamingMsg.getSessionType());
        }
        roamingMsg.setText(roamingmsg.toString());
    }

    @Override
    public void onFailed(int code) {
        Toast.makeText(SessionActivity2.this, "云端聊天记录关键词查询失败, code=" + code, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onException(Throwable exception) {
        Toast.makeText(SessionActivity2.this, "云端聊天记录关键词查询出现异常, msg=" + exception.getMessage(), Toast.LENGTH_SHORT).show();
    }
});

群聊云端消息检索

/**
*  群组会话云端历史消息关键词查询
*  @param tid 群id
*  @param fromTime 起始时间点  单位毫秒 
*  @param endTime  结束时间点  单位毫秒
*  @param keyword  查询关键词
*  @param limit    本次查询的消息条数上限(最多100条)
*  @param reverse  true是表示反向查询(按时间正序起查,正序排列),默认false表示按时间逆序起查,逆序排列
*/
InvocationFuture<java.util.List<IMMessage>> searchTeamMsgByKeyword(long tid,
                                                                   long fromTime,
                                                                   long endTime,
                                                                   java.lang.String keyword,
                                                                   int limit,
                                                                   boolean reverse);

lucene插件检索

云信 SDK v2.7.0 加入基于 Lucene 的全文检索插件,支持在客户端本地进行聊天消息的全文检索。目前开放的查询接口适用于两类需求:

检索所有会话,返回所有匹配关键字的会话、每个会话匹配关键字的消息条数。如果会话只有一条消息匹配,那么直接返回该消息内容,返回的会话数量可以指定,也可以一次性列出所有会话。会话间的排序规则,按照每个会话最近一条匹配消息的时间倒序排列。需要支持多个关键字查询,采用空格隔开,关键字之间是 AND 关系。

检索单个会话,返回所有匹配关键字的消息,并高亮显示被击中的关键字,可以跳转到该消息的上下文。

云信 SDK 目前主要针对上述两种需求提供查询服务,只要集成了全文检索插件,SDK 会自动同步所有聊天记录到全文检索索引中。 在 v2.8.0 版本我们已经对依赖的 Lucene 源码做了大幅度的精简,约 1M+ 的大小,对于大的工程,仍然可能造成方法数 65535 的限制,此时可能需要 Multi dex 的支持。

插件集成

参见SDK集成

接口说明

全文检索接口为:LuceneService ,具体 API 如下(下面只列出异步版本,同步版本 API 也提供,详见客户端API文档 )。针对需求2,强烈建议您使用分页查询接口。

/**
 * 检索所有会话,返回每个会话与检索串匹配的消息数及最近一条匹配的消息记录。(异步函数)
 *
 * @param query 待检索的字符串
 * @param limit 最多返回多少条记录
 * @return InvocationFuture 可以设置回调函数,回调时返回聊天消息全文检索结果集
*/
public InvocationFuture<List<MsgIndexRecord>> searchAllSession(String query, int limit);

/**
 * 检索指定的会话,返回该会话中与检索串匹配的所有消息记录。(异步函数)
 *
 * @param query       待检索的字符串
 * @param sessionType 待检索的会话类型(个人/群组)
 * @param sessionId   待检索的会话ID
 * @return 聊天消息全文检索结果集
*/
public InvocationFuture<List<MsgIndexRecord>> searchSession(String query, SessionTypeEnum sessionType, String sessionId);

/**
 * 指定会话关键字查询(分页返回匹配记录)(异步)
 *
 * @param query       待检索的字符串
 * @param sessionType 待检索的会话类型(个人/群组)
 * @param sessionId   待检索的会话ID
 * @param pageIndex   页码(从第一页开始)
 * @param pageSize    分页大小
 * @return InvocationFuture 可以设置回调函数,回调时返回聊天消息全文检索结果集
*/
public InvocationFuture<List<MsgIndexRecord>> searchSessionPage(String query, SessionTypeEnum sessionType, String sessionId, int pageIndex, int pageSize);

/**
 * 指定会话关键字查询(分页查询:根据锚点,返回下一页匹配记录)(异步)
 *
 * @param query       待检索的字符串
 * @param sessionType 待检索的会话类型(个人/群组)
 * @param sessionId   待检索的会话ID
 * @param anchor      首页传null,下一页传上一页的最后一条记录
 * @param pageSize    分页大小
 * @return InvocationFuture 可以设置回调函数,回调时返回聊天消息全文检索结果集
*/
public InvocationFuture<List<MsgIndexRecord>> searchSessionNextPage(String query, SessionTypeEnum sessionType, String sessionId, MsgIndexRecord anchor, int pageSize);

/**
 * 指定会话关键字查询匹配记录总数(同步)
 *
 * @param query       待检索的字符串
 * @param sessionType 待检索的会话类型(个人/群组)
 * @param sessionId   待检索的会话ID
 * @return 匹配的记录总数
*/
public int searchSessionMatchCount(String query, SessionTypeEnum sessionType, String sessionId);

/**
 * 指定会话关键字查询匹配记录总页数(同步)
 *
 * @param query       待检索的字符串
 * @param sessionType 待检索的会话类型(个人/群组)
 * @param sessionId   待检索的会话ID
 * @param pageSize    分页每页记录数
 * @return 匹配的记录总页数
*/
public int searchSessionPageCount(String query, SessionTypeEnum sessionType, String sessionId, int pageSize);

/**
 * 获取所有缓存数据的大小
 * @return 缓存数据字节数
 */
public long getCacheSize();

/**
 * 删除所有缓存数据
 */
public void clearCache();