Monday, January 25, 2010

Small update on the Xpages search demo

The xpages search demo I posted last week is still messy, but I've cleaned it up a tiny bit.

I've added another parameter in the config for the search-method. You can now specify fieldName separately from the formula. I actually documented it, but forgot to implement it in the demo.

This should make it easier to refer to fields in the columns.
E.g.
TemplateSearch.search( [{ 
fieldName: 'name',
formula: 'LastName + ", " + FirstName',
dataType: 'string'
},{
fieldName: 'modified',
formula: '@Modified',
dataType: 'date'
}]);

If you want to have a demo of something more in regards search-results/data tables, leave a comment, and I'll take a look at it. If it's something I can do in a relatively short amount of time, I'll make/post a demoapp with a simple description.

Saturday, January 23, 2010

Comments are now open

I've got a few comments over the time of my blog that people can't comment because they don't have a google account.

I've now opened for anonymous comments, so if you want to ask me about something in regards to any of my blogposts, now's your chance.

The reason I restricted comments back in the day was because I was afraid of dealing with spam all day. Let's see how it turns out.

Wednesday, January 20, 2010

XPages: Three ways to build a search interface with "on the fly" sortable columns

While copy/paste programmers and XPages novices might get something out of this demoapp/blogpost, it's directed towards the people that want to push XPages beyond the constraints of the drag and drop interface in Domino Designer.

I detest the "need" to have a Notes view for every kind view in XPages. Recently, at work, I've been occupied mostly by creating customizable search/filtering views in XPages.

Until today, I've used a DataTable with a SSJS function as data source (returns JS-objects). The function does an FTSearch on a NotesView, and fetch precalculated JSON strings from a view column. The DataTable can be designed to use one/all fields from the json-objects. One DataTable column can have one or more values from the JSON object (e.g. dataItem.fieldName + ' ' + dataItem.fieldName2). This has the advantage of only needing a one (unsorted) column view to generate a wide array of reports.

Julian Buss seems to have been working on/pondering solutions for "on the fly" sortable searches as well. I've implemented what I think he meant in the demoapp as well. I didn't take the time to write caching algorithms for his way, using NotesViewEntryCollection. I also didn't take the time to implement descending sort. The reason I was so lazy was that I didn't like my implementation of his idea.

The last way (default choice in demoapp), and the best way I've found so far is to do FTSearch on the db. In the demoapp, I search the entire db without restricting to a form/etc. This is because I didn't find the need for restricting the search as there are only one kind of documents in the demoapp. The result from the search is a NotesDocumentCollection. The datasource is a function that accepts what I call an array of field definitions.

E.g.
var fieldDefinitons = [{
fieldName: 'someFieldName',
dataType: 'string'
},{
fieldName: 'someFormulaString',
dataType: 'date'
}]


Supported datatypes in the demoapp are string, multi-value string, date, multi-value date, number and multi-value numbers. The field definitions are parsed into a string that can be evaluated against a document (using session.evaluate). Using session.evaluate is the fastest way I know of to get multiple values out of a document. Compared to fetching precalculated JSON strings from a view, there is no discernible difference in speed when evaluating against documents in the NotesDocumentCollection.

Regarding caching, the JSON object is stored in a viewScope-variable. When the user navigates to another page, the JSON object should be recycled from what I understand of XPages/JSF. The values are only fetched from the server when the query string is changed. When the used wants to sort the view, the cached object is resorted. This results in speedy pagination/sort.

On my local computer, with 5000 items in the result-object, re-sort is done in about 100ms on the server. It probably takes 500-1000ms before the user gets what he ordered. The initial search takes 2-4 seconds (server time).

I could probably write a tiny book on the "technology"/thought/history behind this demoapp. Instead, I'll tease you with an animated gif, and let you download a demoapp (here be messy code). The demoapp is a biggie. It's a mutilated version of Jake's FakeNames application. I chose this because I wanted to test against a "big" database. This has 40k NAB Person documents.

