Last active
August 9, 2022 17:39
-
-
Save equivalent/310a948f9d6b4ade0ce1cb243e995569 to your computer and use it in GitHub Desktop.
ActiveRecord Elasticsearch edge ngram example for Elasticsearch gem Rails
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
require 'ansi' | |
require 'sqlite3' | |
require 'active_record' | |
require 'elasticsearch/model' | |
ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT) | |
ActiveRecord::Base.establish_connection( adapter: 'sqlite3', database: ":memory:" ) | |
ActiveRecord::Schema.define(version: 1) do | |
create_table :articles do |t| | |
t.string :title | |
t.date :published_at | |
t.timestamps | |
end | |
end | |
class Article < ActiveRecord::Base | |
include Elasticsearch::Model | |
include Elasticsearch::Model::Callbacks | |
article_es_settings = { | |
index: { | |
analysis: { | |
filter: { | |
autocomplete_filter: { | |
type: "edge_ngram", | |
min_gram: 1, | |
max_gram: 20 | |
} | |
}, | |
analyzer:{ | |
autocomplete: { | |
type: "custom", | |
tokenizer: "standard", | |
filter: ["lowercase", "autocomplete_filter"] | |
} | |
} | |
} | |
} | |
} | |
settings article_es_settings do | |
mapping do | |
indexes :title | |
indexes :suggestable_title, type: 'string', analyzer: 'autocomplete' | |
end | |
end | |
def as_indexed_json(options={}) | |
as_json.merge(suggestable_title: title) | |
end | |
end | |
Article.__elasticsearch__.client = Elasticsearch::Client.new log: true | |
# Create index | |
Article.__elasticsearch__.create_index! force: true | |
# Store data | |
Article.delete_all | |
Article.create title: 'Foo' | |
Article.create title: 'Bar' | |
Article.create title: 'Foo Foo' | |
Article.__elasticsearch__.refresh_index! | |
# Search and suggest | |
fulltext_search_response = Article.search(query: { match: { title: 'foo'} } ) | |
puts "Article search:".ansi(:bold), | |
fulltext_search_response.to_a.map { |d| "Title: #{d.title}" }.inspect.ansi(:bold, :yellow) | |
fulltext_search_response_2 = Article.search(query: { match: { title: 'fo'} } ) | |
puts "Article search:".ansi(:bold), | |
fulltext_search_response_2.to_a.map { |d| "Title: #{d.title}" }.inspect.ansi(:bold, :red) | |
autocomplete_search_response = Article.search(query: { match: { suggestable_title: { query: 'fo', analyzer: 'standard'} } } ) | |
puts "Article suggest:".ansi(:bold), | |
autocomplete_search_response.to_a.map { |d| "Title: #{d.suggestable_title}" }.inspect.ansi(:bold, :green) | |
# Elasticsearch will index :title with standard analyzer as fulltext search: | |
# | |
# * foo | |
# * bar | |
# | |
# but field :suggestable_title is indexed with or autocomplete | |
# edge-ngram analyzer so that string is reverse-indexed as: | |
# | |
# * f | |
# * fo | |
# * foo | |
# * b | |
# * ba | |
# * bar |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Elasticsearch edge-ngrams: https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-edgengram-tokenizer.html
this Gist is a mirror for PR https://github.com/elastic/elasticsearch-rails/pull/582/files