You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

IBM Domino Java优化:提升$(Rooms)视图特定互联网地址搜索效率

优化IBM Domino Rooms视图查询性能的方案

嘿,我完全理解你现在的困扰——遍历整个$(Rooms)视图来逐个查找会议室文档,这种线性扫描在处理批量请求时效率肯定拉胯,50个查询花18秒确实没法接受。咱们来把这个逻辑彻底优化一下,利用Domino的视图索引和搜索能力来大幅提升速度。

问题根源

你当前的代码用ViewNavigator从头到尾遍历所有视图条目,本质是线性扫描,如果视图里有上百甚至上千个会议室条目,每次查询都要走一遍全量数据,性能自然差。Domino的视图本身是带索引的,咱们要直接利用这个索引来做精准查询,而不是手动遍历。

优化方案1:使用公式搜索(快速实现,无需修改视图)

如果不想改动系统自带的$(Rooms)视图,最快捷的方式是用Domino的Database.search()方法,通过公式直接筛选出匹配InternetAddress的文档,跳过全量遍历:

Session session = ExtLibUtil.getCurrentSession();
Database names = session.getDatabase(session.getServerName(), "names.nsf");

// 构建精确匹配的搜索公式,注意转义双引号
String escapedMail = mail.replace("\"", "\"\"");
String searchFormula = "InternetAddress = \"" + escapedMail + "\"";

// 执行搜索,直接拿到匹配的文档集合
DocumentCollection dc = names.search(searchFormula);
Document docRoom = null;

if (dc.getCount() > 0) {
    docRoom = dc.getFirstDocument();
}

// 后续获取会议室信息的逻辑不变
if(docRoom == null) {
    dc.recycle();
    return null;
}

String fileName = docRoom.getItemValueString("MailFile");
String fileServer = docRoom.getItemValueString("MailServer");
String fullName = docRoom.getItemValueString("FullName");

// 务必回收资源,避免内存泄漏
dc.recycle();
docRoom.recycle();
names.recycle();

这种方式会直接利用Domino的索引能力,查询速度会比遍历快几个数量级。

优化方案2:创建自定义视图(性能最优推荐)

如果你的应用需要频繁做这类查询,建议创建一个自定义视图(不要修改系统自带的$(Rooms)视图,避免升级或系统变更时出问题),把InternetAddress设为第一列并勾选“排序”和“为列创建索引”。

假设你创建的视图名为(RoomsByInternetAddress),代码可以改成:

Session session = ExtLibUtil.getCurrentSession();
Database names = session.getDatabase(session.getServerName(), "names.nsf");
View vw = names.getView("(RoomsByInternetAddress)");

// 利用视图索引直接获取匹配的文档,true表示精确匹配
Document docRoom = vw.getDocumentByKey(mail, true);

if(docRoom == null) {
    vw.recycle();
    names.recycle();
    return null;
}

String fileName = docRoom.getItemValueString("MailFile");
String fileServer = docRoom.getItemValueString("MailServer");
String fullName = docRoom.getItemValueString("FullName");

// 回收资源
docRoom.recycle();
vw.recycle();
names.recycle();

这种方式是性能最优的,因为getDocumentByKey直接命中视图索引,几乎是O(1)的查询时间。

批量查询的额外优化

你需要处理50个会议室,建议一次性批量查询所有需要的邮件地址,而不是逐个查询,减少和names.nsf的交互次数。比如:

// 假设mails是包含50个会议室邮件地址的List<String>
List<String> mails = Arrays.asList("room1@domain.com", "room2@domain.com", ...);

// 构建批量查询公式
StringBuilder formulaBuilder = new StringBuilder("@In(InternetAddress; [");
for(int i=0; i<mails.size(); i++) {
    if(i > 0) formulaBuilder.append(";");
    formulaBuilder.append("\"").append(mails.get(i).replace("\"", "\"\"")).append("\"");
}
formulaBuilder.append("])");

DocumentCollection dc = names.search(formulaBuilder.toString());
// 遍历文档集合,把结果缓存到Map里(key=InternetAddress,value=会议室信息)
Map<String, RoomInfo> roomCache = new HashMap<>();
Document doc = dc.getFirstDocument();
while(doc != null) {
    String addr = doc.getItemValueString("InternetAddress");
    RoomInfo info = new RoomInfo();
    info.setMailFile(doc.getItemValueString("MailFile"));
    info.setMailServer(doc.getItemValueString("MailServer"));
    info.setFullName(doc.getItemValueString("FullName"));
    roomCache.put(addr, info);
    
    Document nextDoc = dc.getNextDocument(doc);
    doc.recycle();
    doc = nextDoc;
}
dc.recycle();

// 后续处理直接从缓存取
for(String mail : mails) {
    RoomInfo info = roomCache.get(mail);
    // 处理约会逻辑
}

这样一次查询就能拿到所有需要的会议室信息,避免了50次单独的数据库请求,性能会再上一个台阶。

额外注意事项

  • 资源回收:Domino的Java对象(Session、Database、View、Document等)必须手动回收,否则会导致内存泄漏,长期运行会影响服务器性能。
  • 索引检查:确保InternetAddress字段在names.nsf中被索引(可以在数据库属性的“全文索引”或视图列索引里配置),这样搜索会更快。

内容的提问来源于stack exchange,提问作者AJ Cole

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 18:02:44