Alex Rivera | Logout

Autocomplete server-side implementation

Asked 2009-06-09T16:10:52.500
23

What is a fast and efficient way to implement the server-side component for an autocomplete feature in an html input box?

I am writing a service to autocomplete user queries in our web interface's main search box, and the completions are displayed in an ajax-powered dropdown. The data we are running queries against is simply a large table of concepts our system knows about, which matches roughly with the set of wikipedia page titles. For this service obviously speed is of utmost importance, as responsiveness of the web page is important to the user experience.

The current implementation simply loads all concepts into memory in a sorted set, and performs a simple log(n) lookup on a user keystroke. The tailset is then used to provide additional matches beyond the closest match. The problem with this solution is that it does not scale. It currently is running up against the VM heap space limit (I've set -Xmx2g, which is about the most we can push on our 32 bit machines), and this prevents us from expanding our concept table or adding more functionality. Switching to 64-bit VMs on machines with more memory isn't an immediate option.

I've been hesitant to start working on a disk-based solution as I am concerned that disk seek time will kill performance. Are there possible solutions that will let me scale better, either entirely in memory or with some fast disk-backed implementations?

Edits:

@Gandalf: For our use case it is important the the autocompletion is comprehensive and isn't just extra help for the user. As for what we are completing, it is a list of concept-type pairs. For example, possible entries are [("Microsoft", "Software Company"), ("Jeff Atwood", "Programmer"), ("StackOverflow.com", "Website")]. We are using Lucene for the full search once a user selects an item from the autocomplete list, but I am not yet sure Lucene would work well for the autocomplete itself.

@Glen: No databases are being used here.

Edit
Report

2 Answers

2

I've done this for small data sets using a Ternary search tree. The DDJ code is not too difficult to convert to Java, but it assumes the entire data set will fit into memory. There are on-disk implementations of Ternary search trees (here is one in python), but of course they are going to be less performant. Since ternary search trees excel at partial matches, though, the performance might be suitable for your needs.

answered 2009-06-09T18:18:51.317
-1

Are there possible solutions that will let me scale better

Yes, Oracle. This is kind of thing that databases are built for. Just index the relevant columns. If you are running against the wall of in-memory solutions, then the trade-off with disk seek time or network latency is probably moot. Especially if you insert a caching layer in between.

Also, you may be able to decrease the number of hits if you tweak your client-side code a little. Such as setting a minimum number of type characters before a query is run or setting a fraction of a second of delay after the user stops typing. If you are already using those, set them a bit higher.

answered 2009-06-09T19:06:43.270

Your Answer