Skip to content

Instantly share code, notes, and snippets.

@acmacalister
Created March 31, 2014 17:17
Show Gist options
  • Select an option

  • Save acmacalister/9897280 to your computer and use it in GitHub Desktop.

Select an option

Save acmacalister/9897280 to your computer and use it in GitHub Desktop.
ElasticSearch Article
ActiveRecord::Schema.define(version: 20140330054512) do
create_table "followers", force: true do |t|
t.integer "user_id"
t.integer "follower"
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "pending"
t.datetime "renew_at"
end
add_index "followers", ["user_id"], name: "index_followers_on_user_id", using: :btree
create_table "interests", force: true do |t|
t.integer "user_id"
t.integer "category_id"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "interests", ["category_id"], name: "index_interests_on_category_id", using: :btree
add_index "interests", ["user_id"], name: "index_interests_on_user_id", using: :btree
create_table "locations", force: true do |t|
t.integer "user_id"
t.string "latitude"
t.string "longitude"
t.string "address"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "locations", ["user_id"], name: "index_locations_on_user_id", using: :btree
create_table "users", force: true do |t|
t.string "name"
t.string "title"
t.datetime "created_at"
t.datetime "updated_at"
end
end
class User < ActiveRecord::Base
include Tire::Model::Search
include Tire::Model::Callbacks
has_many :followers
has_many :locations
has_many :interests
after_touch() { tire.update_index }
mapping do
indexes :id, type: 'integer'
indexes :name, type: 'string', analyzer: 'snowball'
indexes :title, type: 'string', analyzer: 'snowball'
indexes :coordinates, type: 'geo_point'
indexes :user_interests, type: 'string'
indexes :user_pictures, type: 'string'
end
def coordinates
array = []
locations.each do |l|
array << {lat: l.latitude, lon: l.longitude}
end
array
end
def user_interests
array = []
interests.map { |i| array << i[:category_id] }
array
end
def to_indexed_json
to_json(methods: ['coordinates', 'user_interests'])
end
def self.search(params, user)
array = [user.id]
pending = []
u_interests = []
user.followers.map { |f| f[:pending] ? pending << f[:follower] : array << f[:follower] }
user.interests.map { |i| u_interests << i[:category_id] }
tire.search(page: params[:page], per_page: params[:per_page]) do
query do
boolean({ :minimum_number_should_match => 1 }) do
should { match :user_interests, u_interests, {boost: 1}} if !u_interests.empty?
should { match :id, pending, { boost: 100 } } if !pending.empty?
end
end
filter :geo_distance, distance: "#{params[:distance]}mi", coordinates: "#{params[:latitude]},#{params[:longitude]}"
filter :not, { :terms => { id: array } }
end
end
def self.search_json(json)
array = []
json.each do |user|
array << {
id: user.id,
name: user.name,
title: user.name
interests: user.user_interests.sort || []
}
end if json
array.to_json
end
end
class UsersController < ApplicationController
def index
@users = User.search(params, @current_user)
render json: User.search_json(@users)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment