Autor Thema: Problem mit db.search  (Gelesen 5029 mal)

Offline Alfirin

  • Frischling
  • *
  • Beiträge: 10
Problem mit db.search
« am: 02.07.14 - 12:53:37 »
Ich habe hier eine (doch schon etwas betagte) Datenbank, in der ca. 700.000 Dokumente gespeichert sind. Die Dokumente enthalten ein Feld mit einer Kundennummer, welches anhand eine Referenzdatenbank mit einer neuen Kundennummer überschrieben werden soll.

Da die Anzahl der Dokumente sehr groß ist, möchte ich immer nur jeweils einen Block an Dokumenten auslesen und diese dann ändern. Anschließend den nächsten Block etc.



Sub ChangeKUndNr
   
   On Error GoTo errorhandler

   Dim sThis As New NotesSession
   Dim dbThis As NotesDatabase
   Dim dbKNUD As NotesDatabase
   Dim viewKAOSUCH As NotesView
   Dim docclSearch As NotesDocumentCollection
   Dim docProfil As NotesDocument
   Dim docBase As NotesDocument
   Dim DocKNUD As NotesDocument
   
   Dim iAnswer As Integer
   Dim lCounterDoc As Long
   Dim lCounterBlock As Long
   Dim strSearch As String
   Dim strKN As String
   Dim strKNOSP As String
   Dim strForm As String
   

   
   '### initialize ###

   Set dbThis = sThis.CurrentDatabase
   strSearch = "@Modified < @Date(" + Str$(Year(Now())) + ";" + _
   Str$(Month(Now())) + ";" + _
   Str$(Day(Now())) + ";" + _
   Str$(Hour(Now())) + ";" + _
   Str$(Minute(Now())) + ";" + _
   Str$(Second(Now())) + ")"
   
   iAnswer = MessageBox("Sind Sie sicher, dass Sie in der Datenbank " & dbThis.Title & " alle Kundennummern überarbeiten möchten?", MB_YESNO + MB_ICONQUESTION, dbThis.Title)
   If iAnswer = IDNO Then GoTo terminate
   
   'Zugang zur KNUD-Datenbank ermitteln und DB öffnen
   Set docProfil = dbThis.Getprofiledocument("Profil")
   Set dbKNUD = sThis.Getdatabase(docProfil.KNUDServer(0), docProfil.KNUDPfad(0))
   Set viewKAOSUCH = dbKnud.Getview("kaosuch")
   
   'den ersten Block zur Bearbeitung holen
   Set docclSearch = dbThis.Search(strSearch, Nothing, 11)
   lCounterBlock = 1         
   Do While docclSearch.Count > 0

      'Alle Dokumente der DB 'Kreditaktenarchiv' durchlaufen
      Set docBase = docclSearch.Getfirstdocument()
      lCounterDoc = docclSearch.Count
      
      Do While Not docBase Is Nothing
         
         strKN = ""
         strKNOSP = ""
         Print lCounterBlock & ". Block - Es sind noch " & lCounterDoc & " von " & docclSearch.Count & " zu bereinigen ..."
         
         strForm = docBase.Form(0)
         Select Case strForm
         Case "Akte","Eingabe":
            strKN = Format$(docBase.Kundennummer(0),"0000000000")
         Case "Historie":
            strKN = Format$(docBase.HKundennummer(0),"0000000000")
         Case Else:
            GoTo nextDoc
      End Select
         
         'Set docKNUD = viewKAOSUCH.Getdocumentbykey(strKN, True)               --> für Test auskommentiert
         If Not docKNUD Is Nothing Then
            strKNOSP = docKNUD.KundenummerOSP(0)
            Select Case strForm
            Case "Akte","Eingabe":
               docBase.KundennummerAlt = Format(strKN,"#########0")
               docBase.Kundennummer = Format(strKNOSP,"#########0")
            Case "Historie":
               docBase.HKundennummerAlt = Format(strKN,"#########0")
               docBase.HKundennummer = Format(strKNOSP,"#########0")
         End Select
            'Call docBase.Save(False, False, True)         -> für test auskommentiert
         End if
         
