Java: Test if a Document Exists in a Notes View

I'm writing some Java code in a Notes Agent that processes every single document in a database, apart from those that may exist in certain views.

To test if the document is in a view or not I used this simple function:

private boolean isDocumentInView(lotus.domino.View view, Document doc) 
throws Exception{ if (view==null) return false; //Evaluate returns either a double of 0.0 or 1.0 for this! Dunno why? Vector test = session.evaluate(view.getSelectionFormula(), doc); Double result = (Double)test.firstElement(); return result.equals(1d); }

I seem to remember discussing this before publically, but can't find any reference to it, so I'm blogging now in the hope somebody finds it useful (or in case I need it again at some point -- as the fact evaluate returns a Double has caught me out more than once now).


Jesse Gallagher made a suggestion and did a little investigation to validate that the following method is much more efficient (see comments for more details):

private boolean isDocumentInView(lotus.domino.ViewNavigator nav, Document doc) 
throws Exception{ if (nav==null) return false; return nav.gotoEntry(doc); }

Thanks Jesse! I've updated my code to use this approach instead now.

Obviously you'd define and set the ViewNavigator once at the beginning of the code. You could always simply pass the name of the view as a String to the function and let it get view each time, but that would be plain crazy!


  1. Hi Jake,

    in formula language there is no "boolean" data type (nor "integer" or "real" etc.). There just is "number" and "string".

    And @True is a number (1), @False is 0.

    As you are evaluating in java, which has strong typing, you will get the number data type which should be able to hold the returned value - which is the double data type.

    To avoid this kind of trouble I tend to use formulas which return strings, e. g. by wrapping the formula into an

    @if (....; "1"; "0");

    Not pretty, but more reliable. I also like to wrap the formula with an @If (@IsError(...); ...), so that I can check the results - instead of the exception handling.

    @Formulas throwing errors are bad, not only in forms - you never know what is going on without catching the errors in every single formula...

    By the way:

    Your formula probably might not work for views with response hierarchies, e. g. selection formulas containing @Responses or @Descendants. But I haven't tested this.


    1. Hi Hans-Peter,

      I bow down to your superior wisdom! Now you've explained it it makes sense. Without the explanation I'd expected the more obvious result of it returning either a 1 or 0 | "1" or "0" | "True" or "False" .

      Thanks for the explanation. I continue to learn.

  2. What could be a use case for this?

    1. It's hard to say what my exact use case was without breaking confidentiality agreements, but this is the 2nd time I've used the same approach. It is useful. Enough for me to think it worthy or posting here.

      Based on the principle that the selection formula for some views is representative of the business logic for a database, it shouldn't be too hard to think of a case where you need to check whether a document is in a view or not.

      Show the rest of this thread

  3. Oh, I like this method. Now it has me thinking about other ways to do it as well... namely, I wonder how the performance would compare to creating a ViewNavigator and calling .gotoEntry(doc). That's always seemed like a bizarre method to me, but I think I found it to be surprisingly fast when I tried it a while back.

    I also kind of wonder how it would work in oddball scenarios like a document qualifying for the selection formula but not visually showing up in the view because its parent isn't there.

    1. Oooh, hadn't thought of that approach. Surely it would be slower to find the document in a ViewNavigator though!? Or would it depend on the complexity of the Selection Formula. If the formula were simply SELECT Form="Foo" then evaluate may win? If the formula were dozens of lines of code, perhaps not?

      I'll leave it with you if you want to look in to it any further ;)

      Hide the rest of this thread

      1. My curiosity piqued, I did indeed run some tests. I wrote an agent in our project-tracking database (95k documents) to test all documents against a view in four ways:

        1. The method you have above

        2. The method you have above changed to only fetch the selection formula once and then pass that in instead of the view

        3. A method that creates a view navigator from the view and uses .gotoEntry(doc) on that

        4. A method that takes an already-created navigator instead of the view

        Somewhat freakishly, the average run times of three attempts at each were about halved, each in order:

        1. 55-59s

        2. 30-31s

        3. 14-15s

        5. 6s

        So, at least if you're going to be running the method quite a few times, using the view navigator is much faster.

        1. Wowsers, that's some difference.

          You've convinced me to change my approach.

        2. This could change with different versions of domino,

          I know recently 852 and 853 they have made significant improvements to view navigator.

    • avatar
    • Phil
    • Thu 23 Feb 2012 08:27 AM

    Can't you just create a view that only shows the documents you require, then process that?

    To take your example above - SELECT !Form="Foo"


    1. Good point. You could, but then you've duplicated the code/logic. If the logic of the view changes you have to change it in the new view too.

      Like everything it's "horses for courses" and "more than one way to swing a cat".

  4. Another approach, which would work the same way for both views and folders is to create an empty NoteCollection object, use NoteCollection.add(doc) to put your document into the collection, and then use NoteCollection.intersect(view). If your document is still in the NoteCollection, it was in the view.

    Or to do it in bulk instead of one document at a time, first define two NoteCollection objects nc1 and nc2, with both containing all documents using the setSelectDocuments(true) and buildCollection() methods. Next call nc2.intersect(view) which gives you only the documents in the view. Finally, call nc1.remove(nc2), which gives you all the documents that were not in the view.

    If you have multiple views and/or folders to work with, you can do it in a loop. I.e., after each remove(), call nc2.clearCollection, then call nc2.add(nc1) so once again you have two identical collections (all docs minus the ones that were removed in previous iterations), and repeat the process of intersecting and removing.

    Note that I haven't tried the bulk approach, but I have a feeling it should be significantly faster because it's never actually opening documents.

Your Comments


About This Page

Written by Jake Howlett on Thu 23 Feb 2012

Share This Page

# ( ) '


The most recent comments added:

Skip to the comments or add your own.

You can subscribe to an individual RSS feed of comments on this entry.

Let's Get Social

About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »

More Content