Java 迭代LotusDomino中的每个文档
我希望迭代一个(可能很大的)LotusDomino数据库中的每个文档,如果处理中断(网络连接错误、应用程序重新启动等),我能够从上一个文档继续它。我没有对数据库的写入权限 我正在寻找一种不必从服务器下载已经处理过的文档的方法。因此,我必须将一些起始信息传递给服务器,哪个文档应该是(可能重新启动的)处理中的第一个文档Java 迭代LotusDomino中的每个文档,java,lotus-notes,lotus-domino,Java,Lotus Notes,Lotus Domino,我希望迭代一个(可能很大的)LotusDomino数据库中的每个文档,如果处理中断(网络连接错误、应用程序重新启动等),我能够从上一个文档继续它。我没有对数据库的写入权限 我正在寻找一种不必从服务器下载已经处理过的文档的方法。因此,我必须将一些起始信息传递给服务器,哪个文档应该是(可能重新启动的)处理中的第一个文档 我已经检查了AllDocuments属性和documentcollation.getNthDocument方法,但该属性未排序,因此我猜两次调用之间的顺序可能会改变 另一个想法是使用
AllDocuments
属性和documentcollation.getNthDocument
方法,但该属性未排序,因此我猜两次调用之间的顺序可能会改变数据库.getModifiedDocuments
方法,该方法具有相应的文档.getLastModified
方法。看起来不错,但是
在我看来,返回集合的顺序并没有记录在案,而是基于创建时间而不是上次修改时间
以下是基于以下内容的示例代码:
它打印以下内容:
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做到这一点吗?我不使用Java API,但在Lotusscript中,我会这样做:
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。其他列包含您希望在代理中读取的所有值,在您的示例中,这些值将是创建日期和上次修改日期
然后,您的代码可以简单地在视图中循环,如下所示:
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),否则返回最后一个成功的值。如果您有权更改数据库,或者可以要求他人这样做,那么您应该创建一个按唯一键或修改日期排序的视图,然后只存储“指针”到最后处理的文档 除此之外,您必须自己维护以前处理过的文档的列表。在这种情况下,您可以使用AllDocuments属性,只需遍历它们。使用GetFirstDocument和GetNextDocument,因为据报道它们比GetNthDocument快
或者,您可以进行两次传递,一次用于收集所有文档的UNID列表,然后进行第二次传递以处理UNID列表中的每个文档(使用GetDocumentByUNID方法).Lotus Notes/Domino数据库设计为在复制环境中跨客户端和服务器分布。在一般情况下,您不能保证在给定的创建或修改时间开始将为您带来一致的结果 如果100%确定目标数据库没有复制副本,则可以使用getModifiedDocuments,然后编写排序例程,将(modDateTime,UNID)对放入SortedSet或其他合适的数据结构中。然后,您可以处理整个集合,如果遇到错误,您可以将尝试处理的元素的modDateTime保存为重新启动点。但是,如果有多个文档具有完全相同的modDateTime戳,您可能需要了解一些额外的细节以避免重复
我想最后说一句话。我知道您在询问Java,但如果您正在为法规遵从性目的开发备份或归档系统,那么LotusCAPI有一些特殊的功能,您确实应该看看 代理已经保留了一个字段来描述他们尚未处理的文档,这些文档将通过正常处理自动更新
更好的方法是将搜索结果存储在配置文件文档中。但是,如果您试图关联数据库中您没有写入权限的文档,那么您唯一能做的就是保留一个您已经处理过的文档链接列表(以及您需要保留的关于这些文档的任何信息),或者一个姐妹数据库,每个doclink包含一个文档,外加多个与您对它们所做的处理相关的字段。然后,传输ID列表并在客户机上执行匹配,以进行每个文档的查找。由于您没有对源数据库的写访问权限,因此必须将已处理的所有文档的UniversalID存储在另一个数据库甚至本地文本文件中,并跳过已处理一次的文档。UNID不会改变,因此它可以为您提供更多的保证,您只需处理每个文档一次。@srini.venigalla:当前的解决方案与此非常相似,但我希望避免再次下载和跳过已处理的文档。重新启动的开销似乎很大。我本来打算建议使用NotesDatabase类的UnprocessedDocuments属性,但这似乎需要AgentContext。