我想迭代一个(可能很大的)Lotus Domino数据库中的每个文档,并且如果处理中断(网络连接错误,应用程序重启等),则能够从最后一个继续它。我没有对数据库的写访问权。
我正在寻找一种方法,我不必从服务器上下载那些已经处理过的文件。所以,我必须将一些起始信息传递给服务器,该文档应该是(可能重新启动)处理中的第一个。
我已检查AllDocuments
属性和DocumentColletion.getNthDocument
方法,但此属性未排序,因此我猜订单可以在两次调用之间更改。
另一个想法是使用formula query,但似乎这些查询无法进行排序。
第三个想法是Database.getModifiedDocuments
方法,对应Document.getLastModified
方法。看起来不错但是
它在我看来,返回集合的顺序没有记录,并且基于创建时间而不是最后修改时间。
以下是基于official example的示例代码:
System.out.println("startDate: " + startDate);
final DocumentCollection documentCollection =
database.getModifiedDocuments(startDate, Database.DBMOD_DOC_DATA);
Document doc = documentCollection.getFirstDocument();
while (doc != null) {
System.out.println("#lastmod: " + doc.getLastModified() +
" #created: " + doc.getCreated());
doc = documentCollection.getNextDocument(doc);
}
它打印以下内容:
startDate: 2012.07.03 08:51:11 CEDT
#lastmod: 2012.07.03 08:51:11 CEDT #created: 2012.02.23 10:35:31 CET
#lastmod: 2012.08.03 12:20:33 CEDT #created: 2012.06.01 16:26:35 CEDT
#lastmod: 2012.07.03 09:20:53 CEDT #created: 2012.07.03 09:20:03 CEDT
#lastmod: 2012.07.21 23:17:35 CEDT #created: 2012.07.03 09:24:44 CEDT
#lastmod: 2012.07.03 10:10:53 CEDT #created: 2012.07.03 10:10:41 CEDT
#lastmod: 2012.07.23 16:26:22 CEDT #created: 2012.07.23 16:26:22 CEDT
(我这里不使用任何AgentContext
来访问数据库。数据库对象来自session.getDatabase(null, databaseName)
调用。)
有没有办法可靠地使用Lotus Domino Java API执行此操作?
答案 0 :(得分:4)
如果您有权更改数据库,或者可以要求某人这样做,那么您应该创建一个按唯一键或修改日期排序的视图,然后将“指针”存储到最后一个文档处理。
除此之外,您必须自己维护以前处理过的文档列表。在这种情况下,您可以使用AllDocuments属性并迭代它们。使用GetFirstDocument和GetNextDocument,据报道它们比GetNthDocument更快。
或者,您可以进行两次传递,一次是为您收集所有文档的UNID列表,然后再进行第二次传递以处理您拥有的UNID列表中的每个文档(使用GetDocumentByUNID方法)。
答案 1 :(得分:3)
我不使用Java API,但在Lotusscript中,我会做这样的事情:
找到显示数据库中所有文档的视图。如果您希望代理非常快,请创建一个新视图。应对第一列进行排序,并且可以包含文档的通用ID。其他列包含您要在代理中读取的所有值,在您的示例中将是创建日期和上次修改日期。
您的代码可以简单地循环遍历视图:
lastSuccessful = FunctionToReadValuesSomewhere() ' Returns 0 if empty
Set view = thisdb.GetView("MyLookupView")
Set col = view.AllEntries
Set entry = col.GetFirstEntry
cnt = 0
Do Until entry is Nothing
cnt = cnt + 1
If cnt > lastSuccessful Then
universalID = entry.ColumnValues(0)
createDate = entry.ColumnValues(1)
lastmodifiedDate = entry.ColumnValues(2)
Call YourFunctionToDoStuff(universalID, createDate, lastmodifiedDate)
Call FunctionToStoreValuesSomeWhere(cnt, universalID)
End If
Set entry = col.GetFirstEntry
Loop
Call FunctionToClearValuesSomeWhere()
只需将最后一个成功值和通用ID存储在数据库中的文本文件或环境变量甚至配置文件中。 重新启动代理程序时,请使用一些代码检查值是否为空(然后返回0),否则返回上一个成功的值。
答案 2 :(得分:1)
Lotus Notes / Domino数据库旨在分布在复制环境中的客户端和服务器上。在一般情况下,您无法保证在给定的创建或模拟时间开始将为您带来一致的结果。
如果您100%确定没有制作目标数据库的副本,则可以使用getModifiedDocuments然后编写排序例程以将(modDateTime,UNID)对放入SortedSet或其他合适的数据结构中。然后您可以通过Set进行处理,如果遇到错误,可以将尝试处理的元素的modDateTime保存为重新启动点。为了避免重复,可能还有一些额外的细节,但是,如果有多个文档具有完全相同的modDateTime标记。
我想做一个最后的评论。我知道您在询问Java,但是如果您正在处理备份或归档系统以实现合规性,那么Lotus C API具有您应该关注的特殊功能。
答案 3 :(得分:1)
代理商已经保留了一个字段来描述他们尚未处理的文档,这些文档会通过正常处理自动更新。
执行您尝试执行的操作的更好方法可能是将搜索结果存储在配置文件中。但是,如果您尝试与数据库中的文档相关而您没有写入权限,那么您唯一能做的就是保留已经处理过的文档链接列表(以及您需要保留的所有信息)文档),或者每个文档链接都有一个文档的姐妹数据库,以及与您对它们进行的处理相关的多个字段。然后,传输ID列表并在客户端上执行匹配以执行每个文档的查找。