Skip to content

Instantly share code, notes, and snippets.

@LolWalid
Last active October 30, 2017 13:41
Show Gist options
  • Save LolWalid/0031e3942143836fdd5cc50a4032d458 to your computer and use it in GitHub Desktop.
Save LolWalid/0031e3942143836fdd5cc50a4032d458 to your computer and use it in GitHub Desktop.
Elastic Search UserSearch, friends and full name
# Using gem 'elasticsearch-model' and gem 'elasticsearch-rails'
class User < ApplicationRecord
include Elasticsearch::Model
after_commit on: [:create, :update] do
User.import query: -> { where(id: id) }
end
settings index: { number_of_shards: 2, number_of_replicas: 1 }, analysis: {
analyzer: {
custom_analyzer: {
tokenizer: 'standard',
filter: %w(standard lowercase asciifolding)
}
},
normalizer: {
custom_normalizer: {
filter: %w(lowercase asciifolding)
}
}
} do
mappings do
indexes :account_type, type: 'text', fields: { keyword: { type: 'keyword', ignore_above: 256, normalizer: :custom_normalizer } }, analyzer: :custom_analyzer
indexes :firstname, type: 'text', fields: { raw: { type: 'keyword', index: true } }, analyzer: :custom_analyzer
indexes :friends, type: 'long'
indexes :lastname, type: 'text', fields: { raw: { type: 'keyword', index: true } }, analyzer: :custom_analyzer
end
end
def as_indexed_json(options={})
hash = as_json(only: [:account_type, :firstname, :lastname])
hash[:friends] = friends.pluck(:id)
hash
end
end
# See link below to know all possible filters
# https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html
class UserSearch
def initialize(user, string_query)
@user = user
@string_query = string_query
end
def search
es = User.__elasticsearch__
es_client = es.client
es_client.search(index: es.index_name, type: es.document_type, body: body)
end
def body
{
query: {
function_score: {
query: {
bool: {
must: [
query_string_name,
],
must_not: { match: { account_type: 'GUEST' } }
}
},
functions: [
{ weight: 50, filter: { term: { friends: @user.id } }},
{ weight: 10, filter: query_condition_virtual_users }
],
score_mode: 'max',
boost_mode: 'replace'
}
},
sort: ['_score', { 'firstname.raw' => { order: 'asc' } }, { 'lastname.raw' => { order: 'asc' } } ],
stored_fields: ['_source']
}
end
def query_string_name
fields = %w(firstname lastname)
keywords = @string_query.split(' ')
query = if keywords.length > 1
name.split(' ').map{ |a| "*#{a}*"}.join(' AND ')
else
fields << 'login'
"*#{name}*"
end
{ query_string: { query: query, fields: fields, analyze_wildcard: true } }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment