GithubHelp home page GithubHelp logo

tanker's Introduction

<img src=“https://secure.travis-ci.org/kidpollo/tanker.png?branch=master” />

Tanker - IndexTank integration to your favorite orm

IndexTank is a great search indexing service, this gem tries to make that any orm stays in sync with IndexTank easily. It has a simple yet powerful approach to integrate IndexTank with any ORM and also supports pagination using WillPaginate (default) or Kaminari.

Very little is needed to make it work, basically, all you need is that the orm instance respond to id, all, find and any attributes you wish to index.

Installation

gem install tanker

If you are using Rails 3 its better to add Tanker to your GEMFILE

gem 'tanker'

And run

bundle install

Initialization

If you’re using Rails, config/initializers/tanker.rb is a good place for this:

YourAppName::Application.config.index_tank_url = 'http://:[email protected]'

If you are not using rails you can put this somewhere before you load your models

Tanker.configuration = {:url => 'http://:[email protected]' }

You would probably want to have fancier configuration depending on your environment. Be sure to copy and paste the correct url provided by the IndexTank Dashboard

Pagination

WillPaginate is used by default and you don’t have to add any extra settings to use that. If you want to use Kaminari you have to add the following:

YourAppName::Application.config.index_tank_url = 'http://...'
YourAppName::Application.config.tanker_pagination_backend = :kaminari

or

Tanker.configuration = {:url => 'http://...', :pagination_backend => :kaminari }

Example

class Topic < ActiveRecord::Base
  acts_as_taggable
  has_many :authors

  # just include the Tanker module
  include Tanker

  # define a scope
  scope :awesome, :conditions => {:title => 'Awesome'}

  # define the index by supplying the index name and the fields to index
  # this is the index name you create in the Index Tank dashboard
  # you can use the same index for various models Tanker can handle
  # indexing searching on different models with a single Index Tank index
  tankit 'my_index' do

    conditions do
      indexable?
    end

    indexes :title
    indexes :content
    indexes :id
    indexes :tag_list #NOTICE this is an array of Tags! Awesome!
    indexes :category, :category => true # make attributes also be categories (facets)

    # you may also dynamically retrieve field data
    indexes :author_names do
      authors.map {|author| author.name }
    end

    # you cal also dynamically set categories
    category :content_length do
      content.length
    end

    # to pass in a list of variables with your document,
    # supply a hash with the variable integers as keys:
    variables do
      {
        0 => authors.first.id, # these will be available in your queries
        1 => id                # as doc.var[0] and doc.var[1]
      }
    end

    # You may defined some server-side functions that can be
    # referenced in your queries. They're always referenced by
    # their integer key:
    functions do
      {
        1 => '-age',
        2 => 'doc.var[0] - doc.var[1]'
      }
    end
  end

  # define the callbacks to update or delete the index
  # these methods can be called whenever or wherever
  # this varies between ORMs
  after_save :update_tank_indexes
  after_destroy :delete_tank_indexes

  # Note! Will Paginate pagination, thanks mislav!
  def self.per_page
    5
  end

  # will only index entries whose title is present
  def indexable?
    self.title.present?
  end

end

Create Topics

Topic.create(:title => 'Awesome Topic', :content => 'blah, blah', :tag_list => 'tag1, tag2')
Topic.create(:title => 'Bad Topic', :content => 'blah, blah', :tag_list => 'tag1')
Topic.create(:title => 'Cool Topic', :content => 'blah, blah', :tag_list => 'tag3, tag2')

Search Topics

@topics = Topic.search_tank('Topic', :page => 1, :per_page => 10) # Gets 3 results!
@topics = Topic.search_tank('blah',  :conditions => {:tag_list => 'tag1'}) # Gets 2 results!
@topics = Topic.search_tank('blah',  :conditions => {:title => 'Awesome', :tag_list => 'tag1'}) # Gets 1 result!

Search with scope (Only tested on ActiveRecord)

@topics = Topic.awesome.search_tank('blah') # Gets 1 result!

Search with wildcards!

@topics = Topic.search_tank('Awe*', :page => 1, :per_page => 10) # Gets 1 result!

Search multiple models

