This repository has been archived by the owner on Aug 21, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
550 additions
and
284 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,75 +1,118 @@ | ||
require 'active_model' | ||
require 'elasticsearch/dsl' | ||
|
||
class Geoname | ||
include Tire::Model::Search | ||
include ActiveModel::Model | ||
include Elasticsearch::Model | ||
include Elasticsearch::DSL | ||
|
||
INDEX_NAME = "#{Rails.env}:geonames".freeze | ||
|
||
SYNONYMS = [ | ||
"afb, air force base", | ||
"afs, air force station", | ||
"ang, air national guard", | ||
"cavecreek, cave creek", | ||
"ft, fort", | ||
"junc, junction", | ||
"natl, nat, national", | ||
"newcastle, new castle", | ||
"pk, park", | ||
"spgs, springs", | ||
"st, saint" | ||
].freeze | ||
|
||
index_name("#{Rails.env}:geonames".freeze) | ||
SETTINGS = { | ||
analysis: { | ||
filter: { | ||
synonym: { | ||
type: 'synonym', | ||
synonyms: SYNONYMS | ||
} | ||
}, | ||
analyzer: { | ||
custom_analyzer: { | ||
type: 'custom', | ||
tokenizer: 'whitespace', | ||
filter: %w(standard lowercase synonym) | ||
} | ||
} | ||
} | ||
} | ||
|
||
SYNONYMS = ["ft, fort", "st, saint", "afb, air force base", "afs, air force station", "ang, air national guard", "junc, junction", "spgs, springs", "natl, nat, national", "pk, park", "newcastle, new castle", "cavecreek, cave creek"] | ||
settings index: SETTINGS do | ||
mappings dynamic: 'false' do | ||
indexes :type, type: 'keyword' | ||
indexes :location, type: 'text', analyzer: 'custom_analyzer' | ||
indexes :state, type: 'text', analyzer: 'keyword' | ||
indexes :geo, type: 'geo_point' | ||
indexes :id, type: 'keyword', index: false | ||
end | ||
end | ||
|
||
class << self | ||
|
||
def client | ||
@client ||= Geoname.__elasticsearch__.client | ||
end | ||
|
||
def create_search_index | ||
Tire.index index_name do | ||
create( | ||
settings: { | ||
index: { | ||
analysis: { | ||
analyzer: {custom_analyzer: {type: 'custom', tokenizer: 'whitespace', filter: %w(standard lowercase synonym)}}, | ||
filter: {synonym: {type: 'synonym', synonyms: SYNONYMS}} | ||
} | ||
} | ||
}, | ||
mappings: { | ||
geoname: { | ||
properties: { | ||
type: {type: 'string'}, | ||
location: {type: 'string', analyzer: 'custom_analyzer'}, | ||
state: {type: 'string', analyzer: 'keyword'}, | ||
geo: {type: 'geo_point'}, | ||
id: {type: 'string', index: :not_analyzed, include_in_all: false} | ||
} | ||
} | ||
} | ||
) | ||
end | ||
client.indices.create( | ||
index: INDEX_NAME, | ||
body: { settings: settings.to_hash, mappings: mappings.to_hash } | ||
) | ||
end | ||
|
||
def geocode(options = {}) | ||
search_for(options.merge(size: 1)).results.first.geo.to_hash rescue nil | ||
search_for(options.merge(size: 1)).results.first.geo rescue nil | ||
end | ||
|
||
def search_for(options) | ||
Tire.search index_name do | ||
search_definition = Elasticsearch::DSL::Search.search do | ||
query do | ||
boolean do | ||
must { match :location, options[:location], operator: 'AND' } | ||
must { term :state, options[:state] } | ||
bool do | ||
must do | ||
match :location do | ||
query options[:location] | ||
operator 'and' | ||
end | ||
end | ||
|
||
must { term state: options[:state] } | ||
end | ||
end | ||
|
||
size options[:size] | ||
end | ||
end.to_hash | ||
|
||
Geoname.search(search_definition, index: INDEX_NAME) | ||
end | ||
|
||
def delete_search_index | ||
search_index.delete | ||
client.indices.delete index: INDEX_NAME if search_index_exists? | ||
end | ||
|
||
def search_index | ||
Tire.index(index_name) | ||
def search_index_exists? | ||
client.indices.exists? index: INDEX_NAME | ||
end | ||
|
||
def import(geonames) | ||
Tire.index index_name do | ||
import geonames do |docs| | ||
docs.each do |doc| | ||
doc[:id] = "#{doc[:location]}:#{doc[:state]}" | ||
end | ||
end | ||
refresh | ||
geonames.each do |doc| | ||
client.index( | ||
index: INDEX_NAME, | ||
type: 'geoname', | ||
id: "#{doc[:location]}:#{doc[:state]}", | ||
body: { | ||
location: doc[:location], | ||
geo: doc[:geo], | ||
state: doc[:state] | ||
} | ||
) | ||
end | ||
|
||
#Tire.index index_name | ||
Rails.logger.info "Imported #{geonames.size} Geonames to #{index_name}" | ||
end | ||
__elasticsearch__.refresh_index! index: INDEX_NAME | ||
|
||
Rails.logger.info "Imported #{geonames.size} Geonames to #{INDEX_NAME}" | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.