Adding free-form search with the built-in capabilities of Postgres.

I Do Imaging has always had the ability to search by features of programs: what platform they run on, what images they can read, what function they perform. I’ve just added searching the full text of program names, summaries and descriptions.

Feature, or category, search will always be the primary search mechanism on the site. Medical imaging software is a pretty complex field and most people have a specific need when they come to the site: I want to view a image of type X, I want to convert an image of type X on platform Y.

Accordingly, the programs are classified using 13 categories (platform, user interface, network functions etc) which can be searched in any combination. It’s difficult to choose categories that cover every function of the programs without being too broad or too narrow. Is volume rendering a feature in its own right, or an attribute of image display? Is segmentation part of image processing, or something different? And with the growth of browser-based software, along with virtual machines and containers, there are still more questions. Is a browser a platform or a user interface? What’s the platform of a JavaScript program that is deployed from a server but runs in your browser? What’s the platform of a linux container? So we make best efforts, and occasionally add categories and features as the need arises.

Sometimes, though, it’s helpful to do a broader search. You might want to search for the word ‘brain’ despite (or not knowing) that there’s a category called ‘neuro’ that would match many programs that do brain imaging. So I added full text search of program titles, summaries, and descriptions.

I’m always a bit wary of full-text search as being less ‘precise’ than searching by category. If you type the name of an imaging file format, especially ‘dicom’, into the full-text search you’ll get hundreds of responses, and they won’t be well-ranked, because not every DICOM-capable program has the word ‘DICOM’ prominently in its description. But for free-form queries it’s still useful to have.

Implementing full-text search was quite easy. It’s a feature of Postgres, and there’s a Ruby Gem that makes it available to Rails. It’s just a matter of adding a few lines to the class you wish to search; in this case, Program. The three fields to be searched are given weights so that a term appearing in the title ranks higher than if it were in the summary (longer) or description (longer still) of the program.

include PgSearch
pg_search_scope :search_for,
  against: {name: 'A', summary: 'B', description: 'C'}

The gem and Postgres create an index and maintain it. The gem creates a scope on the class that you can query much like any other scope:

> Program.search_for('conversion').count
=> 17
> Program.search_for('conversion').first
=> #<Program id: 286, name: "XMedCon", summary: "Excellent medical image conversion utility", ...

To guide users who’d searched for a file format name, or program function, I added a bit of code to catch searches for any of the file formats or functions. The programs are still listed, but the page header suggests searching by the file format, and has a link to the appropriate search.