@results = Tanker.search([Topic, Post], 'blah') # Gets any Topic OR Post results that match!

Search with negative conditions

@topics = Topic.search_tank('keyword',  :conditions => {'tag_list' => 'tag1'}) # Gets 1 result!
@topics = Topic.search_tank('keyword',  :conditions => {'-id' => [5,9]}) # Ignores documents with ids of '5' or '9'

Search with query variables

@topics = Topic.search_tank('keyword',  :variables => {0 => 5.6}) # Makes 5.6 available server-side as q[0]

Paginate Results

<%= will_paginate @topics %> for WillPaginate
<%= paginate @topics %> for Kaminari

Fetching attributes and snippets

As of version 1.1 Tanker supports fetching attributes and snippets directly from the Index. If you use either of these search options your Model instances will be instanced from the attributes coming from the index not by making another trip to the database.

This can represent a major speed increase for your queries but it also means that you will only have available the attributes you indexed in your model. There are edge cases that are not tested so please help us have this feature be super stable and have everyone benefit from the speed this entails.

Example:

@very_long_sting = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
Product.create(:name => @very_long_sting, :href => 'http://google.com' )

@products = Product.search_tank('quis exercitation', :snippets => [:name], :fetch => [:href])
@products[0].name_snippet
# => 'Ut enim ad minim veniam, <b>quis</b> nostrud <b>exercitation</b> ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla'
@products[0].href
# => 'http://google.com'
@products[0].any_other_attribute
# => nil

Notice that to get the snippeted value that Index Tank sends you get it via the ‘_snippet’ method generated on the fly.

The attributes that are requested to be fetched are set as attributes as new instances of your model objects and no Database Query is executed. NEAT!

Geospatial Search Example

IndexTank and the Tanker gem support native geographic calculations. All you need is to define two document variables with your latitude and your longitude

class Restaurant < ActiveRecord::Base
  include Tanker

  tankit 'my_index' do
    indexes :name

    # You may define lat/lng at any variable number you like, as long
    # as you refer to them consistently with the same integers
    variables do
      {
        0 => lat
        1 => lng
      }
    end

    functions do
      {
        # This function is good for sorting your results. It will
        # rank relevant, close results higher and irrelevant, distant results lower
        1 => "relevance / miles(d[0], d[1], q[0], q[1])",

        # This function is useful for limiting the results that your query returns.
        # It just calculates the distance of each document in miles, which you can use
        # in your query. Notice that we're using 0 and 1 consistently as 'lat' and 'lng'
        2 => "miles(d[0], d[1], q[0], q[1])"
      }
    end
  end
end

# When searching, you need to provide a latitude and longitude in the query so that
# these variables are accessible on the server.
Restaurant.search("tasty",
                  :var0 => 47.689948,
                  :var1 => -122.363684,
                  # And we'll return all results sorted by distance
                  :function => 1)

# Or we can use just function 2 to return results in the default order, while
# limiting the total results to just those within 50 miles from our lat/lng:
Restaurant.search("tasty",
                  :var0 => 47.689948,
                  :var1 => -122.363684,
                  # the following is a fancy way of saying "return all results where
                  the result of function 2 is at least anything and less than 50"
                  :filter_functions => {2 => [['*', 50]]})
# And we can combine these two function calls to return only results within 50 miles
# and sort them by relevance / distance:
Restaurant.search("tasty",
                  :var0 => 47.689948,
                  :var1 => -122.363684,
                  :function => 1,
                  :filter_functions => {2 => [['*', 50]]})

Extend your index definitions

If you have a bunch of models with a lot of overlapping indexed fields, variables, or categories, you might want to abstract those out into a module that you can include and then extend in the including classes. Something like:

module TankerDefaults
  def self.included(base)
    base.send(:include, ::Tanker) # include the actual Tanker module

    # provide a default index name
    base.tankit 'my_index' do
      # index some common fields
      indexes :tag_list

      # set some common variables
      variables do
        {
          0 => view_count
          1 => foo
        }
      end
    end
  end
end

