4

I have a Mongoid model which I perform ElasticSearch search queries on. Very standard:

class ActivityLog
  include Mongoid::Document
  include Mongoid::Timestamps
  include Tire::Model::Search
  include Tire::Model::Callbacks

  field :extra, type: Hash

  belongs_to :user, :inverse_of => :activity_logs


  def self.search(params, user)
    tire.search(load: true, page: params[:page], per_page: 5) do
      query { string params[:query], default_operator: "AND" } if params[:query].present?
      sort { by :created_at, "desc" }
    end
  end

I am having a hard time understanding the documentation on how to do more advanced stuff, and currently I'm stuck in how to work into my search query that search should be restricted to ActivityLog objects that belongs to the user only.

Could anyone show me how to work the user._id match requirement into the search query?

Cjoerg
  • 1,271
  • 3
  • 21
  • 63
  • you should index the user id in the activity log, then filter on it. – apneadiving Oct 15 '13 at 12:29
  • Thanks for your comment. But I am not sure how to do this. Could you elaborate a little bit, and maybe put it into an answer? – Cjoerg Oct 15 '13 at 12:33
  • you have no dedicated indexing method? – apneadiving Oct 15 '13 at 12:38
  • I have this line: index_name("#{Rails.env}-#{Rails.application.class.to_s.downcase}-activity_logs") – Cjoerg Oct 15 '13 at 12:51
  • well no, you are relying on defaults which makes difficult to tailor, you should read the doc, too much to say even in an sanswer – apneadiving Oct 15 '13 at 12:59
  • OK, I understand. But it is a "simple" relation that I want to filter by. I thought that there were many people out there who had previously needed to search for objects that only belonged to a certain user/object id... – Cjoerg Oct 15 '13 at 13:06
  • sure but its really easy: you index the foreign key and you filter it in your query and you're good – apneadiving Oct 15 '13 at 13:14
  • OK, and can you show me an example on how to index a foreign key? – Cjoerg Oct 15 '13 at 13:17
  • `indexes :user_id`, but the indexing json must match – apneadiving Oct 15 '13 at 13:19
  • Hmm, well not sure I am able to put the pieces from the comments together to a solution. I am asking the question because I am not so sharp in ElasticSearch. But I guess I'll just have to read up on it. – Cjoerg Oct 15 '13 at 13:32

2 Answers2

0

Working with ElasticSearch, there are 2 parts: mapping and search

So, if you want to search by a field of association table (users table), right. There are many ways, but this one I often use for my project:

Inside the ActivityLog model

  mapping do
    indexes :id, type: 'integer'
    indexes :name, type: 'string', analyzer: 'snowball', boost: 5
    indexes :description, type: 'string', analyzer: 'snowball'
    indexes :description_latin, as: 'description.sanitize', type: 'string', analyzer: 'snowball'
    indexes :user_id, as: 'user.id', type: 'string', index: :not_analyzed
    indexes :user_name, as: 'user.name', type: 'string'
    indexes :created_at, type: 'date'
    indexes :slug, index: :not_analyzed
    indexes :publish, type: 'boolean', index: :not_analyzed
  end

Notify the user_id and user_name, the above definition of mapping method will map the user.id to the user_id, and user.name to user_name.

So now in search method, you can do some similar code like filter :terms, user_id: params[:search][:user_id]

Hope this help

duykhoa
  • 2,227
  • 1
  • 25
  • 43
0

One correction to the above, ElasticSearch has dropped the type string and now uses text.

fuzzygroup
  • 1,109
  • 12
  • 12