2012-10-22 70 views
3

我想疊代的(可能大)的Lotus Domino數據庫的每個文檔,並能夠從最後一個,如果處理中斷繼續它(網絡連接錯誤,應用程序啓動等。 )。我沒有對數據庫的寫入權限。遍歷Lotus Domino中的每個文檔

我正在尋找一種方式,我沒有下載從已經處理的服務器的文檔。所以,我必須將一些起始信息傳遞給服務器,該文檔應該是(可能重新啓動的)處理中的第一個。

  1. 我已檢查AllDocuments屬性和DocumentColletion.getNthDocument方法,但此屬性未排序,所以我猜順序可以兩個電話之間切換。

  2. 另一個想法是使用formula query,但它似乎並不認爲排序是可能與這些查詢。

  3. 第三個想法是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))。

Is th是否可以通過Lotus Domino Java API可靠地執行此操作?

+0

由於您沒有對源數據庫的寫訪問權限,因此必須將已處理的所有文檔的UniversalID存儲在另一個數據庫甚至本地文本文件中,並跳過那些已經處理過一次的文檔。 UNID不會更改,因此它可以更加保證您只處理一次文檔。 –

+0

@ srini.venigalla:目前的解決方案與此非常相似,但我想避免再次下載並跳過已處理的文檔。這似乎是一個非常大的開銷。 – palacsint

+0

我打算建議使用NotesDatabase類的UnprocessedDocuments屬性,但它看起來像需要AgentContext。 http://publib.boulder.ibm.com/infocenter/domhelp/v8r0/index.jsp?topic=%2Fcom.ibm.designer.domino.main.doc%2FH_UPDATEPROCESSEDDOC_METHOD_JAVA.html –

回答

4

如果你有機會更改數據庫,或者可以要求別人這樣做,那麼你應該創建一個唯一鍵排序,或者修改日期,然後只是「指針」存儲到最後一個視圖文件已處理。

除非這一點,你必須保持自己先前處理的文檔的列表。在這種情況下,您可以使用AllDocuments屬性並遍歷它們。據報道,使用GetFirstDocument和GetNextDocument比GetNthDocument更快。

或者,您可以製作兩個通行證,一個收集所有文檔的UNID列表,然後再進行第二遍處理,從UNID列表中處理每個文檔(使用GetDocumentByUNID方法) 。

3

我不使用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存儲在說一個文本文件或環境變量或者數據庫甚至profile文件。 當您重新啓動代理程序時,請使用一些代碼檢查值是否爲空(然後返回0),否則返回上一次成功的值。

1

Lotus Notes/Domino數據庫旨在分佈在複製環境中的客戶端和服務器上。在一般情況下,您無法保證從給定的創建時間或模擬時間開始會給您帶來一致的結果。

如果您100%確定目標數據庫沒有副本,那麼您可以使用getModifiedDocuments,然後編寫一個排序例程將(modDateTime,UNID)對放入SortedSet或其他合適的數據結構中。然後,您可以通過Set進行處理,如果遇到錯誤,則可以將您嘗試處理的元素的modDateTime保存爲重新啓動點。可能有一些額外的細節可供您解決,以避免重複,但是,如果有多個文檔具有完全相同的modDateTime標記。

我想做一個最後的評論。我知道您在問Java,但如果您正在爲遵從性目的而在備份或存檔系統上工作,那麼Lotus C API具有您應該關注的特殊功能。

1

代理已保留一個字段來描述尚未處理的文檔,並且這些文檔會通過正常處理自動更新。

做你想做的事情的一種更好的方法可能是將搜索結果存儲在配置文件中。但是,如果您嘗試關聯數據庫中的文檔,但您沒有寫入權限,則唯一可以做的就是保留已處理的文檔鏈接列表(以及需要保留的關於這些文檔的任何信息文檔)或姐妹數據庫爲每個doclink保存一個文檔以及與您對它們進行的處理相關的多個字段。然後,傳輸ID列表並在客戶端上執行匹配,以執行每個文檔查找。