Commit 88267603 by Van Hau Le

Merge branch 'feature/search_function' into 'master'

Feature/search function

See merge request !20
parents 2324f19a 5e442bda
...@@ -21,12 +21,13 @@ gem 'jbuilder' ...@@ -21,12 +21,13 @@ gem 'jbuilder'
gem 'jquery-rails', '4.3.1' gem 'jquery-rails', '4.3.1'
gem 'carrierwave' gem 'carrierwave'
gem 'kaminari' gem 'kaminari'
gem 'sunspot_rails'
gem 'sunspot_solr'
gem 'devise' gem 'devise'
gem 'activerecord-import' gem 'activerecord-import'
gem 'config' gem 'config'
gem 'draper' gem 'draper'
gem 'rsolr'
gem 'rsolr-ext'
gem 'pry'
# Use Redis adapter to run Action Cable in production # Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0' # gem 'redis', '~> 4.0'
# Use Active Model has_secure_password # Use Active Model has_secure_password
......
...@@ -192,7 +192,6 @@ GEM ...@@ -192,7 +192,6 @@ GEM
nokogiri (1.10.5) nokogiri (1.10.5)
mini_portile2 (~> 2.4.0) mini_portile2 (~> 2.4.0)
orm_adapter (0.5.0) orm_adapter (0.5.0)
pr_geohash (1.0.0)
pry (0.12.2) pry (0.12.2)
coderay (~> 1.1.0) coderay (~> 1.1.0)
method_source (~> 0.9.0) method_source (~> 0.9.0)
...@@ -242,6 +241,8 @@ GEM ...@@ -242,6 +241,8 @@ GEM
rsolr (2.2.1) rsolr (2.2.1)
builder (>= 2.1.2) builder (>= 2.1.2)
faraday (>= 0.9.0) faraday (>= 0.9.0)
rsolr-ext (1.0.3)
rsolr (>= 1.0.2)
ruby-vips (2.0.16) ruby-vips (2.0.16)
ffi (~> 1.9) ffi (~> 1.9)
ruby_dep (1.5.0) ruby_dep (1.5.0)
...@@ -271,13 +272,6 @@ GEM ...@@ -271,13 +272,6 @@ GEM
actionpack (>= 4.0) actionpack (>= 4.0)
activesupport (>= 4.0) activesupport (>= 4.0)
sprockets (>= 3.0.0) sprockets (>= 3.0.0)
sunspot (2.5.0)
pr_geohash (~> 1.0)
rsolr (>= 1.1.1, < 3)
sunspot_rails (2.5.0)
rails (>= 3)
sunspot (= 2.5.0)
sunspot_solr (2.5.0)
thor (0.20.3) thor (0.20.3)
thread_safe (0.3.6) thread_safe (0.3.6)
tilt (2.0.10) tilt (2.0.10)
...@@ -329,12 +323,12 @@ DEPENDENCIES ...@@ -329,12 +323,12 @@ DEPENDENCIES
pry pry
puma (~> 3.11) puma (~> 3.11)
rails (~> 6.0.0) rails (~> 6.0.0)
rsolr
rsolr-ext
sass-rails (~> 5) sass-rails (~> 5)
selenium-webdriver selenium-webdriver
spring spring
spring-watcher-listen (~> 2.0.0) spring-watcher-listen (~> 2.0.0)
sunspot_rails
sunspot_solr
turbolinks (~> 5) turbolinks (~> 5)
tzinfo-data tzinfo-data
web-console (>= 3.3.0) web-console (>= 3.3.0)
......
class JobsController < ApplicationController class JobsController < ApplicationController
before_action :authenticate_user!, only: [:apply, :confirm_apply, :finish_apply, :applied_jobs] before_action :authenticate_user!, only: [:apply, :confirm_apply, :finish_apply, :applied_jobs]
before_action :find_user, only: :apply_available before_action :find_user, only: :apply_available
before_action :validate_city_industry, only: :index
def index def index
@search = params
solr = SolrService.new(@search)
if params[:city_id] if params[:city_id]
@city = City.find(params[:city_id]) @jobs = solr.query_by_city["docs"]
@jobs = @city.jobs @jobs_count = solr.query_by_city["numFound"]
elsif params[:industry_id] elsif params[:industry_id]
@industry = Industry.find(params[:industry_id]) @jobs = solr.query_by_industry["docs"]
@jobs = @industry.jobs @jobs_count = solr.query_by_industry["numFound"]
else else
@jobs = Job.all @jobs = solr.query_all["docs"]
@jobs_count = solr.query_all["numFound"]
end end
@jobs = @jobs.page(params[:page]).per(Settings.job.per_page).decorate @jobs = Kaminari.paginate_array(@jobs).page(params[:page]).per(Settings.job.per_page)
end end
def show def show
...@@ -55,4 +60,12 @@ class JobsController < ApplicationController ...@@ -55,4 +60,12 @@ class JobsController < ApplicationController
def find_user def find_user
@user = User.find_by(:id) @user = User.find_by(:id)
end end
def validate_city_industry
if params[:city_id]
redirect_to jobs_path unless City.find_by(id: params[:city_id])
elsif params[:industry_id]
redirect_to jobs_path unless Industry.find_by(id: params[:industry_id])
end
end
end end
module JobHelper
def view_search_result
params[:city_id] ? "City: #{@jobs[0]["city"]}" :
(params[:industry_id] ? "Industry: #{@jobs[0]["industry"]}" : params[:search])
end
end
require "rsolr"
class SolrService
def initialize(params = {search: "*:*"})
@solr = RSolr.connect(
url: Settings.solr.connection.server_url,
read_timeout: Settings.solr.connection.read_timeout,
open_timeout: Settings.solr.connection.open_timeout,
retry_503: Settings.solr.connection.retry_503
)
@params = params
end
def add_data
jobs = Job.includes(:cities, :industries, :company).all
jobs_solr_index = jobs.map do |job|
{
id: job.id,
title: job.title,
industry: job.industries&.first&.name,
description: job.description,
short_des: job.short_des,
salary: job.salary,
company: job.company.name,
city: job.cities&.first&.name,
}
end
jobs_solr_index.each_slice(5000) do |jobs|
@solr.add jobs
rescue Exception
jobs.each do |job|
@solr.add job
rescue
solr_index_error = ActiveSupport::Logger.new("log/solr_errors.log")
solr_index_error.info "This block got error! Cannot add job with id #{job.id}"
next
end
end
@solr.commit
end
def delete_data
@solr.delete_by_query("*:*")
@solr.commit
end
def query_all
q = "*#{@params[:search]}*"
fq = ""
send_request(q, fq)
end
def query_by_city
city = City.find_by(id: @params[:city_id])
return { "numFound": 0, "docs": [] } unless city
city_name = city.name
q = "*:*"
fq = "city: #{escape_str(city_name)}"
send_request(q, fq)
end
def query_by_industry
industry = Industry.find_by(id: @params[:industry_id])
return { "numFound": 0, "docs": [] } unless industry
industry_name = industry.name
q = "*:*"
fq = "industry: #{escape_str(industry_name)}"
send_request(q, fq)
end
def send_request(q, fq)
response = @solr.get "select", params: {
q: q,
fq: fq,
rows: Job.count
}
response["response"]
end
def escape_str(str)
RSolr.solr_escape(str)
end
end
...@@ -2,19 +2,19 @@ ...@@ -2,19 +2,19 @@
<div class="job_data"> <div class="job_data">
<dl class="job_data_row"> <dl class="job_data_row">
<dt>Title</dt> <dt>Title</dt>
<dd><%= link_to job.title, job_path(job.id) %></dd> <dd><%= link_to job["title"], job_path(job["id"]) %></dd>
</dl> </dl>
<dl class="job_data_row"> <dl class="job_data_row">
<dt>Short description</dt> <dt>Short description</dt>
<dd><%= job.display_short_des %></dd> <dd><%= job["short_des"]&.truncate(250) %></dd>
</dl> </dl>
<dl class="job_data_row"> <dl class="job_data_row">
<dt>Salary</dt> <dt>Salary</dt>
<dd><%= job.salary %></dd> <dd><%= job["salary"] %></dd>
</dl> </dl>
<dl class="job_data_row"> <dl class="job_data_row">
<dt>Location</dt> <dt>Location</dt>
<dd><%= job.city_name %></dd> <dd><%= job["city"] %></dd>
</dl> </dl>
</div> </div>
<button type="button" class="btn btn-outline-secondary">Favorite</button> <button type="button" class="btn btn-outline-secondary">Favorite</button>
......
<h3>Total: <%= params[:city_id] ? @city.job_count : <%= form_tag( jobs_path, method: :get, class: "form-inline") do %>
(params[:industry_id] ? @industry.job_count : Job.count) %></h3> <%= search_field_tag :search, params[:search], class: "form-control mb-2 mr-sm-2" %>
<h3>Result for: </h3> <%= submit_tag "Search", class: "btn btn-primary mb-2" %>
<% end %>
<h3>Total: <%= @jobs_count %></h3>
<h3>Result for: <%= view_search_result %></h3>
<%= paginate @jobs %> <%= paginate @jobs %>
......
...@@ -9,3 +9,11 @@ top: ...@@ -9,3 +9,11 @@ top:
limit: 9 limit: 9
job: job:
limit: 5 limit: 5
solr:
connection:
read_timeout: 120
open_timeout: 120
retry_503: 1
retry_after_limit: 1
server_url: "http://localhost:8983/solr/venjob"
namespace :task do namespace :csv do
desc "import data" desc "import data"
task import: :environment do task import: :environment do
Import.new.import Import.new.import
...@@ -7,3 +7,21 @@ namespace :task do ...@@ -7,3 +7,21 @@ namespace :task do
import.info "Cities, industries, companies, jobs imported succesfully at #{Time.current}" import.info "Cities, industries, companies, jobs imported succesfully at #{Time.current}"
end end
end end
namespace :solr do
desc "solr index data"
task solr_index: :environment do
SolrService.new.add_data
solr_index_logger = ActiveSupport::Logger.new("log/solr_service.log")
solr_index_logger.info "Solr index data succesfully at #{Time.current}"
end
desc "solr delete data"
task solr_delete: :environment do
SolrService.new.delete_data
solr_delete_logger = ActiveSupport::Logger.new("log/solr_service.log")
solr_delete_logger.info "Solr delete all data succesfully at #{Time.current}"
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment