Hallo zusammen,
eines gleich vorneweg: wenn jemandem ein besserer Titel für den Thread einfällt - ich ändere das gerne noch ab für's spätere leichte Finden.
DAS IST KEIN FRAGE-THREAD. Ich beschreibe einen möglichen Lösungsvorschlag, ressourcensparend und schnell mehrfach auftretende Werte in Listen zu zählen. Wenn Ihr so ein Problem habt oder es Euch einfach nur interessiert - einfach mal reinlesen. Wenn nicht... lest bitte lieber einen anderen Thread und helft dem Fragesteller bei seinem Problem!
++++++
Ich hatte letztens das Problem, daß ein Agent viel zu lange lief. Größenordnung 15-20 Minuten auf einem ordentlichen Notes-Server. Außerdem ging die CPU-Last auf 50%, 'ne Menge I/O... das Ende vom Lied: der Agent sollte optimiert werden.
Was sollte gelöst werden? Eigentlich eine einfache Aufgabe: Zählen, wie oft Schlüsselworte in Dokumenten vorkommen.
- es gibt X Schlüsselwörter, je Schlüsselwort ein Dokument (sagen wir, FORM="swort")
- es gibt Y Dokumente, die diese Schlüsselwörter in 2 Items enthalten können (Dokument FORM="dokument")
- Item1 = single value text
- Item2 = multi value text
Besonderheiten Item2: hier handelt es sich um eine Historie, je Element wird das Datum geführt und getrennt durch Leerzeichen das zu diesem Datum verwendete Schlüsselwort.
Bsp.
- Schlüsselworte: eins, zwei, drei
- Dokument1, Item1="eins", Item2="01.01.2015 zwei","25.12.2014 drei"
- Dokument2, Item1="zwei", Item2="03.01.2015 eins","02.01.2015 zwei","02.01.2015 zwei"
Hier sieht man schon das Problem im Dokument2: das Element "02.01.2015 zwei" tritt doppelt auf. Ja, das ist in dieser Applikation zulässig und hat eine (sinnvolle) Bedeutung.
"Standard-Ansatz": LISTE
Eine sinnvolle Möglichkeit, das Problem zu lösen (also "wie oft taucht in allen Dokumenten Schlüsselwort zwei auf" usw. für alle Schlüsselworte): alle Dokumente z.B. mit LotusScript durchlaufen, eine Liste mit Index=Schlüsselwort aufbauen und bei jedem gefundenen Schlüsselwort das Listenelement um eins erhöhen.
Ist man durch alle Dokumente durch, liefert Liste(Schlüsselwort) die Anzahl des Vorkommens. In unserem Beispiel (2 Dokumente) also Liste("zwei")=4.
Diese "Listen"-Lösung lief statt 15-20 Minuten ca. 15-20 Sekunden. Neue Agenten wurden in der nächsten Minute in die Queue gestellt, starteten nicht sofort danach. D.h. es ist noch Nachlaufzeit (Housekeeping: Speicher aufräumen) im Nachgang nötig.
Alternativ-Ansatz: "LOOKUP-VIEW"
Ich fand das noch zu langsam und zu umständlich, außerdem plusterte sich die Liste im RAM auf. Anderer Ansatz: Lookup-Ansicht. Das scheitert im ersten Moment daran, daß man zwar Multivalue-Items anzeigen kann, auch mit Mehrfachwerten getrennt, aber je Schlüsselwort gibt's nur eine Zeile in der Ansicht. Für Dokument2 (siehe Bsp. oben) bekomme ich, wenn ich Item1 und Item2 sinnvoll zusammenfasse (Stichwort Datum wegschneiden) nur zwei Zeilen angezeigt:
eins
zwei
Ich MÖCHTE aber eine Anzeige der Form:
eins
zwei
zwei
zwei
damit ich eben direkt in der Ansicht zählen kann, daß "zwei" dreimal auftrat im Dokument.
Die Lösung für die erste (sortierte) Spalte der Lookup-View:
- Trennzeichen T definieren, das in Schlüsselwörtern nicht vorkommt, z.B. "~~"
- Item2 mit einer @For(x:=0; x<=@Elements(Item2)... Schleife durchlaufen
- aus einem gefundenen Schlüsselwort einen String bauen der Form Schlüsselwort+T+@NoteId+T+@Text(x) und alles in einer neuen Liste zusammenfügen
- dazu dann noch Item1 als Item1+T+@NoteId+T+"0"
- über die neue Liste ein @Trim und fertig.
Die Zeilen in der Ansicht sehen jetzt prinzipiell so aus (siehe Beispiel oben, Dokument1 und Dokument2 mit ausgedachten NoteID's):
eins~~NT00005555~~1
eins~~NT0000AAAA~~0
zwei~~NT00005555~~0
zwei~~NT00005555~~2
zwei~~NT00005555~~3
zwei~~NT0000AAAA~~1
drei~~NT0000AAAA~~2
In LotusScript kann man sich jetzt einfach mit
Set vec = LookupView.Getallentriesbykey(Schlüsselwort & Trennzeichen, False)
eine ViewentryCollection geben lassen und die Anzahl der Elemente zählen.
Für unser Beispiel:
Set vec = LookupView.Getallentriesbykey("zwei" & "~~", False)
Print Cstr(vec.Count)
erzeugt als Ausgabe "4".
Im o.g. Agenten durchläuft man dann einfach alle Schlüsselwortdokumente einmal, ermittelt für jedes Schlüsselwort die Summe des Auftretens in den Dokumenten und schreibt den Wert ggf. zurück in das Schlüsselwortdokument für spätere Auswertungen.
Der Index der Lookup-View ist angenehm klein, der Agent läuft jetzt im Schnitt 2s und verbraucht praktisch keinen RAM. Folgeagenten starten praktisch sofort nach Ende des Zähl-Agenten.
Für viele Aufgabenstellungen sind Listen toll, für die o.g. ist der Weg über die spezielle Lookup-Ansicht nochmal schneller und ressourcensparender. Ich war selbst überrascht, wie groß der Unterschied war. Selbst wenn der Ansichts-Index neu aufgebaut werden muß, läuft der Agent nur 5s.
Wer viel mit großen Listen arbeitet weiß, daß sowohl Aufbau als auch Abbau der Liste im RAM Zeit frißt, teilweise Minuten. Gerade Agenten, die im 5-Minuten-Takt laufen sollen, haben so bei steigender Datenmenge zwangsläufig irgendwann "Aussetzer" und werden ggf. erst zum übernächsten 5-Minuten-Intervall in die Amgr-Queue eingestellt.
Vielleicht eine Möglichkeit für den einen oder anderen, an der Stelle den "Turbo" zu zünden. Viel Erfolg beim Ausprobieren!