Skip to content

Commit f8df53a

Browse files
equivalentkarmi
authored andcommitted
[MODEL] Added an example with Edge NGram mapping for auto-completion
This example uses an [Edge Ngram](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-edgengram-tokenizer.html) mapping to demonstrate how to create a custom "settings" for a model, and how to use the NGram feature for autocomplete. NOTE: The "Completion Suggester" should be used in all cases where it's applicable; see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-completion.html. Closes elastic#582
1 parent 16ef393 commit f8df53a

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
require 'ansi'
2+
require 'sqlite3'
3+
require 'active_record'
4+
require 'elasticsearch/model'
5+
6+
ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT)
7+
ActiveRecord::Base.establish_connection( adapter: 'sqlite3', database: ":memory:" )
8+
9+
ActiveRecord::Schema.define(version: 1) do
10+
create_table :articles do |t|
11+
t.string :title
12+
t.date :published_at
13+
t.timestamps
14+
end
15+
end
16+
17+
class Article < ActiveRecord::Base
18+
include Elasticsearch::Model
19+
include Elasticsearch::Model::Callbacks
20+
21+
article_es_settings = {
22+
index: {
23+
analysis: {
24+
filter: {
25+
autocomplete_filter: {
26+
type: "edge_ngram",
27+
min_gram: 1,
28+
max_gram: 20
29+
}
30+
},
31+
analyzer:{
32+
autocomplete: {
33+
type: "custom",
34+
tokenizer: "standard",
35+
filter: ["lowercase", "autocomplete_filter"]
36+
}
37+
}
38+
}
39+
}
40+
}
41+
42+
settings article_es_settings do
43+
mapping do
44+
indexes :title
45+
indexes :suggestable_title, type: 'string', analyzer: 'autocomplete'
46+
end
47+
end
48+
49+
def as_indexed_json(options={})
50+
as_json.merge(suggestable_title: title)
51+
end
52+
end
53+
54+
Article.__elasticsearch__.client = Elasticsearch::Client.new log: true
55+
56+
# Create index
57+
58+
Article.__elasticsearch__.create_index! force: true
59+
60+
# Store data
61+
62+
Article.delete_all
63+
Article.create title: 'Foo'
64+
Article.create title: 'Bar'
65+
Article.create title: 'Foo Foo'
66+
Article.__elasticsearch__.refresh_index!
67+
68+
# Search and suggest
69+
fulltext_search_response = Article.search(query: { match: { title: 'foo'} } )
70+
71+
puts "", "Article search for 'foo':".ansi(:bold),
72+
fulltext_search_response.to_a.map { |d| "Title: #{d.title}" }.inspect.ansi(:bold, :yellow),
73+
""
74+
75+
fulltext_search_response_2 = Article.search(query: { match: { title: 'fo'} } )
76+
77+
puts "", "Article search for 'fo':".ansi(:bold),
78+
fulltext_search_response_2.to_a.map { |d| "Title: #{d.title}" }.inspect.ansi(:bold, :red),
79+
""
80+
81+
autocomplete_search_response = Article.search(query: { match: { suggestable_title: { query: 'fo', analyzer: 'standard'} } } )
82+
83+
puts "", "Article autocomplete for 'fo':".ansi(:bold),
84+
autocomplete_search_response.to_a.map { |d| "Title: #{d.suggestable_title}" }.inspect.ansi(:bold, :green),
85+
""
86+
87+
puts "", "Text 'Foo Bar' analyzed with the default analyzer:".ansi(:bold),
88+
Article.__elasticsearch__.client.indices.analyze(
89+
index: Article.__elasticsearch__.index_name,
90+
field: 'title',
91+
text: 'Foo Bar')['tokens'].map { |t| t['token'] }.inspect.ansi(:bold, :yellow),
92+
""
93+
94+
puts "", "Text 'Foo Bar' analyzed with the autocomplete filter:".ansi(:bold),
95+
Article.__elasticsearch__.client.indices.analyze(
96+
index: Article.__elasticsearch__.index_name,
97+
field: 'suggestable_title',
98+
text: 'Foo Bar')['tokens'].map { |t| t['token'] }.inspect.ansi(:bold, :yellow),
99+
""
100+
101+
require 'pry'; binding.pry;

0 commit comments

Comments
 (0)