class SuperModel
  include TankerDefaults

  # no need to respecify the index if it's the same
  # (but you can override it)
  tankit do
    # `indexes :tag_list` is inherited
    indexes :name
    indexes :boyfriend_names do
      boyfriends.map(&:name)
    end

    # set some more specific variables
    variables do
      {
        # `0 => view_count` is inherited
        1 => iq,                 # overwrites "foo"
        2 => endorsements.count  # adds new variables
      }
    end
  end
end

You currently can’t remove previously defined stuff, though.

Single table inheritance

If you are using tanker with STI models and want the different models to be indexed as the same type, you can provide the base model name with an :as option to tankit.

module TankerPetDefaults
  def self.included(base)
    base.send(:include, ::Tanker)

    base.tankit 'my_index', :as => 'Pet' do
      indexes :skills
    end
  end
end

class Pet < ActiveRecord::Base
end

class Cat < Pet
  include TankerPetDefaults
end

class Monkey < Pet
  include TankerPetDefaults
end

# Search using the base model
Pet.search('stealth')

Reindex your data

If you are using rails 3 there are of couple of rake tasks included in your project

rake tanker:clear_indexes

This task deletes all your indexes and recreates empty indexes, if you have not created the indexes in the Index Tank interface this task creates them for you provided you have enough available indexes in your account.

rake tanker:reindex

This task pushes any functions you’ve defined in your tankit() blocks to indextank.com

rake tanker:functions

This task re-indexes all the your models that have the Tanker module included. Usually you will only need a single Index Tank index but if you want to separate your indexes please use different index names in the tankit method call in your models

To reindex just one class rather than all the classes in your application just call:

Model.tanker_reindex

And if you’d like to specify a custom number of records to PUT with each call to indextank.com you may specify it as the first argument:

Model.tanker_reindex(:batch_size => 1000) # defaults to batch size of 200

Or you can restrict indexing to a subset of records. This is particularly helpful for massive datasets where only a small portion of the records is useful.

Model.tanker_reindex(:batch_size => 1000, :scope => :not_deleted) # will call Model.not_deleted.all internally

Note on Patches/Pull Requests

  • Fork the project.

  • Make your feature addition or bug fix.

  • Add tests for it. This is important so I don’t break it in a future version unintentionally.

  • Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)

  • Send me a pull request. Bonus points for topic branches.

Note on testing

Tanker is has a full suite of unit tests that cover configuration and the api of the library but it also inludes a battery of Integration tests! These tests spec the behabiero between Index Tank and an ActiveRecord model with a Sqlite3 Backend.

If you want to run the specs you will need to provide an Index Tank Api key and user in the spec/integration_spec_conf.rb file. This file is ignored from the repo but you’ll find an example file in the same path.

To run specs +bundle exec rake spec+ and +bundle exec rake spec integration+

Acknowledgements

The gem is based on a couple of projects:

Kudos to this awesome projects and developers

There is a growing list of colabrators to this Gem so I would briefly mention them so if you know them and use this gem buy them a beer!

Copyright © 2011 @kidpollo. See LICENSE for details.

tanker's People

Contributors

coryschires avatar dandorman avatar edgarjs avatar forest avatar helloenvoy-andrew avatar herval avatar jackdanger avatar jksilliman avatar kidpollo avatar slothbear avatar spectator avatar trungpham avatar zsxking avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

tanker's Issues

Uncaught exception when searching and index tank isn't available

If index tank can not be reached (or do not have the index supplied or give any other error) a search will throw an uncaught exception.

The problem is that tanker always expects the response hash to contain 'results'.

    results = index_result['results']
    return [] if results.empty?

The solution is of course simple

    results = index_result['results']
    return [] if results.nil? || results.empty?

In production you do not want your app to get an error when your search is down but in development it would be nice to see the error. Me and @arvida was discussing that maybe we should have some sort of general handling for communication exceptions? (log, send with hoptoad if available or so)

Mainly want to take it up for discussion, I can send a pull request for just fixing so it fails silently if you think that is enough for now.

Feature request: access to `query_relevance_score`

I'd like to be able to only show results with a relevance above a certain threshhold.

Since we're doing some query expansion, the results set contains a lot of fuzz - documents which are only vaguely relevant. From reading the API docs it seems that the HTTP response body does include the relevance score of each result, which sounds perfect for this situation. However, as far as I can tell from the documentation Tanker doesn't support it.

