Skip to main content
    Country/region select      Terms of use
     Home      Products      Services & solutions      Support & downloads      My account     

developerWorks  >  Lotus  >  Forums & community  >  Best Practice Makes Perfect

Best Practice Makes Perfect

A collaboration with Domino developers about how to do it and how to get it right in Domino

Joseph LeMay writes:

...each contract has change orders associated with it.  Each change order has to show the amount of the original contract plus all previous change orders, and then the new total, so there's some math to do on each change order, and the more change orders you have, the more math there is.  So what I'd have to do is
set dc = view.GetAllDocumentsByKey(ContractNo)
then loop through the dc by accessing the properties of each document.
But would I get a peformance kick if I did
set viewnav = view.createViewNavFromCategory(ContractNo)
then looped through the view entries?

My answer (and I'm sure someone will correct me if I'm wrong, given the crowd who read this), neither one is significantly more efficient. The performance hit is in the next step, where you retrieve the data. If you use the Columnvalues property to get data from the view, then you're in good shape. If you use NotesDocument.GetItemValue or NotesDocument.fieldname, it takes longer because you have to "crack open" the note rather than just pulling the information from the view table. So use Columnvalues.
To improve performance further, try to avoid iterating through the view entries. In your case, you might be able to do this by taking advantage of category totals. Since a category row is a NotesViewEntry also, you should be able to use the NotesView methods to retrieve the first document row that matches your key, then back up an entry to find the category row. So long as you only get one change order at a time in any given execution of your code, you can get the current total very quickly this way. Even if you get more than one, assuming the documents are sorted properly withing the categories, you should be able to jump to the most recent CO, update it based on the total, then subtract its own figure from the total and move on to the next document, etc as long as you keep finding unprocessed orders.

Andre Guirard | 11 October 2007 11:13:38 PM ET | Plymouth, MN, USA | Comments (2)


1) ColumnValues
Kendall | 10/12/2007 1:02:53 AM

I never tried createviewnavfromcatgory (didn't fit what I needed), but in lots of testing, I found doc.ColumnValues to be very poor...bad enough that I got the impression it opened the document Notes, like doc.FieldName, just by getting the NotesDocument object (or at least by accessing even a property like ColumnValues; I don't think I ever tried just getting the documents and not access ColumnValues, since it wouldn't have helped ;-).

But yeah, NotesViewEntry's ColumnValues is a huge improvement! It's a pity that most FTSearch methods (other than NotesDatabase's) limit the options, but the performance improvement's worth almost any was that much better over doc.ColumnValues.

I also tested variations in what objects I used, like view.FTSearch and then getting AllEntries...versus getting AllEntries and then doing FTSearch. I forget all the variations I tried what what I finally used. (I was sorting results, so that entered into it as well.) Lots of tedious but interesting testing.... ;-)

2) NotesView.GetAllEntriesByKey
Fabian Robok | 10/12/2007 3:59:42 AM

Never tried createViewNavFromCategory as well, but I did once come across an issue, where using a document collection (and thus documents) was way, way faster, than reading column values from view entries. Not sure if this was specific to 6.5.4, but it turned out, that after getting a view entry collection using getAllEntriesByKey, navigating to the next ve took like half a second(!). The view in question had multiple categories AND single documents appearing in many of them. Switching to getAllDocumentsByKey and looping through all documents (and I think I used doc.ColumnValues then) did speed up the whole code by a factor of 15 to 20.

A special case for sure and probably a view more appropriate to the task might have fixed it. But I was only working on small parts of the application. The bottom line is, that code might be extremely inefficient in total, even if a very efficient method like ve.ColumnValues is used. :-)

3) Alternative approach?
Kerr | 10/12/2007 6:32:11 AM

Doesn't the previous change order have all the data you need for the new one? From the description it sounds like it does. If so then you just need to get the previous change order for a given contract and extract the info, no looping round all change orders required.

4) A doc in multiple categories
Erik Brooks | 10/18/2007 3:58:24 PM

Anybody reading this needs to understand that NotesViewEntry.ColumnValues() can be *orders of magnitude* faster than document-level access. The more fields you need to access from that one doc, the more time ColumnValues() will save you.

Using a category row to calculate totals can also be a huge time-saver, as totals for that row will be calculated at view-index time, which is some hard-coded assembly goodness. If instead you're using script to iterate through each doc and total your numbers one-by-one, you're toast.

Of course, you are limited to the capabilities of Notes column totalling at that point. Total, averages, and... that's about it.

If you could somehow flag a view column's totalling to be "Min", "Max", "StdDev", etc. (or better yet - let us define our own via @Formulas or some C API hooks) then it would open Notes up to a much larger audience of market research / data-mining companies as a viable database platform.

Be careful though -- you must take extra-special care when using NotesViewNavigator with docs that reside in multiple categories. There are many inconveniences and bugs in such a case, the biggest being that by looking at just ColumnValues() you don't know *which* category corresponds to the entry you have.

E.g. if a doc is in "Apple" and "Blueberry" categories, then ColumnValues will always return an array of "Apple":"Blueberry", regardless of which row you're actually looking at.

Also make sure that you run an @Sort() in your column formula as well, otherwise ColumnValues may return "Blueberry" : "Apple" even though it shows "Apple" first in the UI because of column sorting.

 Add a Comment
Comment:  (No HTML - Links will be converted if prefixed http://)
Remember Me?     Cancel

Search this blog 


    About IBM Privacy Contact