我正在开发一个c#应用程序,它从Lotus Notes数据库(.nsf文件,没有Domino服务器)中的所有文档中提取元数据:
NotesDocumentCollection documents = _notesDatabase.AllDocuments;
if (documents.Count>0)
{
NotesDocument document = documents.GetFirstDocument();
while (document!=null)
{
//processing
}
}
这很有效,除了我们还需要记录文档出现的所有视图。我们迭代所有这些视图:
foreach (var viewName in _notesDatabase.Views)
{
NotesView view = _notesDatabase.GetView(viewName);
if (view != null)
{
if (view.AllEntries.Count > 0)
{
folderCount = view.AllEntries.Count;
NotesDocument document = view.GetFirstDocument();
while (document!=null)
{
//record the document/view cross reference
document = view.GetNextDocument(document);
}
}
Marshal.ReleaseComObject(view);
view = null;
}
}
以下是我的问题和疑问:
我们经常在视图中遇到NotesDatabase.AllDocuments集合中找不到的文档。怎么可能?有没有更好的方法来获取笔记数据库中的所有文件?
有没有办法在不循环浏览所有视图和文档的情况下找出文档的所有视图?这部分过程可能非常慢,尤其是在大型nsf文件(35 GB!)上。我很想找到一种方法来获取一个视图名称列表和Document.UniversalID。
如果没有更有效的方法来查找所有文档+视图信息,是否可以并行执行此操作,使用单独的线程/工作程序/处理每个视图?
谢谢!
答案 0 :(得分:0)
以相同的顺序回答问题:
我不确定这是怎么可能的,除非可能有一个特殊类型的文档没有被AllDocuments属性返回。也许排除复制冲突?
不幸的是,没有比这更好的方法了。视图实际上只是一个保存的数据库查询,它返回匹配文档的列表。没有与文档直接关联的视图列表。
您可以通过在自己的线程上处理每个视图来并行执行此操作,但瓶颈可能是需要刷新视图的Domino服务器,因此可能无法获得太多收益。
另外一点,视图中的“AllEntries”与视图中的所有文档都不同。条目可以包括类别行,它只是一个分组,不受实际文档的支持。换句话说,AllEntries的计数可能超过所有文档的计数。
答案 1 :(得分:0)
嗯,首先,在作业运行时可能会创建文档。循环遍历AllDocuments需要时间,然后循环遍历所有视图需要时间。除非您正在处理与所有其他可能用户隔离的数据库的副本或副本,否则您可以轻松地遇到在加载AllDocuments之后但在访问其中一个视图之前创建文档的情况。
此外,view.getXXXDocument()
方法返回的某些对象是否可能是已删除的文档。您应该检查document.isValid()
以避免尝试处理它们。
我打算建议使用NotesNoteCollection作为对AllDocuments的检查。如果AllDocuments正在返回完整的文档集,或者如果NotesNoteCollection(在选择文档和构建集合之后),那么有一种方法可以比迭代每个视图更快。
(1)从视图中读取所有选择公式,删除单词' SELECT'并将它们保存在{view name,formula}对的列表中。
(2)遍历文档(来自NotesNoteCollection或AllDocuments),对于每个文档,您可以使用foreach迭代视图/公式对列表。在每个公式上使用NotesSession.Evaluate
方法,将当前文档传入上下文。从任何评估公式返回True会告诉您文档位于与公式对应的视图中。
它仍然是蛮力,但它必须比迭代所有视图更快。