Example

results = Article.search_tank('keyword')
top_results = results.select { |a| a.relevance >= 2 }

Relevant API Section

The response body will contain a JSON map with these fields:
    "matches": the total number of matches for the query
    "facets": a map from category name to a values count map
    "results": a list of objects with the "docid" field
        query_relevance_score: query specific document relevance score
        variable_<N>: variable value, from 0 to N
        category_<NAME>: category value for the NAME document category / facet
    "search_time": the time it took to search in seconds

Possible solutions

  • Instead of returning an array of whichever model, return an array of Result which extends the model and adds a new field called relevance, which is fetched from the IndexTank response.
  • Just expose the raw JSON response when you call results.index_tank_json, as a fallback for situations where Tanker doesn't cover all the API's functionality.

Let me know your thoughts, when I have some time I'd love to help work on this if you think it sounds sensible.

cannot connect to index tank on other port besides 80

def execute(req)
res = Net::HTTP.new(@uri.host).start { |http| http.request(req) }
if res.is_a? Net::HTTPSuccess
if res.body.nil? or res.body.empty?
return res.code, nil
else
begin
return res.code, JSON.parse(res.body)
rescue
raise "Invalid JSON response: #{res.body}"
end
end
elsif res.is_a? Net::HTTPUnauthorized
raise SecurityError, "Authorization required"
elsif res.is_a? Net::HTTPBadRequest
raise ArgumentError, res.body
else
raise HttpCodeException.new(res.code, res.body)
end
end

it seems like the code only forward the host part of the uri, and not the port.

IndexTank::HttpCodeException: Incorrect api call

I am using indextank-1.1.6 and facing above exception

following is my model definition

include Tanker
tankit "regions" do
indexes :name
indexes :full_name
indexes :slug
end

trace is like below

IndexTank::HttpCodeException: Incorrect api call
/home/loken/.rvm/gems/ruby-2.1.0@corental/gems/tanker-1.1.6/lib/indextank_client.rb:64:in execute' /home/loken/.rvm/gems/ruby-2.1.0@corental/gems/tanker-1.1.6/lib/indextank_client.rb:22:inPUT'
/home/loken/.rvm/gems/ruby-2.1.0@corental/gems/tanker-1.1.6/lib/indextank_client.rb:143:in add_documents' /home/loken/.rvm/gems/ruby-2.1.0@corental/gems/tanker-1.1.6/lib/tanker.rb:61:inbatch_update'
/home/loken/.rvm/gems/ruby-2.1.0@corental/gems/tanker-1.1.6/lib/tanker.rb:302:in block in tanker_reindex' /home/loken/.rvm/gems/ruby-2.1.0@corental/gems/tanker-1.1.6/lib/tanker.rb:301:ineach'
/home/loken/.rvm/gems/ruby-2.1.0@corental/gems/tanker-1.1.6/lib/tanker.rb:301:in each_with_index' /home/loken/.rvm/gems/ruby-2.1.0@corental/gems/tanker-1.1.6/lib/tanker.rb:301:intanker_reindex'
/home/loken/.rvm/gems/ruby-2.1.0@corental/gems/tanker-1.1.6/lib/tanker/utilities.rb:39:in block in reindex_all_models' /home/loken/.rvm/gems/ruby-2.1.0@corental/gems/tanker-1.1.6/lib/tanker/utilities.rb:38:ineach'
/home/loken/.rvm/gems/ruby-2.1.0@corental/gems/tanker-1.1.6/lib/tanker/utilities.rb:38:in reindex_all_models' /home/loken/.rvm/gems/ruby-2.1.0@corental/gems/tanker-1.1.6/lib/tanker/tasks/tanker.rake:7:inblock (2 levels) in <top (required)>'

Facets?

How do i get categories and count of results in it?

pagination total_results not counting correct

Hello guys,
i don't know if i make something wrong. here is my problem:

Tour.all.count

89
t = Tour.search_tank "deutsch*"
t.count
8
t.total_entries
87

