×

Fast CakePHP Search With IndexTank

indextank

Published: February 16, 2011

Update April 08, 2012: IndexTank is shutting down. Use IndexDen instead. Instructions here.

I've previously posted my ghetto CakePHP search function. This time I'm going to show you a much better method, mainly by offloading the work to people who really know how to do search. That's where IndexTank comes in - they know how to do search. They power the search for Reddit, WordPress.com, and many others.

You simply hand them the documents you want indexed and the give you back the ability to query against it.

I'm not going to spend anytime explaining how IndexTank works, mainly because I barely understand it. Instead I will show you a simple way to get it to work with CakePHP.

The code in this example is built around the code for Homkora in which the main two Objects are Projects and Timers. So to start grab the IndexTank library from https://indextank.com/documentation/php-client this would be a good page to read as well just to get an idea of what's going on.

Take the file you downloaded (indextank_client.php in my case) and place it in app/vendors of your CakePHP application.

Now open up your app_controller.php and add these four functions

These are the three functions that call to IndexTank directly and the one that creates the IndexTank client object. It imports the library and create a new $client object.

Each one is built to be passed the variables it needs to make a connection to IndexTank.

All the functions accept the $indexType variable which is where you set which index to perform actions against. In my case I have one for Projects and one for Timers.

So now lets add some documents to our index.

I'm going to assume you having something similar in your controller. In this case it's in my add() function in the projects controller.

Let's add the code to call our addIndextank() function in the app controller.

Let go over what's going on here.

This line is setting the data that will be indexed. The 'text' field is one used by IndexTank by default and I recommend setting it to the type of query that will be preformed the most.

The key value pairs after 'text' can be whatever other data you would like to save and be able to query against.

Simply sets the ID that is going to be used for the document ID in IndexTank. I figured it best to keep them the same as in the application database so this sets it as the last saved Project ID.

This line is the call to the addIndextank function. The "HomkoraProjects" is what is passed as $indexType in the app_controller and is basically the name of the index. We then pass the ID and the data to be indexed too.

Now when you add a new Project you should also be adding a new document to IndexTank.

Now if you delete the Project it's best to delete to document in the index as well. So let's add some code to our projects controller delete() function.

Starting with

We can add a simple call like

Deleting documents requires a lot less information so we just have to pass it the $indexType and the ID (which should match between your app and IndexTank if you add documents using the above example)

Alright, now you can add and remove documents from your index, but what good are they without being able to search against them.

In my projects controller I added the following function

I pass the search term through a form and set it as the $query variable.

Here I call our searchIndextank() function and pass it the $indexType again and the query to perform.

You'll notice in the searchIndextank() I return the data $res and in the search() function I set it to $res.

Once I get the results from IndexTank I can use them to search for the Projects in my database. Here I set them all the the $projects array and prepare them for display in the view.

I know you're thinking, if you are getting the data from the database anyway - why use IndexTank?

Well with only a few records, you aren't going to get a much faster result, but with lots of records, IndexTank will return the results faster plus it allows you to cut down on your database calls. Their ability to rank results and search based on numerous factors is pretty good and better than what the average person can write in most cases.

I'm using a pretty bare bones searchIndextank() function but this should get you started. I'm quite impressed with the results so far and I'm continuing to find better ways to work with their index.

If you know a better way to set this up, or have questions, let me know in the comments.