Runtime Revolution
 
Articles Other News

Make Money and Friends: Google Style Searches and Text Records

by Jerry Daniels

 

Requirements

A couple of years ago, I received a new client who had very specific needs for a small business application he wanted built. This new application would be replacing an older one that he had been selling and supporting for 17 years. His two main requirements were: he had to be able to support the new application, and it had to have an excellent global search capability not unlike the type that Google uses. The new application also had to match all the features found in the older app.

This first requirement  (supportability) took SQL-style databases out of the running, since the client did not want to support a database application, but preferred a file-based system running under the control of his application (given that a Revolution card-based system would be difficult to run over a network). Another part of his reasoning for this custom, file-based data solution was requirement #2: global search. My client had been told repeatedly that global, free-form searches were not ideal for SQL databases. Our firm proceeded to design a file-based system.

Design

Operating System folders (directories) were used to group records. All contact records were placed in the "contacts" folder; all inventory records in the "inventory" folder. Each text record had a unique ID number found in its file name.

Record folder structure shown in Pathfinder

Each record in the system was a text file filled with URL-encoded data that was "tagged" with the name of the field or button in which it would be displayed. The prefix and the suffix of the name would indicate the type of control, and the type of data, respectively.  URL encoding would ensure that returns and characters used in tags would not conflict with tagging--just as they behave with HTML and XML.

Partial display of a text-based contact record file

Repeat loops could now easily walk down the controls on a card, determine if they had data and display it appropriately. Routines that saved data within the new application would also rely on these "tags" surrounding each data element.  Fields within a displayed record would be made editable and non-editable based on the "_edit" or "_disp" suffix.  A handy function called "getTagData" would do the heavy lifting by extracting the URL-encoded data elements quickly.

Code for the "getTagData" function shown here in Galaxy Scripts

Lists of Records

List of Contact Records

Business system developers all know that records need to be listed in order to be useful. The user looks at a list, double-clicks a line item and views the record. These much-needed lists would be the by-product of indexing each record as it is added, deleted or modified--or bulk imported from the legacy system. "Meta data" found at the top of each record would be used to build indices that could be searched easily.

The indices also became the basis for displaying search results or a sub group of records like "mailing list" and "mailing list 2." In viewing the list shown above and the record-level meta data upon which it is based, it becomes obvious that several  columns of data are not being shown in the list itself.

Meta data found at the "top" of each record

The Search Begins

The client identified for us which fields (for each record type) his customers wanted to include in the global search process. We then designed and implemented a system that would include this data as part of the meta data for each record and ultimately, each line of each index that would then be searched and displayed as a list.

The Query Field

Our search algorithm was based on the concept that, "Asking a good question yields a good answer." Formatting the text that the user types in the query field would ultimately determine our success. It had to be used in a filter command, so that searches would be extremely fast.

To filter the index, we wrote a filter string that would utilize only the data between the triple pipes and containing words that began with each word in the user-entered search string. "dan*" would match up with "daniel"; "adel" would match "adel", of course. With a well-formatted filter string, filter can find matching records in a list of 6,000 in less than 100 milliseconds on an old Mac G4 with a PowerPC chip set.

User Interface and Workflow

Since my client's soon-to-be legacy software was built for the early Mac, he wanted his new application to look like a new OS X style application which would also run under the Windows operating system.

A Contact Record with Navigation Tree showing

But, good looks alone will not be widely adopted by users who are accustomed to 17 years of another user interface. Fast searches, quickly thumbing through records -- one after another, as well as a handy navigation tree -- all helped with user adoption issues in this development project.

 
©2005 Runtime Revolution Ltd, 15-19 York Place, Edinburgh, Scotland, UK, EH1 3EB.
Questions? Email info@runrev.com for answers.