Screenshots (animated gif):


>> Demoapp (6 MB zip)

Share and enjoy!

Wednesday, January 13, 2010

SSD - The best Lotus Notes/Eclipse can get?

As some of you might know, Notes/Domino in Eclipse contains a lot of files. I believe it was somewhere around 35 000 for Notes/Sametime/Domino Designer 8.5.1.

Random access time (the time it takes to find/access a random file) is where mechanical disks probably are at it's weakest. This is especially noticable when you want to access a lot of files "at once", like when you want to start Notes cold (not started since booting the computer).

When the first SSDs came out, the test results were lousy. After reading about ten tests the initial months after SSDs became commercial, I more or less forgot about SSDs.

Then I read this. Cold starting Lotus Notes in 4 seconds?!?!

To be certain, I nagged my boss into testing out an SSD at work. I ended up with a Corsair, which has good write and read speeds. I don't think I'm exaggerating when I say that it felt like a new computer. I'm not sure my work computer starts Notes below five seconds (Core 2 Duo/1.7GHz), but it's well below 10 seconds.

What probably made me the most happiest is that during the weekly antivirus scan, I could work as normal. With the mechanical disk, it felt like working on a computer from the 20th century.

Then I decided it was time to get an SSD for my desktop computer at home. After reading a test at tomshardware.com, I decided on a 80GB Intel X25M G2. It has decent write speed, and great read speed.

I'm happy I decided on that disk after reading this performance comparison (at the time of writing, Intel X25M G2 at the top).

When SSDs become as cheap as mechanical drives, it's going to do a lot for servers worldwide.

If you're still not convinced (10 000 RPM IDE disk vs SSD):

XPages: Developer Tool - Deep dive into the XPages API

If you work on XPages, and are going to download only one demoapp from me in your life, this is the one you should download (at least compared to my earlier apps).

On several occasions, Domino Designer falls short when it comes to developing XPages. On those occasions I try to dive into the XPages API. I used to create a computed field with the value of typeof getComponent( 'component-id' ). This gave me the class name of the object. Then I declared a variable with the type of the class. This gave me the methods available for the component type. E.g.
var field:com.ibm.xsp.component.xp.XspInputText = new com.ibm.xsp..
Today, working on inspecting an Exception object, trying to find a way to print ServerSide JavaScript stack trace (you only get the Java stack trace), I came up with an idea that will save me a lot of time in the future of XPage development. I didn't find a pay to get the JS stack trace, if you're wondering.

It started with a simple field that you put a class name into. This gave you the properties and methods of the class.

Then I added the functionality to type the name of a global object (e.g. facesContext), and it printed the properties/methods of that object.

Then, while writing/preparing this blog post, I remembered my client side getClientId/getComponent. After a little bit of copy/paste/modify, I ended up with a custom control that lets you select any control (including event handlers/etc) on the page from a combobox (just add the custom control to the XPage you're developing), and get the methods and properties of the corresponding class in the XPages API.

A couple of screen captures (animated gif):


>> Download Demoapp with custom control (28K zip)

In theory, the custom control lets you post commands to the server, so remember to modify the ACL after you download!

Share and enjoy!

It's about time you update the NotesDatabase.Search documentation, IBM!

A colleague of mine was working on NotesDocumentCollections resulting from a NotesDatabase.Search. He discovered that whatever you put into the last parameter (maxDocs), all documents were returned.

Here's the documentation on the Search method:

Syntax:

Set notesDocumentCollection = notesDatabase.Search( formula$, notesDateTime, maxDocs% )

Parameters:

formula$

String. A Notes @function formula that defines the selection criteria.

notesDateTime


A cutoff date. The method searches only documents created or modified since the cutoff date. Specify Nothing to indicate no cutoff date.

maxDocs%

Integer. The maximum number of documents you want returned. Specify 0 to receive all matching documents.


The documentation on maxDocs is wrong, and IBM has been aware of the issue since Notes 4.5.

Do Quality control much?