The 8 is the real (correct) resultset (all tours with "deutsch*" in the content). But why is total_entries 87?
As far as i understand this, will_paginate uses the total_entries to calculate the paginate links ( < 1 2 3 > ).
So i get 9 paginate links for only 8 results (with 10 per page). I don't know, maybe it's a paginate bug, but i use will_paginate at other places without tanker without problems. Any help is appreciated, thanks!

What happens when IndexTank is down?

Hi, I'm a beginner at Rails and I was wondering how errors are handled in Tanker? For example, what happens when the IndexTank API is unreachable? Will my model fail to save? Ideally, my model data would be saved regardless and any failed attempts at indexing would be placed in a queue for retrying later.

Thanks!

Configuration

Hi guys,

Thank you very much for this work. I have a question: IndexTank isn't signing up new users. How do I get an api url? Is there a proper way to get around this? I am deploying my app on Heroku and I keep getting this message when I try to activate indexTank " That add-on is only available to selected users". Is this related to IndexTank's acquisition? Any idea how will the situation be?

Thank you very much!

can't search for words with special chars

hey guys,

i ran into a problem when i tried to search words with special characters like german umlauts (Ä, Ü and so on). I can't imagine that it is an intextank issue or is it? I hope you can help! thanks

AutoComplete

I'm having trouble getting Indextank's AutoComplete feature to work when using Tanker. When I run it I get no results back regardless of the query. I know the same issue was reported here - #25 - but i'm confused with the resolution that was given. I'm not sure what is meant by :indexes => :text in this instance. Can anyone shed a bit more light on what I need to do?

Can tanker drop records that can't be found?