nextDoc:   
         Set docBase = docclSearch.Getnextdocument(docBase)
         lCounterDoc = lCounterDoc - 1
         
      Loop
      
      'nächsten Block holen
      Set docclSearch = dbThis.Search(strSearch, Nothing, 11)
      lCounterBlock = lCounterBlock + 1
      
   Loop
   
   Print "Die Bereinigung der Kundennummern in der Datenbank " & dbThis.Title & " ist abgeschlossen."

   '### terminate ###

terminate:
   Set sThis = Nothing
   Set dbThis = Nothing
   Set dbKNUD = Nothing
   Set viewKAOSUCH = Nothing
   Set docclSearch = Nothing
   Set docProfil = Nothing
   Set docBase = Nothing
   Set docKNUD = Nothing

   Exit sub

   '### errorhandling ###

errorhandler:
   MessageBox    "Module: " & "ScriptSPK (Script)" & Chr(10) &_
"Procedure: " & "OpenExtDoc" & Chr(10) &_
"Error: " & Error() & Chr(10) &_
"Code: " & Err() & Chr(10) &_
"Line: " & Erl() & Chr(10) ,_
   MB_OK + MB_ICONSTOP ,_
   dbThis.Title
   Stop
   Resume terminate


End Sub



Das Script liefert mir dann jedoch etwas seltsame Werte.

Code
...
1. Block - Es sind noch -43900 von 11 zu bereinigen ...
1. Block - Es sind noch -43901 von 11 zu bereinigen ...
1. Block - Es sind noch -43902 von 11 zu bereinigen ...
2. Block - Es sind noch 11 von 11 zu bereinigen ...
2. Block - Es sind noch 10 von 11 zu bereinigen ...
2. Block - Es sind noch 9 von 11 zu bereinigen ...
2. Block - Es sind noch 8 von 11 zu bereinigen ...
2. Block - Es sind noch 7 von 11 zu bereinigen ...
2. Block - Es sind noch 6 von 11 zu bereinigen ...
2. Block - Es sind noch 5 von 11 zu bereinigen ...
2. Block - Es sind noch 4 von 11 zu bereinigen ...
2. Block - Es sind noch 3 von 11 zu bereinigen ...
2. Block - Es sind noch 2 von 11 zu bereinigen ...
2. Block - Es sind noch 1 von 11 zu bereinigen ...
2. Block - Es sind noch 0 von 11 zu bereinigen ...
2. Block - Es sind noch -1 von 11 zu bereinigen ...
2. Block - Es sind noch -2 von 11 zu bereinigen ...
2. Block - Es sind noch -3 von 11 zu bereinigen ...
2. Block - Es sind noch -4 von 11 zu bereinigen ...
2. Block - Es sind noch -5 von 11 zu bereinigen ...
...

Offentsichtlich sind in der DocCollection ja die angeforderten 11 Dokumente enthalten. In der inneren Schleife werden dann jedoch alle Dokumente meiner TestDB durchlaufen.

Ich hab jetzt schon alles Mögliche probiert, aber irgenwie sehe ich den Wald vor lauter Bäumen nicht mehr. Hat irgendjemand ne Idee???

Regards


Alfirin

Offline ghostmw

  • Aktives Mitglied
  • ***
  • Beiträge: 201
  • Geschlecht: Männlich
    • BELOS - Raum+Ressourcenmanagement unter Lotus Notes
Re: Problem mit db.search
« Antwort #1 am: 02.07.14 - 13:37:42 »
Hallo Alfirin,

ok, hast du schon mal probiert, dir eine Ansicht zu basteln, und die Notesdocument-Objekte aus der Ansicht zu lesen?

Das ist eine gute Alternative, damit hast du die Limitierung und die Blockbildung nicht, die dir aktuell Probleme bereitet.

Die Selektionsformel kannst du mit der Eigenschaft SelectionFormula des NotesView-Objektes manipulieren und setzen, mit den Paramtern aus deinem Search-Aufruf.
Z.B. Select Form="MEINEFORM" & myDate >= [1.1.2014]

Das kannst du ggf. auch in der Hilfe nachlesen.
Ein Refresh der Ansichtsdaten und es kann mit dem Iterieren losgehen über alle Dokumente ( => getFirst/getNextDocument ).

Wäre zu überlegen.

Gruß
Marco
« Letzte Änderung: 02.07.14 - 13:39:21 von ghostmw »
Grüße
Marco Weller
Lotus Domino / Lotus Notes seit 1996 (ab 4.5x)

Offline Alfirin

  • Frischling
  • *
  • Beiträge: 10
Re: Problem mit db.search
« Antwort #2 am: 02.07.14 - 14:03:01 »
Hallo Marco,

das wäre sicher auch ein gangbarer Weg. Aber mich interessiert doch zunächst, wieso in der DocCollection die korrekte Anzahl an Dokumenten über 'Count' ausgewiesen wird, wenn ich dann jedoch die Dokumente 'durchblättere' ein aus meiner Sicht völlig unlogisches Verhalten auftritt.

Da die Ursache des Fehlers ja in der Regel vor der Tastatur sitzt würde ich doch gern die Ursache kennen, damit ich zukünftig nicht in die selbe Falle tappe.  ;D

Regards


Alfirin

Offline ghostmw

  • Aktives Mitglied
  • ***
  • Beiträge: 201
  • Geschlecht: Männlich
    • BELOS - Raum+Ressourcenmanagement unter Lotus Notes
Re: Problem mit db.search
« Antwort #3 am: 02.07.14 - 14:23:45 »
Ok, verstehe ...
ich gehe immer den Ansatz, wenn ich länger als x Minuten nach einem Problem und dessen Ursache suche, nehme ich eine andere Variante.

Also du machst in deinen Schleifen db.Search.
Da bekommst du 0-11 Treffern, meiner Meinung nach bekommst du doch aber immer die gleichen x Treffer aus meiner Sicht zurückgeliefert und nicht fortlaufend. Das gibt der Befehl nicht her.

Zitat
 Loop
      
      'nächsten Block holen
      Set docclSearch = dbThis.Search(strSearch, Nothing, 11)
      lCounterBlock = lCounterBlock + 1
      
   Loop

Da liegt der Hase im Pfeffer ...

Zitat
extDoc:  
         Set docBase = docclSearch.Getnextdocument(docBase)

Da könnte auch eine Ursache liegen, du manipulierst und speicherst das docBase, und holst dann anhand dessen das nächste Dokument. Wenn man Views benutzt, und das Dokument durch das Speichern aus der Ansicht verschwindet, knallts hier u.U.
Ich kann aktuell nicht ausschließen, dass es bei dir nicht auch so sein könnte.

Wie dein Script überhaupt fertig werden kann, ist noch ein wenig schleierhaft, das müsste eine Endlosschleife geben für  
Code
docclSearch.Count > 0
.
Grüße
Marco Weller
Lotus Domino / Lotus Notes seit 1996 (ab 4.5x)

Offline Alfirin

  • Frischling
  • *
  • Beiträge: 10
Re: Problem mit db.search
« Antwort #4 am: 02.07.14 - 15:02:03 »
Hallo Marco,

richtig. Zur Zeit bekomme ich immer dieselben 11 Treffer, da ich das docThis.Save auskommentiert habe. Ich wollte halt ganz bewusst noch keine Veränderung an den Dokumenten durchführen, solange die Schleife nicht korrekt läuft. Darüber hinaus sollen die Blöcke im Echtbetrieb dann auch eine Größe von 30.000 Dokumenten haben.

