Giter VIP home page Giter VIP logo

pose's Introduction

POlymorphic SEarch Build status Code Climate Coverage Status Dependency Status

A database agnostic fulltext search engine for ActiveRecord objects in Ruby on Rails.

  • Searches over several classes at once.
  • The searchable content of each class and document can be freely customized.
  • Uses the main Rails database - no separate servers, databases, or search engines required.
  • Does not pollute the searchable classes or their database tables.
  • Very fast search, doing only simple queries over fully indexed columns.
  • Allows to augment the fulltext search query with your own joins and where clauses.

Installation

Set up the gem.

Add the gem to your Gemfile and run bundle install

gem 'pose'

Create the database tables for pose.

$ rails generate pose:install
$ rake db:migrate

Pose creates two tables in your database. These tables are automatically populated and kept up to date.

  • pose_words: index of all the words that occur in the searchable content.
  • pose_assignments: lists which word occurs in which document.

Make your ActiveRecord models searchable

class MyClass < ActiveRecord::Base

  # This line makes your class searchable.
  # The given block must return the searchable content as a string.
  posify do

    # Only active instances should show up in search results.
    return nil unless status == :active

    # The searchable content.
    [ self.foo,
      self.parent.bar,
      self.children.map &:name ].join ' '
  end
end

Note that you can return whatever content you want in the posify block, not only data from this object, but also data from related objects, class names, etc.

Now that this class is posified, any create, update, or delete operation on any instance of this class will update the search index automatically.

Index existing records in your database

Data that existed in your database before adding Pose isn't automatically included in the search index. You have to index those records manually once. Future updates will happen automatically.

To index all entries of MyClass, run rake pose:reindex_all[MyClass] on the command line.

At this point, you are all set up. Let's perform a search!

Upgrading from version 1.x

Version 2 is a proper Rails engine, and comes with a slightly different database table schema. Upgrading is as simple as

$ rails generate pose:upgrade
$ rake db:migrate

Searching

To search, simply call Pose's search method, and tell it the search query as well as in which classes it should search.

result = Pose.search 'foo', [MyClass, MyOtherClass]

This searches for all instances of MyClass and MyOtherClass that contain the word 'foo'. The method returns a hash that looks like this:

{
  MyClass => [ <myclass instance 1>, <myclass instance 2> ],
  MyOtherClass => [ ],
}

In this example, it found two results of type MyClass and no results of type MyOtherClass. A Pose search returns the object instances that match the query. This behavior, as well as many others, is configurable through search options.

Search options

Configure the searched classes

Pose accepts an array of classes to search over. When searching a single class, it can be provided directly, i.e. not as an array.

result = Pose.search 'foo', MyClass

Configure the result data

By default, search results are the instances of the objects matching the search query. If you want to just get the ids of the search results, and not the full instances, use the parameter :result_type.

result = Pose.search 'foo', MyClass, result_type: :ids   # Returns ids instead of object instances.

Limit the amount of search results

By default, Pose returns all matching items. Large result sets can become very slow and resource intensive to process. To limit the result set, use the :limit search parameter.

result = Pose.search 'foo', MyClass, limit: 20    # Returns only 20 search results.

Combine fulltext search with structured data search

You can add your own ActiveRecord query clauses to a fulltext search operation. For example, given a class Note that belongs to a User class and has a boolean attribute public, finding all public notes from other users containing "foo" is as easy as:

result = Pose.search 'foo', MyClass, where: [ public: true, ['user_id <> ?', @current_user.id] ]

Maintenance

Besides an accasional search index cleanup, Pose is relatively maintenance free. The search index is automatically updated when objects are created, updated, or deleted.

Optimizing the search index

For performance reasons, the search index keeps all the words that were ever used around, in order to try to reuse them as much as possible. After deleting or changing a large number of objects, you can shrink the memory consumption of Pose's search index by removing no longer used search terms from it.

$ rake pose:index:vacuum

Recreating the search index from scratch

To index existing data in your database, or after loading additional data outside of ActiveRecord into your database, you should recreate the search index from scratch.

rake pose:index:reindex_all[MyClass]

Uninstalling

To remove all traces of Pose from your database, run:

rails generate pose:remove

Also don't forget to remove the posify block from your models as well as the gem entry from your Gemfile.

Use Pose in your tests

Pose can slow down your tests, because it updates the search index on every :create, :update, and :delete operation in the database. If this becomes a problem, you can disable Pose in your test environments, and only enable it for the tests that actually need search functionality.

To disable Pose for tests, add this line to config/environments/test.rb

Pose::CONFIGURATION[:perform_search] = false

Now, with search disabled in the test environment, enable Pose in some of your tests by setting the same value to true inside the tests:

context 'with search enabled' do

  before :all do
    Pose::CONFIGURATION[:perform_search] = true
  end

  after :all do
    Pose::CONFIGURATION[:perform_search] = false
  end

  it 'has search enabled in this test here...'

  it 'has search enabled in this test as well...'
end

Development

If you find a bug, have a question, or a better idea, please open an issue on the Pose issue tracker. Or, clone the repository, make your changes, and submit a pull request.

Run the unit tests for the Pose Gem

For now, Pose uses Postgresql for tests, since it is free, and one of the most strict databases. To run tests, first create a test database.

createdb pose_test

Then run the tests.

$ rake spec

Road Map

  • add join to search parameters
  • pagination of search results
  • ordering
  • weighting search results
  • test Pose with more types of data stores (NoSQL, Google DataStore etc)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.