One of the benefits of XPages is the power of repeat controls to effectively perform ‘joins’, whether that is with nested repeat controls or merging data prior to displaying in a repeat control. When it comes to collections of documents I tend to favour NotesViewEntryCollections. This is both for performance (predominantly using getColumnValues().get) as well as sort order (NotesDocumentCollections are sorted on document creation order).

Recently I had the need to extend an existing repeat control to use entries already available in another view. My approach was to use the NotesViewEntryCollection created using getAllEntriesByKey() and then add entries from the second view. I didn’t expect it to insert the entries so sorting order was maintained, but I expected to be able to reuse an existing repeat control, because both views had the same columns.

Unfortunately, with a bit of logging I found that although entries were found, the NotesViewEntryCollection count did not increase. After checking with the community, I confirmed that a NotesViewEntryCollection can only contain entries from a single view. It is a NotesViewEntryCollection rather than a NotesViewEntryCollection. Historically, this is understandable, but it did take a bit of work to confirm.

The options then are twofold.

Firstly, amend one of the views, as I did in this case. This is fine if the data being retrieved is from a single database, but not feasible if merging data from different databases.

The second is to use a java.util.TreeMap, passing in the entries from the collection and, if necessary, creating non-Notes objects containing the primitive column values. That is, not storing them as NotesViewEntry objects, to avoid NullPointerExceptions if the NotesViewEntry objects get recycled. A java.util.TreeMap is effectively like a LotusScript List, with the advantage being that it is automatically sorted in the key, which can be any data type (in LotusScript, the key is converted to text, so “0” and 0 are the same). For the TreeMap, the key would be the value you wish to sort on, extended as required to make it unique. Of course, extracting the NotesViewEntries and their properties into a TreeMap takes more code, therefore having a performance hit. So it is only going to be a realistic option if you are processing a small number of entries at a time.

2 thoughts on “NotesViewEntryCollections”

  1. Option number three would be dynamic merging of x collections, e.g. compare the next entry of each collection and pick the smallest one (based on a comparison by column value), then read the next entry from the same collection and pick the next entry. That approach consumes less memory than storing everything in a giant TreeMap.

    I created a MergeIterator Java class for this purpose. Works quite well for us, e.g. on the server side of a Dojo LazyTreeGrid, returning content for merged categorized views one level at a time.

    The downside is that you loose the option to quickly get the n-th element of the merged collection. That means you have to redo the whole merging until element n if you just want to read a small page of the data (start=n, count=m).

    With a standard NotesViewEntryCollection, Notes does the same thing internally with a single view index (because there might be documents in the view that are hidden to the active user and need to be skipped), but it’s done in C code and much faster.

  2. Another advantage of the 2nd approach is that the results can be cached in one of the scopes and can easily be resorted by any value (column) without the need of extra view indexes.

    Combined with a FT search I’m using it to offer all kinds of lists, but am still investigating the fastest way to extract the values from a view entry (or a document).

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.