From time to time, things are getting into my index that do not exist in my database. When this happens, I get an ActiveRecord::RecordNotFound exception (I'm using rails). I have fixed this locally by monkey patching the instantiate_results_from_db method. I know I could use rescue to handle that exception, but it seems like a shame when tanker could return 1,000 id's and one of them might not be in the database anymore. Here is how I fixed it:

#tanker.rb - instantiate_results_from_db
...
id_map.each do |klass, ids|
  # narrow ids down to records that exist 
  ids = ids.find_all {|x| constantize(klass).exists? x}
  ...
end

I hear this is what Sunspot does. What do you think? I suppose it could be configurable.

Sometimes indextank servers fail

I get a lot of "getaddrinfo: Name or service not known" from my app, with the following log :

/usr/ruby1.9.2/lib/ruby/1.9.1/net/http.rb:644:in `initialize'
/usr/ruby1.9.2/lib/ruby/1.9.1/net/http.rb:644:in `open'
/usr/ruby1.9.2/lib/ruby/1.9.1/net/http.rb:644:in `block in connect'
/usr/ruby1.9.2/lib/ruby/1.9.1/timeout.rb:44:in `timeout'
/usr/ruby1.9.2/lib/ruby/1.9.1/timeout.rb:87:in `timeout'
/usr/ruby1.9.2/lib/ruby/1.9.1/net/http.rb:644:in `connect'
/usr/ruby1.9.2/lib/ruby/1.9.1/net/http.rb:637:in `do_start'
/usr/ruby1.9.2/lib/ruby/1.9.1/net/http.rb:626:in `start'
/app/.bundle/gems/ruby/1.9.1/gems/tanker-1.1.4/lib/indextank_client.rb:48:in `execute'
/app/.bundle/gems/ruby/1.9.1/gems/tanker-1.1.4/lib/indextank_client.rb:22:in `PUT'
/app/.bundle/gems/ruby/1.9.1/gems/tanker-1.1.4/lib/indextank_client.rb:138:in `add_document'
/app/.bundle/gems/ruby/1.9.1/gems/tanker-1.1.4/lib/tanker.rb:348:in `update_tank_indexes'

Is there a way to fix this ?

Search result issue with scoping and pagination

When I try the following for search,

List.published.search_tank ("android", :page => 1, :per_page => 10)

I get 4 records back, but if I do:

List.published.search_tank ("android", :page => 2, :per_page => 10)

I get another four records. I would have expected all 8 to be returned on page 1.

List.published.search_tank ("android", :page => 1, :per_page => 20) returns all the 8 records.

rake tanker:functions is not finding defined fnctions

$ rake tanker:functions
reindexing all IndexTank functions
No IndexTank functions defined.
Define your server-side functions inside your model's tankit block like so:

  tankit 'myindex' do
    functions do
      {
        1 => "-age",
        2 => "relevance / miles(d[0], d[1], q[0], q[1])"
      }
    end
  end

I have the following defined in my model:

tankit do
    functions do
      {
          0 => "-age",
          1 => "relevance / miles(q[0], q[1], d[0], d[1])",
          2 => "miles(q[0], q[1], d[0], d[1])"
      }
    end
end

undefined method `conditions' (Rails 3.2.12, Tanker 1.1.6)

I just installed the latest tanker gem and began following the instructions in the readme, but the conditions block doesn't seem to be recognized:

undefined method `conditions' for #<Tanker::ModelConfig:0x007fdd84551270>

My model looks like this:

class Region < ActiveRecord::Base

  include Tanker

  ....

  tankit 'my_index' do
    conditions do
      indexable?
    end
    indexes :name
  end

  def indexable?
    self.name?
  end

end

Using kaminari for pagination

As described in the documentation, I define

MY_APPLICATION::Application.config.tanker_pagination_backend = :kaminari

in config/initializers/tanker.rb. Calling Tanker.configuration in the console results in

{:url=>"http://:[email protected]"}

As far as I can see, the tanker_pagination_backend wasn't applied. If I now try to use pagination in a view with the help of

<%= paginate @products %>

I get:

undefined method `num_pages' for #WillPaginate::Collection:0x000001042ac538

As far as I can interpret this, will_paginate is used instead of kaminari. What am I doing wrong?

1.8.7 compatibility

Hi there, I just started using Indextank on Heroku recently, and google points me to use this gem rather than thinkingtank (the one suggested by indextank).

Anyway, I added tanker into my Gemfile, ran bundle install, tried to follow through the example, and try to run the rake task.
That is where I ran into the rake task error.

I'm using rake gem version 0.8.7 and it gave me this error when trying to run 'rake' command:
Rake tasks fetching failed with (APP_PATH)
Tanker-1.1.1/lib/Tanker.rb:289:syntax error, unexpected ')', expecting '='

So, I took a look at the library and there seems to be a missing ampersand on the block for ModelConfig's initialize method, tried to fix that (rake runs now) and ran into ArgumentError (3 for 2) when trying to run the rake tanker:reindex task. I'm pretty new to Ruby so I'm not sure how to proceed.
Tried running version 1.0.9, no luck. Reverted to 1.0.0 and it ran fine.
Have I been doing something very wrong or is the gem broken?

search_tank alters the options hash

The search_tank(query, options) method alters the options hash. Might be good for it to dup them first (in search_results) so that the user can repeat the search without recreating the options (or having to dup them itself).

Add support for returning snippets with search results

I'd like to fetch results which include both a reference to my model instance as well as a snippet showing where the search term appeared in the indexed doc.

Looking thru the index tank docs, there's built in support for snippets functionality (also saw some reference to it in the tanker code). After poking around, however, I can't seem to solve a few problems:

  1. Tanker returns only model instances. That's good – and half of what I want. I would also like it to return the snippets (preferably as a virtual attribute so I can call @post.snippets along with the other attributes already being returned thru the model instance)

  2. Even when sprinkling trace statements throughout the Tanker code, I can't seem to figure out where/when/why my searches fail to fetch snippets. The snippets functionality works fine when strictly following the basic ruby tutorial in the index tank docs. Something in the Tanker code seems to be swallowing up the snippets (or preventing them from being fetched in the first place?).

If I'm missing something basic, let me know. Otherwise, I think this would be a feature worth adding. I'd be willing to help out. I just need a little direction as I'm not sure at what point the snippets are getting lost.

Thank for the work on this gem. It beats the pants off thinking_tank.

Cory.

Option to disable update/delete indexes in test environment

Is there a way to disable the update/delete indexes in test environment?
In my case I have many models with:
after_save :update_tank_indexes
after_destroy :delete_tank_indexes
Then each time a test object created, the update_tank_indexes will be called. This make the tests run very slow, and also break the test when I don't have Internet connection. It will be nice to be able to disable tanker's indexes update, and be able to enable it on per test case basis.

Conditional Indexing

With tanker, is there a way to make it so that a model is only indexed based on certain conditions? In my case, I only want to index if the model joins to another model. I've tried some different approaches, but so far nothing has been compatible with rake tanker:reindex.

Facets

Can someone explain me how to work with facets?
Thanks

Search through several models

I didn't find in documentation if this gem supports search through all models. Does this gem supports such feature? and how can I implement this?

Any way to search multiple models with conditions?

I'm trying to search multiple models with conditions like so:

@results = Tanker.search([Topic, Post], 'blah', :conditions => "topics.public is true")

The results I got didn't filter the results based on conditions (i.e. the results still searched for all topics instead of just public topics). I also tried using named scopes too:

@results = Tanker.search([Topic.public, Post], 'blah')

...but got an undefined method "per_page" error. How would I search multiple models with conditions correctly (if at all possible)?

Lost ability to search across multiple fields after upgrade to 1.1.2

Let's say I have a user:

+------------+-----------+------------+-----------+
| first_name | last_name | department | position  |
+------------+-----------+------------+-----------+
| Joe        | Smith     | History    | Professor |
+------------+-----------+------------+-----------+

When running version 1.0.0...

User.search_tank("Joe")
User.search_tank("Smith")
User.search_tank("Joe Smith")

...would all return the model instance for Joe Smith. After upgrading to version 1.1.2, I can still find Joe with...

User.search_tank("Joe")
User.search_tank("Smith")

but...

User.search_tank("Joe Smith")

...returns an empty array. Any idea what might be going on?

PS: New snippets are working great for me. Thanks a bunch! You should add a donate button to the repo.

Paging

Hi all,

My results are limited to 10! I can't find for the life of me where to change it. Appreciate its simple, any help would be appreciated :)

Geoff

Custom Docid

Any tanker forks that allow for creating a custom docid?

Certain keywords break the search_tank method

I encountered another difficulty while using the gem. I'm using Rails 3 and still using 1.8.7 Ruby (some gems are not compatible with the newer version)

Anyway, I have this code in my view

<%= form_tag search_path, :id => 'search_bar', :method => 'get' do %>
<%= text_field_tag :search, params[:search], :id =>"header-search-textbox", :placeholder => 'Search your moments here' %>
<%= submit_tag "Search", :id => 'header-search-btn', :name => nil %>

and my controller:

@moments = Moment.search_tank(params[:search], :variables => {0 => @group.id})
render 'some_page'

The problem is that my search function is broken for some keywords, for example: 'facebook', 'photo', or 'I'. Other random strings e.g. 'qwerty' or 'asdfg' actually ran and returned nil result and some other keywords return the expected results. However, for the few keywords mentioned above, instead of returning me nil result for my moments instance variable, it stops there and the page redirects to a 'page not found' route. It didn't run my render code.

Once again, I am really not sure how those few keywords break the search function. Some help here, anyone?

For now, I am using Indextank's client to get the query and there's no problem, just filing this report to check whether there's something that I'm missing...

Option to disable/enable pagination

Basically I would like to do queries without pagination turned on, so I just get an array of all the documents from #search. I also think new users don't expect the results to be paginated by default?

I am about to go a head and implement this, just want to check with you guys first if you have any thoughts on how it should work and if its a feature for the master branch? I few things I was thinking about:

  • Should pagination be enabled/disabled by default?
  • Should it be a setting on Tanker.configuration or an option per #search call?
  • Maybe you should be able to select pagination lib if enabled? Like having a setting that says
    Tanker.configuration.pagination_backend = :will_paginate or Tanker.configuration.pagination_backend = :kaminari (haven't checked much on the kaminari source yet, so might not be possible to use that lib..)

So, any thoughts on this? =)

Negative conditions don't work as expected (or at all?)

From my console:

Profile.search_tank("Kris")

Returns:

+-----+------------+-----------+-------------------------+------------+
| id  | first_name | last_name | bio                     | department |
+-----+------------+-----------+-------------------------+------------+
| 240 | Miss       | Kris      | Atque consequuntur l... | Dolor      |
+-----+------------+-----------+-------------------------+------------+

So I'm expecting this:

Profile.search_tank("Kris", :conditions => {'-id' => [204]})

To return nothing, but instead I get:

+-----+------------+-----------+-------------------------+------------+
| id  | first_name | last_name | bio                     | department |
+-----+------------+-----------+-------------------------+------------+
| 240 | Miss       | Kris      | Atque consequuntur l... | Dolor      |
+-----+------------+-----------+-------------------------+------------+

Two thoughts:

  1. Am I missing something simple?
  2. In this case, does id refer to the index tank document id rather than the id of the resource I'm searching on (i.e. the profile's id)?

If tanker is filtering on the index_tank doc id, I suspect that's not the behavior that most people would expect. Ideally, we shouldn't need to concern ourselves with index_tank references.

Please let me know if I'm missing something easy. Otherwise, let me know if you'd like me to start working on a fork.

Thanks, Cory.

Autocomplete

Indextank's autocomplete doesn't work properly when using Tanker. The problem seems to be due to Tanker putting multiple models into one index. Have you run into this, and if so, do you have a solution?

Disabling pagination returns max: 10 results

Given the same search term:

When I use :paginate => false, I get 10 results

when I put the normal pagination options back in (:page => params[:page], :per_page => x) I get 145 results

Geospatial example not working

The current Geospatial example code does not produced the desired result. Should the defined index functions be using d[0] q[0] notation or should it be doc.var[0] query.var[0]? And should the Tanker.search function be accepting :var0 :var1 parameters or should it be acception :variables => {0 => ..., 1 => ...}?

How to sort results?

Is there a way to sort results of search? I use indextank for e-commerce app for facet search & catalog list. I need to have the ability to sort by name in ASC & DESC orders, and sort by (price * product.currency.index). As results returned as paginated results I'm not able to sort them as array bevcause each page begins from the start. Paginate => false didn't work right now. Any ideas hot to accomplish this?

Mongoid as ORM

Indexing doesn't work with Mongoid as on ORM because Mongoid stores IDs as a BSON::ObjectId, not as a String or a Number (which yields the error "ArgumentError: "Value for field __id is not a String nor a number""). Any chance of adding a fix for this? I think I'll fork and give it a whirl.

Can't use tanker 1.1.0

/Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/tanker-1.1.0/lib/tanker/railtie.rb:13:in `block in ': undefined local variable or method`setup_tanker_configuration' for Tanker::Railtie:Class (NameError) from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.0.7/lib/active_support/lazy_load_hooks.rb:34:in `call' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.0.7/lib/active_support/lazy_load_hooks.rb:34:in`execute_hook' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.0.7/lib/active_support/lazy_load_hooks.rb:43:in `block in run_load_hooks' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.0.7/lib/active_support/lazy_load_hooks.rb:42:in`each' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.0.7/lib/active_support/lazy_load_hooks.rb:42:in `run_load_hooks' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.7/lib/rails/application/finisher.rb:46:in`block in module:Finisher' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.7/lib/rails/initializable.rb:25:in `instance_exec' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.7/lib/rails/initializable.rb:25:in`run' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.7/lib/rails/initializable.rb:50:in `block in run_initializers' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.7/lib/rails/initializable.rb:49:in`each' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.7/lib/rails/initializable.rb:49:in `run_initializers' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.7/lib/rails/application.rb:134:in`initialize!' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.7/lib/rails/application.rb:77:in `method_missing' from /Volumes/data/Projects/Code/Work/DevilCoders/muzarena/config/environment.rb:5:in`' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.0.7/lib/active_support/dependencies.rb:239:in `require' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.0.7/lib/active_support/dependencies.rb:239:in`block in require' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.0.7/lib/active_support/dependencies.rb:225:in `block in load_dependency' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.0.7/lib/active_support/dependencies.rb:596:in`new_constants_in' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.0.7/lib/active_support/dependencies.rb:225:in `load_dependency' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.0.7/lib/active_support/dependencies.rb:239:in`require' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.7/lib/rails/application.rb:103:in `require_environment!' from /Users/devilcoders/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.7/lib/rails/commands.rb:16:in`' from script/rails:6:in `require' from script/rails:6:in`'

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.