Skip to content

Sources Configuration

floere edited this page Aug 16, 2011 · 32 revisions

Sources

Sources tell an index where to get its data.

Example
Possible Sources
  Each
  Database
  CSV
  Delicious
Experimental

Example

The method Index::Memory(identifier_symbol, options = {}) lets you define it in a block. (Index::Redis is also possible as an index)

class PickySearch < Application

  books_index = Index::Memory.new :books do
    source   Sources::CSV.new(:title, :author, :isbn, :year, :publisher, :subjects, :file => 'app/library.csv')
    category :title, # ...
  end

  # or

  books_index = Index::Memory.new :books, source: Sources::CSV.new(:title, :author, :isbn, :year, :publisher, :subjects, :file => 'app/library.csv') do
    category :title, # ...
  end

end

The source defines where this index is getting its data from.

Possible sources

Any object supporting #each

Picky supports any source as long as it supports #each. The objects returned by each must have each an #id method, and also methods called like the categories (or their :from option).

So if there are categories :isbn and :tiiiiiiitle (with :from => :title), then the objects returned by the #each method need a #id, a #isbn, and a #title method.

array_of_objects_with_id_and_isbn_and_title = [...]
index = Index::Memory.new :name do
  source   array_of_objects_with_methods_id_isbn_title
  category :isbn
  category :tiiiiiitle, :from => :title
end

Note that the :from option enables you to have multiple categories with the same data in it (but perhaps one uses the :similarity option, the other the :partial option etc.)

A cooler example is this:

Suppose you have a Book object, class Book < ActiveRecord::Base; end, then you could pass it in like this:

class Book < ActiveRecord::Base; end
index = Index::Memory.new :name do
  source   Book.order('isbn ASC')
  category :isbn
  category :tiiiiiitle, :from => :title
end

Picky will then traverse the books using #each and call the #id, #isbn, and #title methods on the returned objects.

The only problem is that ranged_category is not yet possible with #each sources.

Database

Sources::DB.new('SELECT id, title, author, isbn13 as isbn FROM books', :file => 'app/db.yml')
Sources::DB.new('SELECT id, title, author, isbn13 as isbn FROM books', active_records_configuration_options_hash)

You can use join statements etc. (The :file option points to a yml with an active record config hash)
Then, reference your columns by their names in the catgories:

index = Index::Memory.new :name do
  source   Sources::DB.new('SELECT id, title, author, isbn13 as isbn FROM books', :file => 'app/db.yml')
  category :isbn
  category :title
end

CSV

Sources::CSV.new(:title, :author, :isbn, :year, :publisher, :subjects, :file => 'app/library.csv')

The first column in the CSV needs to be the id. The others are assumed to be in the order you provide.

Options

  • file: Relative file path of the data csv file.

Ruby 1.9 options like col_sep, row_sep etc. are all available (see http://ruby-doc.org/ruby-1.9/classes/CSV.html for details).

Delicious

Sources::Delicious.new('username', 'password')

Delicious then provides a selection of categories: title, tags, url.

Experimental

If needed you can provide each category with its own source.

index = Index::Memory.new :name do
  category :isbn,  source: Sources::CSV.new(:isbn, :file => 'app/isbn.csv')
  category :title, source: Sources::Delicious.new('username', 'password')
end

But normally you won’t need this. Don’t hesitate to ask for help if you don’t see any other possibility than using this.