Извлеченные родительские папки из документа не всегда корректны
Мы переносим содержимое библиотеки из Filenet Content Services в Filenet P8.
Итак, мы написали экстрактор, который выводит дерево папок и список документов в формате XML, каждый документ с версиями, свойствами и родительской папкой. Этот экстрактор опирается на самодельный DLL, который виртуализирует объекты FileNet.
Документы извлекаются следующим образом (огромный запрос sql):
Public Function getAllDocumentIds() As ADODB.Recordset
Dim cmdProperties As New Dictionary
cmdProperties.Item("Maximum Rows") = 0
cmdProperties.Item("Page Size") = 0
Set getAllDocumentIds = _
executeADOQuery("SELECT idmId, idmVerFileName, " & vbNewLine & _
" idmVerCreateDate, idmAddedByUser" & vbNewLine & _
" FROM FNDOCUMENT ORDER BY idmId ASC", & _
cmdProperties)
End Function
Но мы сталкиваемся с проблемами при извлечении родительских папок таким способом (слегка измененным для использования в качестве примера):
Public Function getFolders(document As IDMObjects.document) As Collection
Dim f As IDMObjects.Folder
' [...]
For Each f In document.FoldersFiledIn '
' folders retrieval
Next
End Function
Для небольшого количества документов сообщается о некоторых "неправильных" родительских папках ("папки, в которых находится документ").
"Неверно", потому что следующий способ не сообщает о том, что документ был в них подан (слегка измененный код):
Public Function getDocumentIds(folder As IDMObjects.Folder) As Collection
Dim rs As ADODB.Recordset
Dim cmdProperties As New Dictionary
' Actually there is a control here, to prevent Filenet crashing.
' Indeed, setting "Page Size" to 0 crashes if no results are returned.
' *Maybe* a product bug.
cmdProperties.Add "SearchFolderName", internalObject.id ' Folder parent
cmdProperties.Item("Maximum Rows") = 0 ' No limits
cmdProperties.Item("Page Size") = 0 ' No limits. Crashes if Recordset is empty
' Here, the cmdProperties entries are copied to an
' ADODB.Command object, into the "properties" member.
' The query are copied to this object, into the "CommandText" member.
' Then ADODB.Command.Execute is invoked and returs an ADODB.RecordSet.
' So this Recordset contains all documents filled in this folder.
Set rs = executeADOQuery("SELECT * from FnDocument", cmdProperties)
Exit Function
End Function
Мы работаем над обходным решением, которое может потребовать больше ресурсов (для каждого документа дважды проверьте...). Но понимание того, почему мы не получаем одинаковых результатов, может оказаться уместным для проверки нашей библиотеки.
1 ответ
Если я правильно понимаю проблему, я считаю, что быстрый ответ состоит в том, что логический порядок родительских и дочерних записей в наборе результатов не может быть гарантирован запросом. Вы делаете предположение о последовательности ID. Документ можно перемещать, поэтому нет ничего, что могло бы гарантировать, что идентификатор папки будет иметь место перед идентификатором документа или наоборот. Для большого набора документов, чтобы решить эту проблему без рекурсии, отложите дочерние записи без родителя и разрешите их позже (в примере я использовал страж для пометки / фильтрации таких записей). В зависимости от количества "потерянных" строк, вы можете сделать это в памяти, или это может потребовать второго прохода. Метод getrows позволит вам обрабатывать "огромные" наборы данных, особенно если вы используете XML и не хотите исчерпывать память.