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 (in reference to using db.Search vs. finding documents in a view):
> when I need to build a collection of documents, I usually just build a view and sort it by some key, then use notesView.GetAllDocumentsByKey(key).  Is this inefficient?  I can't think of a time I've used  I suppose adding another view increases the size of the db, and gives it another view to index, which can cause a performance hit, but I haven't run into a situation yet where this has really slowed things down noticeably

If you can use a view, I think it's generally the best-performing choice. But you can't always use a view, and performance is not always the paramount consideration.

As we saw in the timing tests I did, accessing documents through a view is very fast compared to other methods, if the pool of candidate documents is all the documents. Adding a view does make your nsf larger and slows the application generally -- or so I've been told; I've never tried to measure by how much (anyone have stats?). But if you can use a view that you needed anyway for a different reason, this is not a factor.

But there are times that a view doesn't work as well as other methods:

  • Unless you use a date-based selection formula, the stored view index contains all the documents in the database that match your selection formula (and if you do use a date-based selection, the index must be rebuilt with each use, so it's slow). A view's not as useful if you want to limit to documents touched since a certain date -- a common situation in scheduled agents.
  • The view selection criteria are static, whereas you can use code to construct a db.Search with any formula you like, determined at runtime. You can change the view selection formula at runtime with LotusScript code (assuming the agent's signer has Designer access) but this is not a good way to do a search. You lose the performance advantage of views, because all the documents have to be reviewed for reindexing. Because the view indexer uses the summary instead of the entire document, it might be faster than the same formula in db.Search, but the view indexer has to do the extra work of sorting the documents and writing the new index to disk ($$$), so overall you might not get any performance boost by setting view.SelectionFormula vs. using db.Search -- and the code is more complex.
  • It's hard to use a view to find documents in a range, or where a field "contains" a string, or where field != value, or any other criteria which are not field value.
As a side note, the new NotesDocumentCollection methods I just wrote about, are nice because they expand the number of cases where a view search is useful in finding documents. Because before, you could only easily do an "and" condition, and now it's fairly simple to do an "or" or "and not", or to do an "and" that doesn't require a single view sorted by both keys. For instance, suppose you have a view sorted by Expertise and then by Country, and you want to find people skilled in "Swimming" who live in "Grand Fenwick". In current versions, you could do something like:

Dim key(0 to 1) As String
key(0) = "Swimming"
key(1) = "Grand Fenwick"
Set collResult = view.GetAllDocumentsByKey(key, True)

(Note: be careful with GetAllDocumentsByKey, because the default matching is not exact, so you might update the documents for "Marshmallow" when you only meant to update "Marsh")

However, this requires a view that's sorted by both keys, which makes it harder to double-up the view with some other use. Whereas in version 8.0, you can use two views, one sorted by Expertise and one sorted by Country (which you probably needed these views anyway), find the matching documents in each view, and then Intersect them:

Set collA = viewByCountry.GetAllDocumentsByKey("Grand Fenwick", True)
Set collB = viewByExpertise.GetAllDocumentsByKey("Swimming", True)
Call collA.Intersect(collB)
' limit to docs where (A and B) is true.

It's less efficient, but needing fewer views is also worth something. And if you wanted to find all the people in Grand Fenwick who do not swim (because you're expecting a flood and need to enroll the non-swimmers in swim training), just use Subtract instead of Intersect. Or for the equivalent of "or", use Merge.

Doing the search this way is possible in pre-8.0 -- it's not that hard to write your own Subtract or Intersect functions -- but it's faster and simpler with the built-in methods; it saves your time and gives better performance (because the looping happens in the fast C++ code).

Complexity and code readability is also very important. While view searches might be the best-performing, you don't always get the easiest-to-understand code, especially when you use set operations on collections. By comparison, the following is simple and not much slower:

Set collResult = db.FtSearch( {([Country] = "} & Country & {") and not ([Expertise] = "} & Skill & {")}, 0) ' I'm assuming there are no quotes in the data.

Besides the code itself being less complex, you can see exactly what this does without having to switch screens to look at the design of a view. It's all right there in front of you. Compare the amount of time it takes to write this statement with the time it takes to create the view you need for a view-based search -- and the time you later have to spend figuring out what went wrong and re-creating the view after some other developer (or you yourself, after some time has passed) deleted the view, thinking it was unused.

Remember, your time is valuable -- the less you have to spend writing and maintaining code, the more slack you have to read my blog and do crossword puzzles. Only worry about performance when it really makes a difference -- CPU cycles are cheap.

Andre Guirard | 27 April 2007 01:01:00 AM ET | Plymouth, MN, USA | Comments (11)

Search this blog 


    About IBM Privacy Contact