Searchlogic 1.3.0 – Adding modifiers into the mix

Searchlogic 1.3.0 was released today and has some pretty cool features, mainly modifiers. I’m going to assume you know what Searchlogic is. If you don’t, you’re missing out. Take a quick glance at the readme on github, otherwise this article probably won’t make a whole lot of sense.

Why modifiers are necessary?

ActiveRecord does a great job when it comes to keeping your code database agnostic. But I feel like it neglected searching when it came to that goal. What if you want to find all records that were created after 7am? Depending on your database you would have to do something like the following:

MySQL:        HOUR(created_at)
PostgreSQL:   date_part('hour', created_at)
SQLite:       strftime('%H', created_at)

All of a sudden your app is not database agnostic. Oh no!

All of that bragging to your girlfriend about how you can switch databases in a matter of minutes was all a lie. How’s she going to feel when she finds out HOUR(created_at) is a MySQL specific function? Searchlogic to the rescue!

Searchlogic modifiers

Remember how you can do this in searchlogic?

User.all(:condition => {:created_at_gt => Time.parse("Jan 1, 2008")})
# => "created_at > 2008-01-01 00:00:00

Now you can do this too:

User.all(:conditions => {:hour_of_created_at_gt => 10})
# => HOUR(created_at) > 10

or this:

User.all(:conditions => {:tan_of_sin_of_cos_of_minute_of_created_at_gt => 20})
# => TAN(SIN(COS(MINUTE(created_at)))) > 20

What the hell was that? That was me making the point that you can chain modifiers. Obviously a very unrealistic example, but cool none-the-less.

Check out the readme for a list of modifiers and check out the changelog for a complete list of changes

What do you think?

  • Share/Save/Bookmark


10 Responses to “Searchlogic 1.3.0 – Adding modifiers into the mix”

  1. Oleg says:

    I think it’s pretty awesome.

  2. pete says:

    I think you have too much time on your hands.

    Good work! You’re releasing faster than I can include your releases in my projects!

  3. Brian says:

    Consider my face melted!

  4. faust45 says:

    What about
    find(:order_by => :coalesce_short_title) =>
    SELECT *
    FROM Table
    ORDER BY COALESCE(short, title)

  5. rob says:

    What version of rails is required, 1.6, 2.0 2.1?

  6. Ben Johnson says:

    Rails really isn’t technically required, just ActiveRecord and ActiveSupport. But I am fairly certain you could use this with 1.6 as it doesn’t using anything internal really.

    Also, I will look into coalesce. When I built in the modifiers I just scanned through a list of common MySQL functions. 90% of my modifiers probably will never be used, they were so easy to add though, so why not. Plus I could add a million and it wouldn’t effect performance.

  7. faust45 says:

    I don’t found way to add modifiers in ORDER BY statement.

  8. Ben Johnson says:

    As of now modifiers are not supported in the order by function. This is something that will be supported in the next version. I will more than likely have to rework that function, as initially it was just a simple function.

  9. mathieu says:

    Great work Ben,

    Have you some guidelines to add oracle support for modifiers.

    Tried to put :

    <code>
    module Searchgasm
    module ActiveRecord
    module ConnectionAdapters
    module SQLiteAdapter
    # String functions
    def upper_sql(column_name)
    "upper(#{column_name})"
    end
    end
    end
    end
    end

    ::ActiveRecord::ConnectionAdapters::OracleAdapter.send(:include, Searchgasm::ActiveRecord::ConnectionAdapters::OracleAdapter)
    </code>

    into
    \vendor\plugins\searchgasm-1.4.2\lib\searchgasm\active_record\connection_adapters\oracle_adapter.rb

    nothing altered in the query.

    Gretz

  10. mathieu says:

    Ben drop my previous comment.. code is wrong…

    Great work Ben.

    I’m trying to add Oracle support with modifiers

    Created :

    \vendor\plugins\searchgasm-1.4.2\lib\searchgasm\active_record\connection_adapters\oracle_adapter.rb

    with :

    module Searchgasm
    module ActiveRecord
    module ConnectionAdapters
    module OracleAdapter
    # String functions
    def upper_sql(column_name)
    "upper(#{column_name})"
    end
    end
    end
    end
    end

    ::ActiveRecord::ConnectionAdapters::OracleAdapter.send(:include, Searchgasm::ActiveRecord::ConnectionAdapters::OracleAdapter)

    "search"=>{"conditions"=>"upper_of_libelle_marche_contains"=>"mi",….}

    SQL : … AND (marche_supreme.libelle_marche LIKE ‘%mi%’)

    Not really that!

    Thanks