Recently we have been improving an internal dashboard app and were in need for some simple text search solution.Something more robust than sql queries and something easier than diving to a proper lucene based approach.The models have been recently migrated to Mongodb(for other reasons), so the mongo text search seemed pretty sweet.

While doing this the information found was a bit scarce or outdated, so here is a small writeup on how to do it in rails using mongoid.
Notice: the example below is purposefully kept simple, showing only the things that matter.

Versions used:

  • Mongodb 2.6.x (the $text operator is new in 2.6)
  • Ruby 2.2
  • Rails 4.2.x
  • Mongoid 5.0.0.beta
  • Extra: bson_ext gem for faster serialization

I wanted to search for for some profile info, so the model looks like this :

class MyModel
  include Mongoid::Document
  field :profile_info, type: String
  
  index({ profile_info: "text" })
  
  def self.search(q)
    MyModel.where({ :$text => { :$search => q, :$language => "none" } })
  end
end

Notice here i used $language => “none”, that’s because i am searching for greek text and there is no support for greek, so “none” just uses simple tokenization.Check available languages here and the $text operator docs here.

Then run the rake task to create our indexes :

rake db:mongoid:create_indexes

Now our controller :

class MyController < ApplicationController
 def search
   MyModel.search(params[:search])
 end
end

And finally a simple rails search form for our view :

<%= form_tag('/search', :method => "get", id: "search-form") do %>
  <%= text_field_tag :search, params[:search], placeholder: "Search", :type => "search" %>
<% end %>

That’s it!

So far it fits its purpose just fine in a low-traffic, internal context and was implemented pretty easily.
Before going deeper you should give it a try!