Commit f18b0d89 by Ngô Trung Hưng

Merge branch 'master' into 'admin'

# Conflicts:
#   Gemfile
#   Gemfile.lock
#   config/application.rb
#   config/locales/en.yml
#   config/locales/vn.yml
#   config/routes.rb
parents 9f4a0e4d 897ec388
Pipeline #1115 canceled with stages
in 0 seconds
......@@ -27,3 +27,8 @@
# Ignore master key for decrypting credentials and more.
/config/master.key
/lib/csv
.vscode/settings.json
config/settings.local.yml
config/settings/*.local.yml
config/environments/*.local.yml
# Load DSL and set up stages
require "capistrano/setup"
# Include default deployment tasks
require "capistrano/deploy"
# Load the SCM plugin appropriate to your project:
#
# require "capistrano/scm/hg"
# install_plugin Capistrano::SCM::Hg
# or
# require "capistrano/scm/svn"
# install_plugin Capistrano::SCM::Svn
# or
require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git
# Include tasks from other gems included in your Gemfile
#
# For documentation on these, see for example:
#
# https://github.com/capistrano/rvm
# https://github.com/capistrano/rbenv
# https://github.com/capistrano/chruby
# https://github.com/capistrano/bundler
# https://github.com/capistrano/rails
# https://github.com/capistrano/passenger
#
# require "capistrano/rvm"
require "capistrano/rbenv"
# require "capistrano/chruby"
require "capistrano/bundler"
require "capistrano/rails/assets"
require "capistrano/rails/migrations"
require "capistrano/passenger"
#require 'capistrano/bower'
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
......@@ -35,6 +35,8 @@ gem 'devise'
gem 'carrierwave'
gem 'rails-i18n'
gem 'i18n-js'
gem 'rsolr'
gem 'config'
gem 'therubyracer'
# Use ActiveStorage variant
# gem 'mini_magick', '~> 4.8'
......@@ -48,8 +50,10 @@ gem 'bootsnap', '>= 1.1.0', require: false
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
gem 'rubocop'
gem 'dotenv-rails'
gem 'pry'
gem 'pry-nav'
end
group :development do
......@@ -71,3 +75,11 @@ end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
# Deploy
gem 'capistrano'
gem 'capistrano-rails'
gem 'capistrano-bundler'
gem 'capistrano-unicorn-nginx'
gem 'unicorn'
gem 'capistrano-rvm'
GEM
remote: https://rubygems.org/
specs:
actioncable (5.2.4.3)
actionpack (= 5.2.4.3)
actioncable (5.2.4.4)
actionpack (= 5.2.4.4)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailer (5.2.4.3)
actionpack (= 5.2.4.3)
actionview (= 5.2.4.3)
activejob (= 5.2.4.3)
actionmailer (5.2.4.4)
actionpack (= 5.2.4.4)
actionview (= 5.2.4.4)
activejob (= 5.2.4.4)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
actionpack (5.2.4.3)
actionview (= 5.2.4.3)
activesupport (= 5.2.4.3)
actionpack (5.2.4.4)
actionview (= 5.2.4.4)
activesupport (= 5.2.4.4)
rack (~> 2.0, >= 2.0.8)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.2.4.3)
activesupport (= 5.2.4.3)
actionview (5.2.4.4)
activesupport (= 5.2.4.4)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.3)
activejob (5.2.4.3)
activesupport (= 5.2.4.3)
activejob (5.2.4.4)
activesupport (= 5.2.4.4)
globalid (>= 0.3.6)
activemodel (5.2.4.3)
activesupport (= 5.2.4.3)
activemodel (5.2.4.4)
activesupport (= 5.2.4.4)
activemodel-serializers-xml (1.0.2)
activemodel (> 5.x)
activesupport (> 5.x)
builder (~> 3.1)
activerecord (5.2.4.3)
activemodel (= 5.2.4.3)
activesupport (= 5.2.4.3)
activerecord (5.2.4.4)
activemodel (= 5.2.4.4)
activesupport (= 5.2.4.4)
arel (>= 9.0)
activestorage (5.2.4.3)
actionpack (= 5.2.4.3)
activerecord (= 5.2.4.3)
activestorage (5.2.4.4)
actionpack (= 5.2.4.4)
activerecord (= 5.2.4.4)
marcel (~> 0.3.1)
activesupport (5.2.4.3)
activesupport (5.2.4.4)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
airbrussh (1.4.0)
sshkit (>= 1.6.1, != 1.7.0)
archive-zip (0.12.0)
io-like (~> 0.3.0)
arel (9.0.0)
bcrypt (3.1.15)
ast (2.4.1)
bcrypt (3.1.16)
bindex (0.8.1)
bootsnap (1.4.7)
bootsnap (1.4.8)
msgpack (~> 1.0)
breadcrumbs_on_rails (4.0.0)
rails (>= 5.0)
builder (3.2.4)
byebug (11.1.3)
capistrano (3.14.1)
airbrussh (>= 1.0.0)
i18n
rake (>= 10.0.0)
sshkit (>= 1.9.0)
capistrano-bundler (2.0.1)
capistrano (~> 3.1)
capistrano-rails (1.6.1)
capistrano (~> 3.1)
capistrano-bundler (>= 1.1, < 3)
capistrano-rvm (0.1.2)
capistrano (~> 3.0)
sshkit (~> 1.2)
capistrano-unicorn-nginx (5.2.0)
capistrano (>= 3.1)
sshkit (>= 1.2.0)
capybara (3.33.0)
addressable
mini_mime (>= 0.1.3)
......@@ -87,9 +106,13 @@ GEM
coffee-script-source
execjs
coffee-script-source (1.12.2)
concurrent-ruby (1.1.6)
concurrent-ruby (1.1.7)
config (2.2.1)
deep_merge (~> 1.2, >= 1.2.1)
dry-validation (~> 1.0, >= 1.0.0)
crass (1.0.6)
devise (4.7.2)
deep_merge (1.2.1)
devise (4.7.3)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0)
......@@ -105,8 +128,48 @@ GEM
activemodel-serializers-xml (>= 1.0)
activesupport (>= 5.0)
request_store (>= 1.0)
dry-configurable (0.11.6)
concurrent-ruby (~> 1.0)
dry-core (~> 0.4, >= 0.4.7)
dry-equalizer (~> 0.2)
dry-container (0.7.2)
concurrent-ruby (~> 1.0)
dry-configurable (~> 0.1, >= 0.1.3)
dry-core (0.4.9)
concurrent-ruby (~> 1.0)
dry-equalizer (0.3.0)
dry-inflector (0.2.0)
dry-initializer (3.0.3)
dry-logic (1.0.7)
concurrent-ruby (~> 1.0)
dry-core (~> 0.2)
dry-equalizer (~> 0.2)
dry-schema (1.5.4)
concurrent-ruby (~> 1.0)
dry-configurable (~> 0.8, >= 0.8.3)
dry-core (~> 0.4)
dry-equalizer (~> 0.2)
dry-initializer (~> 3.0)
dry-logic (~> 1.0)
dry-types (~> 1.4)
dry-types (1.4.0)
concurrent-ruby (~> 1.0)
dry-container (~> 0.3)
dry-core (~> 0.4, >= 0.4.4)
dry-equalizer (~> 0.3)
dry-inflector (~> 0.1, >= 0.1.2)
dry-logic (~> 1.0, >= 1.0.2)
dry-validation (1.5.6)
concurrent-ruby (~> 1.0)
dry-container (~> 0.7, >= 0.7.1)
dry-core (~> 0.4)
dry-equalizer (~> 0.2)
dry-initializer (~> 3.0)
dry-schema (~> 1.5, >= 1.5.2)
erubi (1.9.0)
execjs (2.7.0)
faraday (1.0.1)
multipart-post (>= 1.2, < 3)
ffi (1.13.1)
globalid (0.4.2)
activesupport (>= 4.2.0)
......@@ -114,11 +177,11 @@ GEM
concurrent-ruby (~> 1.0)
i18n-js (3.7.1)
i18n (>= 0.6.6)
image_processing (1.11.0)
image_processing (1.12.0)
mini_magick (>= 4.9.5, < 5)
ruby-vips (>= 2.0.17, < 3)
io-like (0.3.1)
jbuilder (2.10.0)
jbuilder (2.10.1)
activesupport (>= 5.0.0)
kaminari (1.2.1)
activesupport (>= 4.1.0)
......@@ -132,50 +195,60 @@ GEM
activerecord
kaminari-core (= 1.2.1)
kaminari-core (1.2.1)
libv8 (3.16.14.19-x86_64-linux)
kgio (2.11.3)
libv8 (3.16.14.19)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
ruby_dep (~> 1.2)
loofah (2.6.0)
loofah (2.7.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
mini_mime (>= 0.1.1)
marcel (0.3.3)
mimemagic (~> 0.3.2)
method_source (1.0.0)
method_source (0.9.2)
mimemagic (0.3.5)
mini_magick (4.10.1)
mini_mime (1.0.2)
mini_portile2 (2.4.0)
minitest (5.14.1)
minitest (5.14.2)
msgpack (1.3.3)
multipart-post (2.1.1)
mysql2 (0.5.3)
nio4r (2.5.2)
net-scp (3.0.0)
net-ssh (>= 2.6.5, < 7.0.0)
net-ssh (6.1.0)
nio4r (2.5.4)
nokogiri (1.10.10)
mini_portile2 (~> 2.4.0)
orm_adapter (0.5.0)
pry (0.13.1)
coderay (~> 1.1)
method_source (~> 1.0)
public_suffix (4.0.5)
parallel (1.19.2)
parser (2.7.1.4)
ast (~> 2.4.1)
pry (0.12.2)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
pry-nav (0.3.0)
pry (>= 0.9.10, < 0.13.0)
public_suffix (4.0.6)
puma (3.12.6)
rack (2.2.3)
rack-test (1.1.0)
rack (>= 1.0, < 3)
rails (5.2.4.3)
actioncable (= 5.2.4.3)
actionmailer (= 5.2.4.3)
actionpack (= 5.2.4.3)
actionview (= 5.2.4.3)
activejob (= 5.2.4.3)
activemodel (= 5.2.4.3)
activerecord (= 5.2.4.3)
activestorage (= 5.2.4.3)
activesupport (= 5.2.4.3)
rails (5.2.4.4)
actioncable (= 5.2.4.4)
actionmailer (= 5.2.4.4)
actionpack (= 5.2.4.4)
actionview (= 5.2.4.4)
activejob (= 5.2.4.4)
activemodel (= 5.2.4.4)
activerecord (= 5.2.4.4)
activestorage (= 5.2.4.4)
activesupport (= 5.2.4.4)
bundler (>= 1.3.0)
railties (= 5.2.4.3)
railties (= 5.2.4.4)
sprockets-rails (>= 2.0.0)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
......@@ -185,23 +258,41 @@ GEM
rails-i18n (5.1.3)
i18n (>= 0.7, < 2)
railties (>= 5.0, < 6)
railties (5.2.4.3)
actionpack (= 5.2.4.3)
activesupport (= 5.2.4.3)
railties (5.2.4.4)
actionpack (= 5.2.4.4)
activesupport (= 5.2.4.4)
method_source
rake (>= 0.8.7)
thor (>= 0.19.0, < 2.0)
rainbow (3.0.0)
raindrops (0.19.1)
rake (13.0.1)
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
ref (2.0.0)
regexp_parser (1.7.1)
regexp_parser (1.8.0)
request_store (1.5.0)
rack (>= 1.4)
responders (3.0.1)
actionpack (>= 5.0)
railties (>= 5.0)
rexml (3.2.4)
rsolr (2.3.0)
builder (>= 2.1.2)
faraday (>= 0.9.0)
rubocop (0.91.0)
parallel (~> 1.10)
parser (>= 2.7.1.1)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.7)
rexml
rubocop-ast (>= 0.4.0, < 1.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 2.0)
rubocop-ast (0.4.2)
parser (>= 2.7.1.4)
ruby-progressbar (1.10.1)
ruby-vips (2.0.17)
ffi (~> 1.9)
ruby_dep (1.5.0)
......@@ -220,14 +311,14 @@ GEM
selenium-webdriver (3.142.7)
childprocess (>= 0.5, < 4.0)
rubyzip (>= 1.2.2)
spring (2.1.0)
spring (2.1.1)
spring-watcher-listen (2.0.1)
listen (>= 2.7, < 4.0)
spring (>= 1.2, < 3.0)
sprockets (3.7.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.2.1)
sprockets-rails (3.2.2)
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
......@@ -244,8 +335,12 @@ GEM
thread_safe (~> 0.1)
uglifier (4.2.0)
execjs (>= 0.3.0, < 3)
warden (1.2.8)
rack (>= 2.0.6)
unicode-display_width (1.7.0)
unicorn (5.7.0)
kgio (~> 2.6)
raindrops (~> 0.7)
warden (1.2.9)
rack (>= 2.0.9)
web-console (3.7.0)
actionview (>= 5.0)
activemodel (>= 5.0)
......@@ -266,10 +361,16 @@ DEPENDENCIES
bootsnap (>= 1.1.0)
breadcrumbs_on_rails
byebug
capistrano
capistrano-bundler
capistrano-rails
capistrano-rvm
capistrano-unicorn-nginx
capybara (>= 2.15)
carrierwave
chromedriver-helper
coffee-rails (~> 4.2)
config
devise
dotenv-rails
draper
......@@ -280,9 +381,12 @@ DEPENDENCIES
mysql2 (>= 0.4.4, < 0.6.0)
nokogiri
pry
pry-nav
puma (~> 3.11)
rails (~> 5.2.4, >= 5.2.4.3)
rails-i18n
rsolr
rubocop
sass-rails (~> 5.0)
selenium-webdriver
spring
......@@ -291,6 +395,7 @@ DEPENDENCIES
turbolinks (~> 5)
tzinfo-data
uglifier (>= 1.3.0)
unicorn
web-console (>= 3.3.0)
whenever
......@@ -298,4 +403,4 @@ RUBY VERSION
ruby 2.6.6p146
BUNDLED WITH
1.17.2
2.1.4
# Solr server
http://192.168.1.57:8983/solr/#/
# README
This README would normally document whatever steps are necessary to get the
......
......@@ -406,18 +406,29 @@ $main-color: #23303D;
transform: translateY(-50%);
}
}
.search_industries select{
@mixin custom_select {
padding: 12px 10px 12px 5px;
width: 100%;
border-radius: 4px !important;
border: none;
box-shadow: none;
background: transparent;
outline: none;
cursor: pointer;
text-indent: 0.01px;
text-overflow: ellipsis;
text-overflow: ellipsis;
padding-left: 16px;
color: #666;
font-size: 15px;
}
.search_industries select{
@include custom_select()
}
.search_location select {
@include custom_select()
}
.search_location {
......@@ -557,10 +568,12 @@ $main-color: #23303D;
background-color: #fff;
color: #666;
margin-bottom: 10px;
border: none;
font-size: 13px;
// padding: 0px 4px;
}
.search_industries_mobile {
position: relative;
@include custom_selected_mobile();
&::before {
position: absolute;
content: '';
......@@ -572,7 +585,13 @@ $main-color: #23303D;
transform: translateY(-50%);
}
}
.search_location_mobile {
.search_industries_mobile select{
padding: 0px 4px;
@include custom_selected_mobile()
}
.search_location_mobile select{
padding: 0px 4px;
@include custom_selected_mobile()
}
......@@ -1362,12 +1381,12 @@ $main-color: #23303D;
.btn_search_submit {
height: 30px;
}
.search_industries_mobile {
padding-right: 4px;
}
.search_location_mobile {
padding-right: 4px;
}
// .search_industries_mobile {
// padding-right: 4px;
// }
// .search_location_mobile {
// padding-right: 4px;
// }
}
@media only screen and (max-width: 576px) {
.lol {
......
# frozen_string_literal: true
class IndexedJob
attr_accessor :job
def initialize(job)
@job = job
end
def do
index_strategy = Sync::Entities::Job.new(job)
Sync::Indexer.new.do(index_strategy)
end
end
# frozen_string_literal: true
module InitSearch
def searches
Search.new search_params
end
private
def search_params
return {} if params[:search].blank?
params.require(:search).permit(:keyword, :industry_id, :city_id)
end
end
......@@ -5,6 +5,6 @@ class HistoriesController < ApplicationController
def index
histories = current_user.histories.order(created_at: :desc)
@jobs = histories.map(&:job)
@jobs = histories.map(&:job).compact
end
end
......@@ -2,12 +2,14 @@
# Home page
class HomeController < ApplicationController
include InitSearch
def index
@industries = Industry.order(name: :asc).all
@industries = Industry.order(name: :asc)
@job_count = Job.count
@cities = City.all_cities
@lasted_jobs = Job.order(created_at: :desc).limit(Job::NUMBER_LASTED_JOB)
@top_cities = City.top_cities(9)
@top_industries = Industry.top_industries(9)
@search = searches
end
end
......@@ -28,6 +28,7 @@ class JobController < ApplicationController
end
def render_result(obj)
@search = Search.new
@keyword = obj.name
@data = obj.jobs.page(params[:page])
return render 'error/page_not_found' if @data.blank?
......
# frozen_string_literal: true
class PasswordsController < Devise::PasswordsController
def new
super
end
def create
self.resource = resource_class.send_reset_password_instructions(resource_params)
yield resource if block_given?
if successfully_sent?(resource)
respond_with({}, location: after_sending_reset_password_instructions_path_for(resource_name))
else
helpers.render_errors(resource)
respond_with(resource) { |format| format.html { redirect_to new_password_path(resource) } }
end
end
end
class SearchController < ApplicationController
before_action :load_data_dropdown, only: :search
include InitSearch
def search
return render 'error/internal_server_error' if params[:search].blank?
@keyword = params[:search][:keyword]
@industry = Industry.find_by(id: params[:search][:industry_id])
@city = City.find_by(id: params[:search][:city_id])
@results = Searches::Query.new.search(params)
return render 'error/page_not_found' if params[:page].to_i > @results.total_pages
@search = searches
render :result
end
def load_data_dropdown
@industries = Industry.order(name: :asc)
@cities = City.select(:id, :name)
end
end
# frozen_string_literal: true
class Search
include ActiveModel::Model
attr_accessor :keyword, :industry_id, :city_id
selected_industry = @industry.blank? ? '*' : @industry.id
selected_city = @city.blank? ? '*' : @city.id
end
# frozen_string_literal: true
module ApplyJobHelper
end
module RegistrationsHelper
end
......@@ -2,6 +2,8 @@
# Description/Explanation of Person class
class Job < ApplicationRecord
after_update :indexed_job
NUMBER_LASTED_JOB = 5
belongs_to :company
......@@ -16,4 +18,8 @@ class Job < ApplicationRecord
has_many :histories
has_many :favorites
def indexed_job
IndexedJob.new(self).do
end
end
......@@ -12,7 +12,6 @@
</div>
</div>
</div>
<!-- Process search pc-->
<div class="box-search">
<div class="search_scaffold">
......@@ -23,29 +22,28 @@
<h4 class="show_total_job"><%= t('pages.banner.slogan_3', job_count: @job_count) %></h4>
<% end %>
</div>
<div class="filter_box">
<div class="search_input">
<input type="search" name="" id="" class="custom_input_search" placeholder="<%= t('pages.banner.search_placeholder') %>">
</div>
<div class="search_industries">
<div class="icon_list">
<i class="fa fa-list-ul" aria-hidden="true"></i>
<%= form_with url: search_path, method: :get, local: true, skip_enforcing_utf8: true do |f| %>
<div class="filter_box">
<div class="search_input">
<%= f.search_field :keyword, value: @keyword, class: 'custom_input_search', placeholder: t('pages.banner.search_placeholder') %>
</div>
<%= select_tag 'industry', options_from_collection_for_select(@industries, 'id', 'name'), prompt: t('pages.banner.all_industries'), class: 'show_list_industries' %>
</div>
<div class="search_location">
<div class="icon_list">
<i class="fas fa-map-marker-alt"></i>
<div class="search_industries">
<div class="icon_list">
<i class="fa fa-list-ul" aria-hidden="true"></i>
</div>
<%= select_tag 'industry_id', options_from_collection_for_select(@industries, 'id', 'name', selected_industry), prompt: t('pages.banner.all_industries'), class: 'show_list_industries' %>
</div>
<div class="search_location">
<div class="icon_list">
<i class="fas fa-map-marker-alt"></i>
</div>
<%= select_tag 'city_id', options_from_collection_for_select(@cities, 'id', 'name', selected_city), prompt: t('pages.banner.all_locations'), class: 'show_list_cities' %>
</div>
<div class="search_submit">
<%= f.submit t('pages.banner.btn_text_search'), name: nil, class: 'btn_search_submit'%>
</div>
<%= select_tag 'city', options_from_collection_for_select(@cities, 'id', 'name'), prompt: t('pages.banner.all_locations'), class: 'show_list_cities' %>
</div>
<div class="search_submit">
<button type="submit" class="btn_search_submit">
<i class="fas fa-search"></i>
<%= t('pages.banner.btn_text_search') %>
</button>
</div>
</div>
<% end %>
</div>
</div>
<!-- Process search tablet-->
......@@ -54,29 +52,28 @@
<div class = "total_job">
<h4 class="show_total_job"><%= t('pages.banner.slogan_3', job_count: @job_count) %> </h4>
</div>
<div class="filter_box filter_box_tablet">
<div class="search_input">
<input type="search" name="" id="" class="custom_input_search" placeholder="<%= t('pages.banner.search_placeholder') %>">
</div>
<div class="search_industries">
<%= form_with url: search_path, method: :get, local: true, skip_enforcing_utf8: true do |f| %>
<div class="filter_box filter_box_tablet">
<div class="search_input">
<%= f.search_field :keyword, value: @keyword, class: 'custom_input_search', placeholder: t('pages.banner.search_placeholder') %>
</div>
<div class="search_industries">
<div class="icon_list">
<i class="fa fa-list-ul" aria-hidden="true"></i>
</div>
<%= select_tag 'industry', options_from_collection_for_select(@industries, 'id', 'name'), prompt: t('pages.banner.all_industries'), class: 'show_list_industries' %>
</div>
<div class="search_location">
<div class="icon_list">
<i class="fas fa-map-marker-alt"></i>
<%= select_tag 'industry_id', options_from_collection_for_select(@industries, 'id', 'name', selected_industry), include_blank: t('pages.banner.all_industries'), class: 'show_list_industries' %>
</div>
<div class="search_location">
<div class="icon_list">
<i class="fas fa-map-marker-alt"></i>
</div>
<%= select_tag 'city_id', options_from_collection_for_select(@cities, 'id', 'name', selected_city), include_blank: t('pages.banner.all_locations'), class: 'show_list_cities' %>
</div>
<div class="search_submit">
<%= f.submit t('pages.banner.btn_text_search'), name: nil, class: 'btn_search_submit'%>
</div>
<%= select_tag 'city', options_from_collection_for_select(@cities, 'id', 'name'), prompt: t('pages.banner.all_locations'), class: 'show_list_cities' %>
</div>
<div class="search_submit">
<button type="submit" class="btn_search_submit">
<i class="fas fa-search"></i>
<%= t('pages.banner.btn_text_search') %>
</button>
</div>
</div>
<% end %>
</div>
</div>
<div class="box-show-total-jobs-mobile">
......@@ -84,34 +81,33 @@
</div>
<!-- Process search mobile-->
<div class="box-search-mobile">
<div class="fillter-search-mobile">
<div class="container">
<div class="row no-gutters">
<div class="col-md-12">
<input type="search" name="" id="" class="custom_input_mobile_search" placeholder="<%= t('pages.banner.search_placeholder') %>">
</div>
<div class="col-sm-6 col-xs-12">
<div class="search_industries_mobile">
<%= select_tag 'industry', options_from_collection_for_select(@industries, 'id', 'name'), prompt: t('pages.banner.all_industries'), class: 'show_list_industries_mobile' %>
<%= form_with url: search_path, method: :get, local: true, skip_enforcing_utf8: true do |f| %>
<div class="fillter-search-mobile">
<div class="container">
<div class="row no-gutters">
<div class="col-md-12">
<%= f.search_field :keyword, value: @keyword, class: 'custom_input_mobile_search', placeholder: t('pages.banner.search_placeholder') %>
</div>
</div>
<div class="col-sm-6 col-xs-12">
<div class="search_location_mobile">
<%= select_tag 'city', options_from_collection_for_select(@cities, 'id', 'name'), prompt: t('pages.banner.all_locations'), class: 'show_list_cities_mobile' %>
<div class="col-sm-6 col-xs-12">
<div class="search_industries_mobile">
<%= select_tag 'industry_id', options_from_collection_for_select(@industries, 'id', 'name', selected_industry), prompt: t('pages.banner.all_industries'), class: 'show_list_industries_mobile' %>
</div>
</div>
<div class="col-sm-6 col-xs-12">
<div class="search_location_mobile">
<%= select_tag 'city_id', options_from_collection_for_select(@cities, 'id', 'name', selected_city), prompt: t('pages.banner.all_locations'), class: 'show_list_cities_mobile' %>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row no-gutters">
<div class="col-sm-12">
<button type="submit" class="btn_search_submit">
<i class="fas fa-search"></i>
<%= t('pages.banner.btn_text_search') %>
</button>
<div class="container">
<div class="row no-gutters">
<div class="col-sm-12">
<%= f.submit t('pages.banner.btn_text_search'), name: nil, class: 'btn_search_submit'%>
</div>
</div>
</div>
</div>
</div>
<% end %>
</div>
<% provide(:title, "#{t('title.home')}") %>
<%= render 'home/banner_and_search' %>
<%= render 'search/banner_and_search' %>
<div class="padding_index"></div>
<% unless @job_count.nil? %>
<% unless @job_count.blank? %>
<div class="box_text_five_jobs">
<span><%= t('pages.index.lasted_job') %></span>
</div>
......
<% provide(:title ,"#{t('pages.detail.br_title')}") %>
<%= render 'home/banner_and_search' %>
<%= render 'search/banner_and_search' %>
<div class="padding_index"></div>
<div class="container">
<div class="row">
......@@ -11,7 +11,7 @@
<%= t('pages.result.result_find', job: @data.total_count, key: @keyword).html_safe %>
</div>
<% else %>
<%= t('pages.result.no_result_find', key: @keyword).html_safe %>
<%= t('pages.result.no_result_find', key: @keyword).html_safe %>
<% end %>
</span>
</div>
......
<div class = "box-banner">
<%= image_tag 'banner-search-box-home.png', class: "banner-top" %>
<div class="row">
<div class="col-xs-12">
<div class = "slogan">
<h2 class = "slogan_text">
<%= t('pages.banner.slogan') %>
</h2>
<h5 class = "slogan_text_h5">
<%= t('pages.banner.slogan') %>
</h5>
</div>
</div>
</div>
<!-- Process search pc-->
<div class="box-search">
<div class="search_scaffold">
<div class = "total_job">
<h4 class="show_total_job">
<%= @job_count.blank? ? t('pages.banner.slogan_2') : t('pages.banner.slogan_3', job_count: @job_count) %>
</h4>
</div>
<%= form_for @search, enforce_utf8: false, method: :get do |f| %>
<div class="filter_box">
<div class="search_input">
<%= f.search_field :keyword, value: @keyword, class: 'custom_input_search', placeholder: t('pages.banner.search_placeholder') %>
</div>
<div class="search_industries">
<div class="icon_list">
<i class="fa fa-list-ul" aria-hidden="true"></i>
</div>
<% selected = @industry.blank? ? '*' : @industry.id %>
<%= f.select 'industry_id', options_from_collection_for_select(@industries, 'id', 'name', selected), include_blank: t('pages.banner.all_industries'), class: 'show_list_industries'%>
</div>
<div class="search_location">
<div class="icon_list">
<i class="fas fa-map-marker-alt"></i>
</div>
<% selected = @city.blank? ? '*' : @city.id %>
<%= f.select 'city_id', options_from_collection_for_select(@cities, 'id', 'name', selected), include_blank: t('pages.banner.all_locations'), class: 'show_list_cities' %>
</div>
<div class="search_submit">
<%= f.submit t('pages.banner.btn_text_search'), name: nil, class: 'btn_search_submit'%>
</div>
</div>
<% end %>
</div>
</div>
<!-- Process search tablet-->
<div class="box-search-tablet">
<div class="search_scaffold-tablet">
<div class = "total_job">
<h4 class="show_total_job"><%= t('pages.banner.slogan_3', job_count: @job_count) %> </h4>
</div>
<%= form_for @search, enforce_utf8: false, method: :get do |f| %>
<div class="filter_box filter_box_tablet">
<div class="search_input">
<%= f.search_field :keyword, value: @keyword, class: 'custom_input_search', placeholder: t('pages.banner.search_placeholder') %>
</div>
<div class="search_industries">
<div class="icon_list">
<i class="fa fa-list-ul" aria-hidden="true"></i>
</div>
<% selected = @industry.blank? ? '*' : @industry.id %>
<%= f.select 'industry_id', options_from_collection_for_select(@industries, 'id', 'name', selected), prompt: t('pages.banner.all_industries'), class: 'show_list_industries' %>
</div>
<div class="search_location">
<div class="icon_list">
<i class="fas fa-map-marker-alt"></i>
</div>
<% selected = @city.blank? ? '*' : @city.id %>
<%= f.select 'city_id', options_from_collection_for_select(@cities, 'id', 'name', selected), prompt: t('pages.banner.all_locations'), class: 'show_list_cities' %>
</div>
<div class="search_submit">
<%= f.submit t('pages.banner.btn_text_search'), name: nil, class: 'btn_search_submit'%>
</div>
</div>
<% end %>
</div>
</div>
<div class="box-show-total-jobs-mobile">
<span><%= t('pages.banner.slogan_3', job_count: @job_count) %> </span>
</div>
<!-- Process search mobile-->
<div class="box-search-mobile">
<%= form_for @search, enforce_utf8: false, method: :get do |f| %>
<div class="fillter-search-mobile">
<div class="container">
<div class="row no-gutters">
<div class="col-md-12">
<%= f.search_field :keyword, value: @keyword, class: 'custom_input_mobile_search', placeholder: t('pages.banner.search_placeholder') %>
</div>
<div class="col-sm-6 col-xs-12">
<div class="search_industries_mobile">
<% selected = @industry.blank? ? '*' : @industry.id %>
<%= f.select 'industry_id', options_from_collection_for_select(@industries, 'id', 'name', selected), prompt: t('pages.banner.all_industries'), class: 'show_list_industries_mobile' %>
</div>
</div>
<div class="col-sm-6 col-xs-12">
<div class="search_location_mobile">
<% selected = @city.blank? ? '*' : @city.id %>
<%= f.select 'city_id', options_from_collection_for_select(@cities, 'id', 'name', selected), prompt: t('pages.banner.all_locations'), class: 'show_list_cities_mobile' %>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row no-gutters">
<div class="col-sm-12">
<%= f.submit t('pages.banner.btn_text_search'), name: nil, class: 'btn_search_submit'%>
</div>
</div>
</div>
</div>
<% end %>
</div>
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="box_jobs">
<div class="col-sm-12 d-block d-sm-none">
<div class="link_favorite_top block_link_favorite md">
<%= render 'btn_func_favorite', data: data %>
</div>
</div>
<div class="row">
<div class="col-sm-10 col-md-9 col-lg-10">
<div class="box_info">
<div class="lol">
<%= link_to data['name'], detail_job_path(id: data['id']), class: 'job_name' %>
</div>
<div class="cop">
<h5 class="box_info_copany_name"><i class="far fa-building"></i> <%= data['company_name'] %></h5>
</div>
<div class="loc">
<h5 class="box_info_location"><i class="fas fa-map-marker-alt"></i>
<%= data['locations'].join(' | ') %>
</h5>
</div>
<h5 class="box_info_salary"><i class="fas fa-dollar-sign"></i>&nbsp;<%= "#{t('pages.index.salary')}: #{data['salary']}" %></h5>
<div class="coc">
<h5 class="box_info_des"><%= strip_tags(data['description']) %></h5>
</div>
</div>
</div>
<div class="col-sm-2 col-md-3 d-none d-sm-block col-lg-2">
<div class="link_favorite_top block_link_favorite">
<%= render 'btn_func_favorite', data: data %>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<% if user_signed_in? %>
<% favorite_id = current_user.favorites.find_by(job_id: data['id']) %>
<% if favorite_id.present? %>
<%= render 'job/link_destroy', favorite_id: favorite_id %>
<% else %>
<%= render 'job/link_create', job_id: data['id'] %>
<% end %>
<% else %>
<span class="link_favorite span_click_favorite"><i class="far fa-heart"></i></span>
<% end %>
<div class="col-lg-12">
<div class="breadcrumb_total_search_pagination_jobs">
<div class="pagination_jobs">
<div id="paginator">
<%= paginate results %>
</div>
</div>
</div>
</div>
\ No newline at end of file
<% provide(:title ,"#{t('pages.detail.br_title')}") %>
<%= render 'search/banner_and_search' %>
<div class="padding_index"></div>
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="breadcrumb_total_search">
<span class="breadcrumb-item active">
<% if @results.total_count == Job.count %>
<div style="word-wrap: break-word;">
<%= "#{t('pages.result.all')} #{@results.total_count}" %>
</div>
<% elsif @results.total_count.positive? %>
<%= t('pages.result.result_find', job: @results.total_count, key: @keyword).html_safe %>
<% else %>
<%= t('pages.result.no_result_find', key: @keyword).html_safe %>
<% end %>
<b><%= "#{@industry.try(:name)} #{@city.try(:name)}" %></b>
</span>
</div>
</div>
<%= render 'paginate', results: @results %>
</div>
</div>
<%= render 'job/modal_login' %>
<%= render partial: 'block_info_job', collection: @results, as: :data %>
<div class="container">
<div class="row">
<%= render 'paginate', results: @results %>
</div>
</div>
<%= render 'shared/scroll_top' %>
......@@ -11,13 +11,13 @@ module Venjob
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.2
config.exceptions_app = self.routes
config.autoload_paths << Rails.root.join('lib/service')
config.autoload_paths << Rails.root.join('lib/src')
config.eager_load_paths << Rails.root.join('lib/business')
config.autoload_paths += Dir[Rails.root.join('lib', '{service,src}')]
config.eager_load_paths += Dir[Rails.root.join('lib', '{business,solr,user}')]
# i18n
config.i18n.available_locales = [:en, :vi]
config.i18n.default_locale = :vi
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading
......
# config valid for current version and patch releases of Capistrano
lock "~> 3.14.1"
set :application, "my_app_name"
set :repo_url, "git@example.com:me/my_repo.git"
# Default branch is :master
# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp
# Default deploy_to directory is /var/www/my_app_name
# set :deploy_to, "/var/www/my_app_name"
# Default value for :format is :airbrussh.
# set :format, :airbrussh
# You can configure the Airbrussh format using :format_options.
# These are the defaults.
# set :format_options, command_output: true, log_file: "log/capistrano.log", color: :auto, truncate: :auto
# Default value for :pty is false
# set :pty, true
# Default value for :linked_files is []
# append :linked_files, "config/database.yml"
# Default value for linked_dirs is []
# append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system"
# Default value for default_env is {}
# set :default_env, { path: "/opt/ruby/bin:$PATH" }
# Default value for local_user is ENV['USER']
# set :local_user, -> { `git config user.name`.chomp }
# Default value for keep_releases is 5
# set :keep_releases, 5
# Uncomment the following to require manually verifying the host key before first deploy.
# set :ssh_options, verify_host_key: :secure
# config valid only for current version of Capistrano
lock "3.14.1"
set :application, "venjob"
set :repo_url, "git@gitlab.zigexn.vn:hungnt/venjob_nth.git"
set :log_level, :debug
# server-based syntax
# ======================
# Defines a single server with a list of roles and multiple properties.
# You can define all roles on a single server, or split them:
# server "example.com", user: "deploy", roles: %w{app db web}, my_property: :my_value
# server "example.com", user: "deploy", roles: %w{app web}, other_property: :other_value
# server "db.example.com", user: "deploy", roles: %w{db}
# role-based syntax
# ==================
# Defines a role with one or multiple servers. The primary server in each
# group is considered to be the first unless any hosts have the primary
# property set. Specify the username and a domain or IP for the server.
# Don't use `:all`, it's a meta role.
# role :app, %w{deploy@example.com}, my_property: :my_value
# role :web, %w{user1@primary.com user2@additional.com}, other_property: :other_value
# role :db, %w{deploy@example.com}
# Configuration
# =============
# You can set any configuration variable like in config/deploy.rb
# These variables are then only loaded and set in this stage.
# For available Capistrano configuration variables see the documentation page.
# http://capistranorb.com/documentation/getting-started/configuration/
# Feel free to add new variables to customise your setup.
# Custom SSH Options
# ==================
# You may pass any option but keep in mind that net/ssh understands a
# limited set of options, consult the Net::SSH documentation.
# http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start
#
# Global options
# --------------
# set :ssh_options, {
# keys: %w(/home/user_name/.ssh/id_rsa),
# forward_agent: false,
# auth_methods: %w(password)
# }
#
# The server-based syntax can be used to override options:
# ------------------------------------
# server "example.com",
# user: "user_name",
# roles: %w{web app},
# ssh_options: {
# user: "user_name", # overrides user setting above
# keys: %w(/home/user_name/.ssh/id_rsa),
# forward_agent: false,
# auth_methods: %w(publickey password)
# # password: "please use keys"
# }
# server-based syntax
# ======================
# Defines a single server with a list of roles and multiple properties.
# You can define all roles on a single server, or split them:
# server "example.com", user: "deploy", roles: %w{app db web}, my_property: :my_value
# server "example.com", user: "deploy", roles: %w{app web}, other_property: :other_value
# server "db.example.com", user: "deploy", roles: %w{db}
# role-based syntax
# ==================
# Defines a role with one or multiple servers. The primary server in each
# group is considered to be the first unless any hosts have the primary
# property set. Specify the username and a domain or IP for the server.
# Don't use `:all`, it's a meta role.
# role :app, %w{deploy@example.com}, my_property: :my_value
# role :web, %w{user1@primary.com user2@additional.com}, other_property: :other_value
# role :db, %w{deploy@example.com}
# Configuration
# =============
# You can set any configuration variable like in config/deploy.rb
# These variables are then only loaded and set in this stage.
# For available Capistrano configuration variables see the documentation page.
# http://capistranorb.com/documentation/getting-started/configuration/
# Feel free to add new variables to customise your setup.
# Custom SSH Options
# ==================
# You may pass any option but keep in mind that net/ssh understands a
# limited set of options, consult the Net::SSH documentation.
# http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start
#
# Global options
# --------------
set :ssh_options, {
keys: %w(/home/hungnt/.ssh/id_rsa),
forward_agent: false,
auth_methods: %w(password)
}
#
# The server-based syntax can be used to override options:
# ------------------------------------
# server "example.com",
# user: "user_name",
# roles: %w{web app},
# ssh_options: {
# user: "user_name", # overrides user setting above
# keys: %w(/home/user_name/.ssh/id_rsa),
# forward_agent: false,
# auth_methods: %w(publickey password)
# # password: "please use keys"
# }
# for staging
set :user, "root"
set :application, "venjob"
set :repository, "git@gitlab.zigexn.vn:hungnt/venjob_nth.git"
set :rails_env, "staging"
set :branch, 'master'
set :default_run_options, :pty => true
set :rbenv_path, "/home/#{fetch(:user)}/.rbenv"
# target servers
# web0103
role :web, "#{fetch(:user)}@192.168.1.139" # Your HTTP server, Apache/etc
role :app, "#{fetch(:user)}@192.168.1.139" # This may be the same as your `Web` server
#role :db, "10.1.173.15", :primary => true # This is where Rails migrations will run
set :use_sudo, false
set :deploy_to, "/var/www/#{fetch(:application)}"
Config.setup do |config|
# Name of the constant exposing loaded settings
config.const_name = 'Settings'
# Ability to remove elements of the array set in earlier loaded settings file. For example value: '--'.
#
# config.knockout_prefix = nil
# Overwrite an existing value when merging a `nil` value.
# When set to `false`, the existing value is retained after merge.
#
# config.merge_nil_values = true
# Overwrite arrays found in previously loaded settings file. When set to `false`, arrays will be merged.
#
# config.overwrite_arrays = true
# Load environment variables from the `ENV` object and override any settings defined in files.
#
# config.use_env = false
# Define ENV variable prefix deciding which variables to load into config.
#
# Reading variables from ENV is case-sensitive. If you define lowercase value below, ensure your ENV variables are
# prefixed in the same way.
#
# When not set it defaults to `config.const_name`.
#
config.env_prefix = 'SETTINGS'
# What string to use as level separator for settings loaded from ENV variables. Default value of '.' works well
# with Heroku, but you might want to change it for example for '__' to easy override settings from command line, where
# using dots in variable names might not be allowed (eg. Bash).
#
# config.env_separator = '.'
# Ability to process variables names:
# * nil - no change
# * :downcase - convert to lower case
#
# config.env_converter = :downcase
# Parse numeric values as integers instead of strings.
#
# config.env_parse_values = true
# Validate presence and type of specific config values. Check https://github.com/dry-rb/dry-validation for details.
#
# config.schema do
# required(:name).filled
# required(:age).maybe(:int?)
# required(:email).filled(format?: EMAIL_REGEX)
# end
end
......@@ -3,7 +3,7 @@
Kaminari.configure do |config|
config.default_per_page = 20
# config.max_per_page = nil
config.window = 3
config.window = 2
# config.outer_window = 0
# config.left = 0
# config.right = 0
......
......@@ -34,15 +34,16 @@ en:
slogan: 'VENJOB HUMAN RESOURCE PLATFORM'
slogan_2: 'Instantly discover the best jobs on VenJob'
slogan_3: 'Instantly discover %{job_count} the best jobs on VenJob'
search_placeholder: 'Input title, companies, locations...'
search_placeholder: 'Input title, companies,...'
btn_text_search: 'Find Job'
all_industries: 'All industries'
all_locations: 'All locations'
confirm:
modal_login: 'PLEASE SIGN IN TO EXECUTE THIS FUNCTION'
result:
result_find: 'There are <b>%{job}</b> results matching keyword <b>%{key}</b>'
no_result_find: 'No results match the keyword <b>%{key}</b>'
result_find: 'There are &nbsp;<b>%{job}</b>&nbsp; results matching keyword &nbsp;<b>%{key}</b>&nbsp;'
no_result_find: 'No results match the keyword &nbsp;<b>%{key}</b>&nbsp;'
all: 'All Job'
detail:
br_title: 'Result'
btr_text_submit_cv: 'Apply Now'
......@@ -51,6 +52,7 @@ en:
expiration_date: ' Expiration date'
experience: ' Experience'
level: ' Level'
industry: ' Industry:'
cities:
ask: 'Do you want to find a job at Viet Nam or oversea?'
domestic: 'Viet Nam'
......@@ -166,4 +168,8 @@ en:
name: 'Name candidate'
email: 'Email'
cv: 'CV Path'
created_at: 'Applied at'
\ No newline at end of file
created_at: 'Applied at'
views:
pagination:
last: 'Last'
first: 'First'
......@@ -34,15 +34,16 @@ vi:
slogan: 'NỀN TẢNG TUYỂN DỤNG NHÂN SỰ VENJOB'
slogan_2: 'Khám phá ngay những việc làm tốt nhất trên VenJob'
slogan_3: "Khám phá ngay %{job_count} việc làm tốt nhất trên VenJob"
search_placeholder: 'Nhập tiêu đề, công ty, địa điểm...'
search_placeholder: 'Nhập tiêu đề, công ty,...'
btn_text_search: 'Tìm việc'
all_industries: 'Tất cả nghành nghề'
all_locations: 'Tất cả đỉa điểm'
confirm:
modal_login: 'VUI LÒNG ĐĂNG NHẬP ĐỂ THỰC HIỆN CHỨC NĂNG NÀY'
result:
result_find: ' <b>%{job}</b> kết quả phù hợp với từ khóa <b>%{key}</b>'
no_result_find: 'Không kết quả phù hợp với từ khóa <b>%{key}</b>'
result_find: ' &nbsp;<b>%{job}</b>&nbsp; kết quả phù hợp với từ khóa &nbsp;<b>%{key}</b>&nbsp;'
no_result_find: 'Không kết quả phù hợp với từ khóa &nbsp;<b>%{key}</b>&nbsp;'
all: 'Tất cả công việc hiện tại'
detail:
br_title: 'Kết quả tìm kiếm'
btr_text_submit_cv: 'Nộp CV ngay'
......@@ -51,6 +52,7 @@ vi:
expiration_date: ' Ngày hết hạn'
experience: ' Kinh nghiệm'
level: ' Cấp bậc'
industry: ' Ngành nghề:'
cities:
ask: 'Bạn muốn tìm việc trong hay ngoài nước?'
domestic: 'Việt Nam'
......@@ -167,4 +169,7 @@ vi:
email: 'Email'
cv: 'Đường dẫn tệp cv'
created_at: 'Ứng tuyển vào'
\ No newline at end of file
views:
pagination:
last: 'Cuối'
first: 'Đầu'
......@@ -12,7 +12,11 @@ Rails.application.routes.draw do
get 'admin', to: 'admin/admin#routing', as: :admin
get 'info/user/:user_id', to: 'users#personal_page', as: :personal_page
devise_for :users, controllers: { registrations: 'registrations', passwords: 'passwords'}
root 'home#index'
# Search
get 'search', to: 'search#search', as: :searches
get 'register/:code', to: 'users#confirm_sign_up', as: :confirm_sign_up
get 'industries', to: 'industry#index', as: :industry_index
get 'cities', to: 'city#index', as: :city_index
......
number_result_search_in_page: 10
url_server_solr: 'http://localhost:8983/solr/venjob'
url_server_solr: 'http://.../solr/venjob'
<dataConfig>
<dataSource type="JdbcDataSource"
driver="com.mysql.jdbc.Driver"
batchSize="-1"
url="jdbc:mysql://127.0.0.1:3306/hungnt_development"
user="root"
password="Trunghung5055@"/>
<document>
<entity name="jobs"
pk="id"
query="SELECT jobs.*, companies.name AS company_name FROM jobs, companies WHERE jobs.company_id = companies.id">
<field column="id" name="id"/>
<field column="name" name="name"/>
<field column="company_name" name="company_name"/>
<field column="salary" name="salary"/>
<field column="description" name="description"/>
<!-- QUERY INDUSTRIES -->
<entity name="industries"
query="SELECT industries.id AS industry_id, industries.name AS industry_name FROM industries, industry_jobs, jobs WHERE jobs.id = industry_jobs.job_id AND industry_jobs.industry_id = industries.id AND jobs.id='${jobs.id}'">
<field column="industry_name" name="industries" />
<field column="industry_id" name="industry_id" />
</entity>
<!-- QUERY CITIES -->
<entity name="cities"
query="SELECT cities.id AS location_id, cities.name AS location_name FROM cities, city_jobs, jobs WHERE jobs.id = city_jobs.job_id AND city_jobs.city_id = cities.id AND jobs.id='${jobs.id}'">
<field column="location_name" name="locations" />
<field column="location_id" name="location_id" />
</entity>
</entity>
</document>
</dataConfig>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Solr managed schema - automatically generated - DO NOT EDIT -->
<schema name="default-config" version="1.6">
<uniqueKey>id</uniqueKey>
<fieldType name="_nest_path_" class="solr.NestPathField" maxCharsForDocValues="-1" omitNorms="true" omitTermFreqAndPositions="true" stored="false"/>
<fieldType name="ancestor_path" class="solr.TextField">
<analyzer type="index">
<tokenizer class="solr.KeywordTokenizerFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.PathHierarchyTokenizerFactory" delimiter="/"/>
</analyzer>
</fieldType>
<fieldType name="binary" class="solr.BinaryField"/>
<fieldType name="boolean" class="solr.BoolField" sortMissingLast="true"/>
<fieldType name="booleans" class="solr.BoolField" sortMissingLast="true" multiValued="true"/>
<fieldType name="delimited_payloads_float" class="solr.TextField" indexed="true" stored="false">
<analyzer>
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.DelimitedPayloadTokenFilterFactory" encoder="float"/>
</analyzer>
</fieldType>
<fieldType name="delimited_payloads_int" class="solr.TextField" indexed="true" stored="false">
<analyzer>
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.DelimitedPayloadTokenFilterFactory" encoder="integer"/>
</analyzer>
</fieldType>
<fieldType name="delimited_payloads_string" class="solr.TextField" indexed="true" stored="false">
<analyzer>
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.DelimitedPayloadTokenFilterFactory" encoder="identity"/>
</analyzer>
</fieldType>
<fieldType name="descendent_path" class="solr.TextField">
<analyzer type="index">
<tokenizer class="solr.PathHierarchyTokenizerFactory" delimiter="/"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.KeywordTokenizerFactory"/>
</analyzer>
</fieldType>
<fieldType name="ignored" class="solr.StrField" indexed="false" stored="false" multiValued="true"/>
<fieldType name="location" class="solr.LatLonPointSpatialField" docValues="true"/>
<fieldType name="location_rpt" class="solr.SpatialRecursivePrefixTreeFieldType" geo="true" maxDistErr="0.001" distErrPct="0.025" distanceUnits="kilometers"/>
<fieldType name="lowercase" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="pdate" class="solr.DatePointField" docValues="true"/>
<fieldType name="pdates" class="solr.DatePointField" docValues="true" multiValued="true"/>
<fieldType name="pdouble" class="solr.DoublePointField" docValues="true"/>
<fieldType name="pdoubles" class="solr.DoublePointField" docValues="true" multiValued="true"/>
<fieldType name="pfloat" class="solr.FloatPointField" docValues="true"/>
<fieldType name="pfloats" class="solr.FloatPointField" docValues="true" multiValued="true"/>
<fieldType name="phonetic_en" class="solr.TextField" indexed="true" stored="false">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.DoubleMetaphoneFilterFactory" inject="false"/>
</analyzer>
</fieldType>
<fieldType name="pint" class="solr.IntPointField" docValues="true"/>
<fieldType name="pints" class="solr.IntPointField" docValues="true" multiValued="true"/>
<fieldType name="plong" class="solr.LongPointField" docValues="true"/>
<fieldType name="plongs" class="solr.LongPointField" docValues="true" multiValued="true"/>
<fieldType name="point" class="solr.PointType" subFieldSuffix="_d" dimension="2"/>
<fieldType name="random" class="solr.RandomSortField" indexed="true"/>
<fieldType name="rank" class="solr.RankField"/>
<fieldType name="string" class="solr.StrField" sortMissingLast="true" docValues="true"/>
<fieldType name="strings" class="solr.StrField" sortMissingLast="true" docValues="true" multiValued="true"/>
<fieldType name="text_ar" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_ar.txt" ignoreCase="true"/>
<filter class="solr.ArabicNormalizationFilterFactory"/>
<filter class="solr.ArabicStemFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_bg" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_bg.txt" ignoreCase="true"/>
<filter class="solr.BulgarianStemFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_ca" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.ElisionFilterFactory" articles="lang/contractions_ca.txt" ignoreCase="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_ca.txt" ignoreCase="true"/>
<filter class="solr.SnowballPorterFilterFactory" language="Catalan"/>
</analyzer>
</fieldType>
<fieldType name="text_cjk" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.CJKWidthFilterFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.CJKBigramFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_cz" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_cz.txt" ignoreCase="true"/>
<filter class="solr.CzechStemFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_da" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" format="snowball" words="lang/stopwords_da.txt" ignoreCase="true"/>
<filter class="solr.SnowballPorterFilterFactory" language="Danish"/>
</analyzer>
</fieldType>
<fieldType name="text_de" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" format="snowball" words="lang/stopwords_de.txt" ignoreCase="true"/>
<filter class="solr.GermanNormalizationFilterFactory"/>
<filter class="solr.GermanLightStemFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_el" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.GreekLowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_el.txt" ignoreCase="false"/>
<filter class="solr.GreekStemFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_en" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_en.txt" ignoreCase="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EnglishPossessiveFilterFactory"/>
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
<filter class="solr.PorterStemFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.SynonymGraphFilterFactory" expand="true" ignoreCase="true" synonyms="synonyms.txt"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_en.txt" ignoreCase="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EnglishPossessiveFilterFactory"/>
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
<filter class="solr.PorterStemFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_en_splitting" class="solr.TextField" autoGeneratePhraseQueries="true" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_en.txt" ignoreCase="true"/>
<filter class="solr.WordDelimiterGraphFilterFactory" catenateNumbers="1" generateNumberParts="1" splitOnCaseChange="1" generateWordParts="1" catenateAll="0" catenateWords="1"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
<filter class="solr.PorterStemFilterFactory"/>
<filter class="solr.FlattenGraphFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.SynonymGraphFilterFactory" expand="true" ignoreCase="true" synonyms="synonyms.txt"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_en.txt" ignoreCase="true"/>
<filter class="solr.WordDelimiterGraphFilterFactory" catenateNumbers="0" generateNumberParts="1" splitOnCaseChange="1" generateWordParts="1" catenateAll="0" catenateWords="0"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
<filter class="solr.PorterStemFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_en_splitting_tight" class="solr.TextField" autoGeneratePhraseQueries="true" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.SynonymGraphFilterFactory" expand="false" ignoreCase="true" synonyms="synonyms.txt"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_en.txt" ignoreCase="true"/>
<filter class="solr.WordDelimiterGraphFilterFactory" catenateNumbers="1" generateNumberParts="0" generateWordParts="0" catenateAll="0" catenateWords="1"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
<filter class="solr.EnglishMinimalStemFilterFactory"/>
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
<filter class="solr.FlattenGraphFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.SynonymGraphFilterFactory" expand="false" ignoreCase="true" synonyms="synonyms.txt"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_en.txt" ignoreCase="true"/>
<filter class="solr.WordDelimiterGraphFilterFactory" catenateNumbers="1" generateNumberParts="0" generateWordParts="0" catenateAll="0" catenateWords="1"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
<filter class="solr.EnglishMinimalStemFilterFactory"/>
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_es" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" format="snowball" words="lang/stopwords_es.txt" ignoreCase="true"/>
<filter class="solr.SpanishLightStemFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_et" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_et.txt" ignoreCase="true"/>
<filter class="solr.SnowballPorterFilterFactory" language="Estonian"/>
</analyzer>
</fieldType>
<fieldType name="text_eu" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_eu.txt" ignoreCase="true"/>
<filter class="solr.SnowballPorterFilterFactory" language="Basque"/>
</analyzer>
</fieldType>
<fieldType name="text_fa" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<charFilter class="solr.PersianCharFilterFactory"/>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.ArabicNormalizationFilterFactory"/>
<filter class="solr.PersianNormalizationFilterFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_fa.txt" ignoreCase="true"/>
</analyzer>
</fieldType>
<fieldType name="text_fi" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" format="snowball" words="lang/stopwords_fi.txt" ignoreCase="true"/>
<filter class="solr.SnowballPorterFilterFactory" language="Finnish"/>
</analyzer>
</fieldType>
<fieldType name="text_fr" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.ElisionFilterFactory" articles="lang/contractions_fr.txt" ignoreCase="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" format="snowball" words="lang/stopwords_fr.txt" ignoreCase="true"/>
<filter class="solr.FrenchLightStemFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_ga" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.ElisionFilterFactory" articles="lang/contractions_ga.txt" ignoreCase="true"/>
<filter class="solr.StopFilterFactory" words="lang/hyphenations_ga.txt" ignoreCase="true"/>
<filter class="solr.IrishLowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_ga.txt" ignoreCase="true"/>
<filter class="solr.SnowballPorterFilterFactory" language="Irish"/>
</analyzer>
</fieldType>
<fieldType name="text_gen_sort" class="solr.SortableTextField" positionIncrementGap="100" multiValued="true">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" words="stopwords.txt" ignoreCase="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" words="stopwords.txt" ignoreCase="true"/>
<filter class="solr.SynonymGraphFilterFactory" expand="true" ignoreCase="true" synonyms="synonyms.txt"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100" multiValued="true">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" words="stopwords.txt" ignoreCase="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" words="stopwords.txt" ignoreCase="true"/>
<filter class="solr.SynonymGraphFilterFactory" expand="true" ignoreCase="true" synonyms="synonyms.txt"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_general_rev" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" words="stopwords.txt" ignoreCase="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.ReversedWildcardFilterFactory" maxPosQuestion="2" maxFractionAsterisk="0.33" maxPosAsterisk="3" withOriginal="true"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.SynonymGraphFilterFactory" expand="true" ignoreCase="true" synonyms="synonyms.txt"/>
<filter class="solr.StopFilterFactory" words="stopwords.txt" ignoreCase="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_gl" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_gl.txt" ignoreCase="true"/>
<filter class="solr.GalicianStemFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_hi" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.IndicNormalizationFilterFactory"/>
<filter class="solr.HindiNormalizationFilterFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_hi.txt" ignoreCase="true"/>
<filter class="solr.HindiStemFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_hu" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" format="snowball" words="lang/stopwords_hu.txt" ignoreCase="true"/>
<filter class="solr.SnowballPorterFilterFactory" language="Hungarian"/>
</analyzer>
</fieldType>
<fieldType name="text_hy" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_hy.txt" ignoreCase="true"/>
<filter class="solr.SnowballPorterFilterFactory" language="Armenian"/>
</analyzer>
</fieldType>
<fieldType name="text_id" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_id.txt" ignoreCase="true"/>
<filter class="solr.IndonesianStemFilterFactory" stemDerivational="true"/>
</analyzer>
</fieldType>
<fieldType name="text_it" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.ElisionFilterFactory" articles="lang/contractions_it.txt" ignoreCase="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" format="snowball" words="lang/stopwords_it.txt" ignoreCase="true"/>
<filter class="solr.ItalianLightStemFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_ja" class="solr.TextField" autoGeneratePhraseQueries="false" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.JapaneseTokenizerFactory" mode="search"/>
<filter class="solr.JapaneseBaseFormFilterFactory"/>
<filter class="solr.JapanesePartOfSpeechStopFilterFactory" tags="lang/stoptags_ja.txt"/>
<filter class="solr.CJKWidthFilterFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_ja.txt" ignoreCase="true"/>
<filter class="solr.JapaneseKatakanaStemFilterFactory" minimumLength="4"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_ko" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.KoreanTokenizerFactory" outputUnknownUnigrams="false" decompoundMode="discard"/>
<filter class="solr.KoreanPartOfSpeechStopFilterFactory"/>
<filter class="solr.KoreanReadingFormFilterFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_lv" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_lv.txt" ignoreCase="true"/>
<filter class="solr.LatvianStemFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_nl" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" format="snowball" words="lang/stopwords_nl.txt" ignoreCase="true"/>
<filter class="solr.StemmerOverrideFilterFactory" dictionary="lang/stemdict_nl.txt" ignoreCase="false"/>
<filter class="solr.SnowballPorterFilterFactory" language="Dutch"/>
</analyzer>
</fieldType>
<fieldType name="text_no" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" format="snowball" words="lang/stopwords_no.txt" ignoreCase="true"/>
<filter class="solr.SnowballPorterFilterFactory" language="Norwegian"/>
</analyzer>
</fieldType>
<fieldType name="text_pt" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" format="snowball" words="lang/stopwords_pt.txt" ignoreCase="true"/>
<filter class="solr.PortugueseLightStemFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="text_ro" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_ro.txt" ignoreCase="true"/>
<filter class="solr.SnowballPorterFilterFactory" language="Romanian"/>
</analyzer>
</fieldType>
<fieldType name="text_ru" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" format="snowball" words="lang/stopwords_ru.txt" ignoreCase="true"/>
<filter class="solr.SnowballPorterFilterFactory" language="Russian"/>
</analyzer>
</fieldType>
<fieldType name="text_sv" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" format="snowball" words="lang/stopwords_sv.txt" ignoreCase="true"/>
<filter class="solr.SnowballPorterFilterFactory" language="Swedish"/>
</analyzer>
</fieldType>
<fieldType name="text_th" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.ThaiTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_th.txt" ignoreCase="true"/>
</analyzer>
</fieldType>
<fieldType name="text_tr" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.TurkishLowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory" words="lang/stopwords_tr.txt" ignoreCase="false"/>
<filter class="solr.SnowballPorterFilterFactory" language="Turkish"/>
</analyzer>
</fieldType>
<fieldType name="text_vi" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.WordDelimiterFilterFactory" catenateNumbers="0" generateNumberParts="1" splitOnCaseChange="1" generateWordParts="1" catenateAll="0" catenateWords="1"/>
<filter class="solr.PorterStemFilterFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.ASCIIFoldingFilterFactory" preserveOriginal="true"/>
<filter class="solr.SnowballPorterFilterFactory" language="English" protected="protwords.txt"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.WordDelimiterFilterFactory" catenateNumbers="0" generateNumberParts="1" splitOnCaseChange="1" generateWordParts="1" catenateAll="0" catenateWords="1"/>
<filter class="solr.PorterStemFilterFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.ASCIIFoldingFilterFactory" preserveOriginal="true"/>
<filter class="solr.SnowballPorterFilterFactory" language="English" protected="protwords.txt"/>
<filter class="solr.SynonymFilterFactory" expand="true" ignoreCase="true" synonyms="synonyms.txt"/>
</analyzer>
</fieldType>
<fieldType name="text_ws" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
</analyzer>
</fieldType>
<field name="_nest_path_" type="_nest_path_"/>
<field name="_root_" type="string" docValues="false" indexed="true" stored="false"/>
<field name="_text_" type="text_general" multiValued="true" indexed="true" stored="false"/>
<field name="_version_" type="plong" indexed="false" stored="false"/>
<field name="company_name" type="text_vi" uninvertible="false" indexed="true" stored="true"/>
<field name="description" type="string" uninvertible="false" indexed="false" stored="true"/>
<field name="id" type="string" multiValued="false" indexed="true" required="true" stored="true"/>
<field name="industries" type="text_vi" uninvertible="false" multiValued="true" indexed="true" stored="true"/>
<field name="industry_id" type="strings" uninvertible="false" docValues="false" multiValued="true" indexed="true" stored="true"/>
<field name="location_id" type="strings" uninvertible="false" multiValued="true" indexed="true" stored="true"/>
<field name="locations" type="text_vi" uninvertible="false" multiValued="true" indexed="true" stored="true"/>
<field name="name" type="text_vi" uninvertible="false" indexed="true" stored="true" termVectors="true"/>
<field name="salary" type="string" uninvertible="false" indexed="false" stored="true"/>
<dynamicField name="*_txt_en_split_tight" type="text_en_splitting_tight" indexed="true" stored="true"/>
<dynamicField name="*_descendent_path" type="descendent_path" indexed="true" stored="true"/>
<dynamicField name="*_ancestor_path" type="ancestor_path" indexed="true" stored="true"/>
<dynamicField name="*_txt_en_split" type="text_en_splitting" indexed="true" stored="true"/>
<dynamicField name="*_txt_sort" type="text_gen_sort" indexed="true" stored="true"/>
<dynamicField name="ignored_*" type="ignored"/>
<dynamicField name="*_txt_rev" type="text_general_rev" indexed="true" stored="true"/>
<dynamicField name="*_phon_en" type="phonetic_en" indexed="true" stored="true"/>
<dynamicField name="*_s_lower" type="lowercase" indexed="true" stored="true"/>
<dynamicField name="*_txt_cjk" type="text_cjk" indexed="true" stored="true"/>
<dynamicField name="random_*" type="random"/>
<dynamicField name="*_t_sort" type="text_gen_sort" multiValued="false" indexed="true" stored="true"/>
<dynamicField name="*_txt_en" type="text_en" indexed="true" stored="true"/>
<dynamicField name="*_txt_ar" type="text_ar" indexed="true" stored="true"/>
<dynamicField name="*_txt_bg" type="text_bg" indexed="true" stored="true"/>
<dynamicField name="*_txt_ca" type="text_ca" indexed="true" stored="true"/>
<dynamicField name="*_txt_cz" type="text_cz" indexed="true" stored="true"/>
<dynamicField name="*_txt_da" type="text_da" indexed="true" stored="true"/>
<dynamicField name="*_txt_de" type="text_de" indexed="true" stored="true"/>
<dynamicField name="*_txt_el" type="text_el" indexed="true" stored="true"/>
<dynamicField name="*_txt_es" type="text_es" indexed="true" stored="true"/>
<dynamicField name="*_txt_et" type="text_et" indexed="true" stored="true"/>
<dynamicField name="*_txt_eu" type="text_eu" indexed="true" stored="true"/>
<dynamicField name="*_txt_fa" type="text_fa" indexed="true" stored="true"/>
<dynamicField name="*_txt_fi" type="text_fi" indexed="true" stored="true"/>
<dynamicField name="*_txt_fr" type="text_fr" indexed="true" stored="true"/>
<dynamicField name="*_txt_ga" type="text_ga" indexed="true" stored="true"/>
<dynamicField name="*_txt_gl" type="text_gl" indexed="true" stored="true"/>
<dynamicField name="*_txt_hi" type="text_hi" indexed="true" stored="true"/>
<dynamicField name="*_txt_hu" type="text_hu" indexed="true" stored="true"/>
<dynamicField name="*_txt_hy" type="text_hy" indexed="true" stored="true"/>
<dynamicField name="*_txt_id" type="text_id" indexed="true" stored="true"/>
<dynamicField name="*_txt_it" type="text_it" indexed="true" stored="true"/>
<dynamicField name="*_txt_ja" type="text_ja" indexed="true" stored="true"/>
<dynamicField name="*_txt_ko" type="text_ko" indexed="true" stored="true"/>
<dynamicField name="*_txt_lv" type="text_lv" indexed="true" stored="true"/>
<dynamicField name="*_txt_nl" type="text_nl" indexed="true" stored="true"/>
<dynamicField name="*_txt_no" type="text_no" indexed="true" stored="true"/>
<dynamicField name="*_txt_pt" type="text_pt" indexed="true" stored="true"/>
<dynamicField name="*_txt_ro" type="text_ro" indexed="true" stored="true"/>
<dynamicField name="*_txt_ru" type="text_ru" indexed="true" stored="true"/>
<dynamicField name="*_txt_sv" type="text_sv" indexed="true" stored="true"/>
<dynamicField name="*_txt_th" type="text_th" indexed="true" stored="true"/>
<dynamicField name="*_txt_tr" type="text_tr" indexed="true" stored="true"/>
<dynamicField name="*_point" type="point" indexed="true" stored="true"/>
<dynamicField name="*_srpt" type="location_rpt" indexed="true" stored="true"/>
<dynamicField name="attr_*" type="text_general" multiValued="true" indexed="true" stored="true"/>
<dynamicField name="*_txt" type="text_general" indexed="true" stored="true"/>
<dynamicField name="*_str" type="strings" docValues="true" indexed="false" stored="false" useDocValuesAsStored="false"/>
<dynamicField name="*_dts" type="pdate" multiValued="true" indexed="true" stored="true"/>
<dynamicField name="*_dpf" type="delimited_payloads_float" indexed="true" stored="true"/>
<dynamicField name="*_dpi" type="delimited_payloads_int" indexed="true" stored="true"/>
<dynamicField name="*_dps" type="delimited_payloads_string" indexed="true" stored="true"/>
<dynamicField name="*_is" type="pints" indexed="true" stored="true"/>
<dynamicField name="*_ss" type="strings" indexed="true" stored="true"/>
<dynamicField name="*_ls" type="plongs" indexed="true" stored="true"/>
<dynamicField name="*_bs" type="booleans" indexed="true" stored="true"/>
<dynamicField name="*_fs" type="pfloats" indexed="true" stored="true"/>
<dynamicField name="*_ds" type="pdoubles" indexed="true" stored="true"/>
<dynamicField name="*_dt" type="pdate" indexed="true" stored="true"/>
<dynamicField name="*_ws" type="text_ws" indexed="true" stored="true"/>
<dynamicField name="*_i" type="pint" indexed="true" stored="true"/>
<dynamicField name="*_s" type="string" indexed="true" stored="true"/>
<dynamicField name="*_l" type="plong" indexed="true" stored="true"/>
<dynamicField name="*_t" type="text_general" multiValued="false" indexed="true" stored="true"/>
<dynamicField name="*_b" type="boolean" indexed="true" stored="true"/>
<dynamicField name="*_f" type="pfloat" indexed="true" stored="true"/>
<dynamicField name="*_d" type="pdouble" indexed="true" stored="true"/>
<dynamicField name="*_p" type="location" indexed="true" stored="true"/>
</schema>
\ No newline at end of file
......@@ -43,13 +43,17 @@ class ImportData
industry_name = val['category'].gsub(',', '/').gsub('/', ' / ')
industry = Industry.find_or_create_by(name: industry_name.strip)
Job.find_or_create_by(name: val['name'], company_id: company_id) do |job|
record = Job.find_or_initialize_by(name: val['name'], company_id: company_id) do |job|
job.level = val['level']
job.salary = val['salary']
job.description = desc
job.city_ids.blank? ? job.cities << city : job.cities == city
job.industry_ids.blank? ? job.industries << industry : job.industries == industry
end
if record.new_record?
record.save
IndexedJob.new(job).do
end
rescue StandardError => e
logger.error "Import_jobs: #{e}"
end
......
module Searches
class Query
def search(params)
solr = connect_solr
# Escape input & Convert space to asterisks
data = sub_space_params!(params[:search][:keyword], params[:search][:industry_id], params[:search][:city_id])
query = if [params[:search][:keyword], params[:search][:industry_id], params[:search][:city_id]].all?(&:blank?)
'*:*'
else
"#{data[:keyword]} AND (industry_id: #{data[:industry_id]}) AND (location_id: #{data[:location_id]})"
end
response = solr.paginate(params[:page], Settings.number_result_search_in_page, 'select', params: { q: query })
Kaminari.paginate_array(response['response']['docs'], total_count: response['response']['numFound']).page(params[:page]).per(Settings.number_result_search_in_page)
end
def sub_space_params!(keyword, industry_id, location_id)
arr_params = {}
industry_id = '' if Industry.find_by_id(industry_id).blank?
location_id = '' if City.find_by_id(location_id).blank?
arr_params[:keyword] = RSolr.solr_escape(keyword.downcase || '')
arr_params[:industry_id] = RSolr.solr_escape(industry_id)
arr_params[:location_id] = RSolr.solr_escape(location_id)
arr_params.each_value { |val| val.sub!('', '*') if val.blank? }
end
private
def connect_solr
SolrSetting::SolrServer.connection
end
end
end
# frozen_string_literal: true
module SolrSetting
class SolrServer
def self.connection
RSolr.connect url: Settings.url_server_solr
end
end
end
# frozen_string_literal: true
module Sync::Entities
class Base
def initialize(entity)
@entity = entity
end
def to_h
raise 'Not implemented error'
end
end
end
# frozen_string_literal: true
module Sync::Entities
class Job < Sync::Entities::Base
def to_h
data = {}
data[:id] = job.id
data[:name] = job.name
data[:company_name] = job.company.name
data[:salary] = job.salary
data[:description] = job.description
data[:industries] = job.industries.pluck(:name)
data[:industry_id] = job.industry_jobs.map(&:industry_id)
data[:locations] = job.cities.pluck(:name)
data[:location_id] = job.city_jobs.map(&:city_id)
data
end
def job
@entity
end
end
end
# frozen_string_literal: true
module Sync
class Indexer
def logger
@logger ||= Logger.new(Rails.root.join('log', 'indexed_data_to_solr.log'))
end
def do(data)
solr = SolrSetting::SolrServer.connection
solr.add data.to_h, add_attributes: { commitWithin: 10 }
rescue StandardError => e
logger.error "Indexed data to Solr have error: #{e}"
end
end
end
......@@ -56,6 +56,8 @@ class CrawlerJob < Crawler
description: data[:description])
create_industry_relation(data[:industry_name], job)
create_city_relation(data[:city_name], job)
# Index data to solr
IndexedJob.new(job).do
rescue StandardError => e
logger.error "Crawler data jobs has error: #{e}"
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