Wenn das docThis.Save dann ausgeführt wird, müsste ja auch die Treffermenge immer geringer werden, da die Dokumente ja dann mit einem aktuelleren Datum verändert worden sind und somit nicht mehr den Suchkriterien entsprechen. Irgendwann würde dann auch ein Block mit Count=0 zurückgeliefert werden und die Schleife somit beendet.

Zum jetzigen Zeitpunkt ist es allerdings wirklich eine Endlosschleife, welche ich jedoch über den Debugger beende.  8)

Zitat
Da könnte auch eine Ursache liegen, du manipulierst und speicherst das docBase, und holst dann anhand dessen das nächste Dokument. Wenn man Views benutzt, und das Dokument durch das Speichern aus der Ansicht verschwindet, knallts hier u.U.
Ich kann aktuell nicht ausschließen, dass es bei dir nicht auch so sein könnte.

Hm. Das kann ich mir so nicht recht vorstellen. Zum Einen handelt es sich doch hier um eine DocCollection und nicht um einen View und die DocCollection sollte doch eigentlich statisch sein, oder? Zum Anderen hab ich ja die Speicherung auskommentiert. Somit sollte es doch zum jetzigen Zeitpunkt sauber laufen.

Regards



Alfirin

Mitch

  • Gast
Re: Problem mit db.search
« Antwort #5 am: 02.07.14 - 15:29:57 »
Set docclSearch = dbThis.Search(strSearch, Nothing, 11)
   lCounterBlock = 1         
  Do While docclSearch.Count > 0

      'Alle Dokumente der DB 'Kreditaktenarchiv' durchlaufen
      Set docBase = docclSearch.Getfirstdocument()
      lCounterDoc = docclSearch.Count

Warum sollte sich der Count auch ändern? Du kickst ja nirgendwo ein Dokument aus der Collection. Der bleibt also immer größer als Null. Endlossschleife. Oder übersehe ich da etwa etwas?

Laufe Collections doch lieber so in der Art durch:
Code
coll = db.Search({foo}, Nothing, 0)
Set doc = coll.GetFirstDocument
While Not doc Is Nothing

   'Code

   Set doc = coll.GetNextDocument(doc)

Wend

Gruß,

Mitch

Offline ghostmw

  • Aktives Mitglied
  • ***
  • Beiträge: 201
  • Geschlecht: Männlich
    • BELOS - Raum+Ressourcenmanagement unter Lotus Notes
Re: Problem mit db.search
« Antwort #6 am: 02.07.14 - 15:53:45 »
Ok, mit einer "statischen" DocCollection sollte es passen.

Das mit dbSearch ist aber alles andere als performant mit den vielen Aufrufen, das aber nur nebenbei.

Code
Do While Not docBase Is Nothing
         
         strKN = ""
         strKNOSP = ""
         Print lCounterBlock & ". Block - Es sind noch " & lCounterDoc & " von " & docclSearch.Count & " zu bereinigen ..."
         
       ...

nextDoc:   
     [i][b]    Set docBase = docclSearch.Getnextdocument(docBase)[/b][/i]
         lCounterDoc = lCounterDoc - 1
         
      Loop 

das aber wundert mich, die Schleife wird bei dir erst nach zig tausend (ca. 40000) Durchläufen beendet.
Ich vermute mal, er navigiert dich trotzdem auf das nächste Dokument in der Gesamtmenge und beschränkt sich nicht auf die 11 Treffer ?

Lass dir mal in einer Schleife die UNID ausgeben und bei deinem bestehenden Print auch, vielleicht erkennt man da was uns hilft.
Grüße
Marco Weller
Lotus Domino / Lotus Notes seit 1996 (ab 4.5x)

Offline Andrew Harder

  • Senior Mitglied
  • ****
  • Beiträge: 295
  • Geschlecht: Männlich
Re: Problem mit db.search
« Antwort #7 am: 02.07.14 - 16:03:53 »
Ich habe da mal eine Verständnisfrage dazu.
Verstanden habe ich schon, das sich in der Datenbank ca. 700.000 Dokumente befinden und es wird db.Search benutzt.
Meine Fragen dazu:
1. Hat diese Datenbank einen Volltxtindex?  :-:
2. Hat die Blockbildung eine technischen Hintergrund?
« Letzte Änderung: 02.07.14 - 16:07:19 von Andrew Harder »
Andy

Offline umi

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.062
  • Geschlecht: Männlich
  • one notes to rule'em all, one notes to find'em....
    • Belsoft AG
Re: Problem mit db.search
« Antwort #8 am: 02.07.14 - 16:07:01 »
Moin

Ich würde, wie schon vorgeschlagen, das ganze über eine Ansicht erledigen. Auch bei 700'000 Datensätzen, sollte das relativ schnell sein, wenn das als server Agent läuft.
Da hier die Kundennummer mehrfach vorkommt, kannst Du dir das Result des Lookups in einer Liste cachen. Was Dir hier eine menge lookups erspart.
Damit hast du nur noch 1 Loop.
Sehr viel zeit benötigt wohl die DB Search selber und ausserdem gibts da einen kleinen bug siehe http://www.iminstant.com/iminstant/iminstant.nsf/d6plinks/CTYR-77KRBX

Falls du es trotzdem blockweise machen möchtest, würde ich in der Ansicht noch die Selection auf ein Feld z.B. KdnNr.Aktualisiert="" machen und im Loop dieses Feld setzen. dann kannst Du die Ansicht durcharbeiten und per counter z.B. nach 10 oder 100 Dokumenten abbrechen.
Gruss

Urs

<:~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jegliche Schreibfehler sind unpeabischigt
http://www.belsoft.ch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~:>

Offline ghostmw

  • Aktives Mitglied
  • ***
  • Beiträge: 201
  • Geschlecht: Männlich
    • BELOS - Raum+Ressourcenmanagement unter Lotus Notes
Re: Problem mit db.search
« Antwort #9 am: 02.07.14 - 16:12:44 »
Bingo, Count ist 11 und dein Loop geht über alle ca. 40000 Dokumente mit getNextDocument.

Mein "Vorredner" hat sogar den "Bug" mit Link geliefert und meine Ahnung bestätigt.

Also wären wir wieder bei einer Alternative wie der View.

Grüße
Marco Weller
Lotus Domino / Lotus Notes seit 1996 (ab 4.5x)

Offline Andrew Harder

  • Senior Mitglied
  • ****
  • Beiträge: 295
  • Geschlecht: Männlich
Re: Problem mit db.search
« Antwort #10 am: 02.07.14 - 16:24:07 »
Spricht etwas gegen
set docclSearch = dbThis.AllDocuments
?

Zur Blockbildung:
700.000 Dokumente / 10 er Block = 70.000 Aufrufe
Wenn der Agent alle 5 Minuten aufgerufen wird sind das also 70.000 * 5 = 350.000 Minuten, also ca. 244 Tage.
Bei 250er Blöcken wären es nur 2 Tage ;)

« Letzte Änderung: 02.07.14 - 16:26:58 von Andrew Harder »
Andy

Offline Alfirin

  • Frischling
  • *
  • Beiträge: 10
Re: Problem mit db.search
« Antwort #11 am: 02.07.14 - 16:24:53 »
@umi

mille grazie. Da bin ich also doch in einen Bug reingeschlittert.  >:D Ok. Dann werd ich mal doch die view-Variante angehen.

@all others
Auch an euch meinen Dank für die Unterstützung!

Regards


Alfirin

Offline Alfirin

  • Frischling
  • *
  • Beiträge: 10
Re: Problem mit db.search
« Antwort #12 am: 02.07.14 - 16:26:53 »
@Andrew
Den 10er-Block habe ich nur in der Testumgebung gewählt, weil ich dort nicht mit so viel Dokumenen rumjonglieren wollte. Im Echtbetrieb soll der Block auf 30.000 erweitert werden.

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz