elasticsearch-model 0.0.1 → 0.1.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +3 -0
- data/LICENSE.txt +1 -1
- data/README.md +669 -8
- data/Rakefile +52 -0
- data/elasticsearch-model.gemspec +48 -17
- data/examples/activerecord_article.rb +77 -0
- data/examples/activerecord_associations.rb +153 -0
- data/examples/couchbase_article.rb +66 -0
- data/examples/datamapper_article.rb +71 -0
- data/examples/mongoid_article.rb +68 -0
- data/examples/ohm_article.rb +70 -0
- data/examples/riak_article.rb +52 -0
- data/gemfiles/3.gemfile +11 -0
- data/gemfiles/4.gemfile +11 -0
- data/lib/elasticsearch/model.rb +151 -1
- data/lib/elasticsearch/model/adapter.rb +145 -0
- data/lib/elasticsearch/model/adapters/active_record.rb +97 -0
- data/lib/elasticsearch/model/adapters/default.rb +44 -0
- data/lib/elasticsearch/model/adapters/mongoid.rb +90 -0
- data/lib/elasticsearch/model/callbacks.rb +35 -0
- data/lib/elasticsearch/model/client.rb +61 -0
- data/lib/elasticsearch/model/importing.rb +94 -0
- data/lib/elasticsearch/model/indexing.rb +332 -0
- data/lib/elasticsearch/model/naming.rb +101 -0
- data/lib/elasticsearch/model/proxy.rb +127 -0
- data/lib/elasticsearch/model/response.rb +70 -0
- data/lib/elasticsearch/model/response/base.rb +44 -0
- data/lib/elasticsearch/model/response/pagination.rb +96 -0
- data/lib/elasticsearch/model/response/records.rb +71 -0
- data/lib/elasticsearch/model/response/result.rb +50 -0
- data/lib/elasticsearch/model/response/results.rb +32 -0
- data/lib/elasticsearch/model/searching.rb +107 -0
- data/lib/elasticsearch/model/serializing.rb +35 -0
- data/lib/elasticsearch/model/support/forwardable.rb +44 -0
- data/lib/elasticsearch/model/version.rb +1 -1
- data/test/integration/active_record_associations_parent_child.rb +138 -0
- data/test/integration/active_record_associations_test.rb +306 -0
- data/test/integration/active_record_basic_test.rb +139 -0
- data/test/integration/active_record_import_test.rb +74 -0
- data/test/integration/active_record_namespaced_model_test.rb +49 -0
- data/test/integration/active_record_pagination_test.rb +109 -0
- data/test/integration/mongoid_basic_test.rb +178 -0
- data/test/test_helper.rb +57 -0
- data/test/unit/adapter_active_record_test.rb +93 -0
- data/test/unit/adapter_default_test.rb +31 -0
- data/test/unit/adapter_mongoid_test.rb +87 -0
- data/test/unit/adapter_test.rb +69 -0
- data/test/unit/callbacks_test.rb +30 -0
- data/test/unit/client_test.rb +27 -0
- data/test/unit/importing_test.rb +97 -0
- data/test/unit/indexing_test.rb +364 -0
- data/test/unit/module_test.rb +46 -0
- data/test/unit/naming_test.rb +76 -0
- data/test/unit/proxy_test.rb +88 -0
- data/test/unit/response_base_test.rb +40 -0
- data/test/unit/response_pagination_test.rb +159 -0
- data/test/unit/response_records_test.rb +87 -0
- data/test/unit/response_result_test.rb +52 -0
- data/test/unit/response_results_test.rb +31 -0
- data/test/unit/response_test.rb +57 -0
- data/test/unit/searching_search_request_test.rb +73 -0
- data/test/unit/searching_test.rb +39 -0
- data/test/unit/serializing_test.rb +17 -0
- metadata +418 -11
data/Rakefile
CHANGED
@@ -1 +1,53 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
desc "Run unit tests"
|
4
|
+
task :default => 'test:unit'
|
5
|
+
task :test => 'test:unit'
|
6
|
+
|
7
|
+
# ----- Test tasks ------------------------------------------------------------
|
8
|
+
|
9
|
+
require 'rake/testtask'
|
10
|
+
namespace :test do
|
11
|
+
task :ci_reporter do
|
12
|
+
ENV['CI_REPORTS'] ||= 'tmp/reports'
|
13
|
+
require 'ci/reporter/rake/minitest'
|
14
|
+
Rake::Task['ci:setup:minitest'].invoke
|
15
|
+
end
|
16
|
+
|
17
|
+
Rake::TestTask.new(:unit) do |test|
|
18
|
+
Rake::Task['test:ci_reporter'].invoke if ENV['CI']
|
19
|
+
test.libs << 'lib' << 'test'
|
20
|
+
test.test_files = FileList["test/unit/**/*_test.rb"]
|
21
|
+
# test.verbose = true
|
22
|
+
# test.warning = true
|
23
|
+
end
|
24
|
+
|
25
|
+
Rake::TestTask.new(:integration) do |test|
|
26
|
+
Rake::Task['test:ci_reporter'].invoke if ENV['CI']
|
27
|
+
test.libs << 'lib' << 'test'
|
28
|
+
test.test_files = FileList["test/integration/**/*_test.rb"]
|
29
|
+
end
|
30
|
+
|
31
|
+
Rake::TestTask.new(:all) do |test|
|
32
|
+
Rake::Task['test:ci_reporter'].invoke if ENV['CI']
|
33
|
+
test.libs << 'lib' << 'test'
|
34
|
+
test.test_files = FileList["test/unit/**/*_test.rb", "test/integration/**/*_test.rb"]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# ----- Documentation tasks ---------------------------------------------------
|
39
|
+
|
40
|
+
require 'yard'
|
41
|
+
YARD::Rake::YardocTask.new(:doc) do |t|
|
42
|
+
t.options = %w| --embed-mixins --markup=markdown |
|
43
|
+
end
|
44
|
+
|
45
|
+
# ----- Code analysis tasks ---------------------------------------------------
|
46
|
+
|
47
|
+
if defined?(RUBY_VERSION) && RUBY_VERSION > '1.9'
|
48
|
+
require 'cane/rake_task'
|
49
|
+
Cane::RakeTask.new(:quality) do |cane|
|
50
|
+
cane.abc_max = 15
|
51
|
+
cane.no_style = true
|
52
|
+
end
|
53
|
+
end
|
data/elasticsearch-model.gemspec
CHANGED
@@ -3,21 +3,52 @@ lib = File.expand_path('../lib', __FILE__)
|
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
4
|
require 'elasticsearch/model/version'
|
5
5
|
|
6
|
-
Gem::Specification.new do |
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "elasticsearch-model"
|
8
|
+
s.version = Elasticsearch::Model::VERSION
|
9
|
+
s.authors = ["Karel Minarik"]
|
10
|
+
s.email = ["karel.minarik@elasticsearch.org"]
|
11
|
+
s.description = "ActiveModel/Record integrations for Elasticsearch."
|
12
|
+
s.summary = "ActiveModel/Record integrations for Elasticsearch."
|
13
|
+
s.homepage = "https://github.com/elasticsearch/elasticsearch-rails/"
|
14
|
+
s.license = "Apache 2"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split($/)
|
17
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.extra_rdoc_files = [ "README.md", "LICENSE.txt" ]
|
22
|
+
s.rdoc_options = [ "--charset=UTF-8" ]
|
23
|
+
|
24
|
+
s.add_dependency "elasticsearch", '~> 0.4'
|
25
|
+
s.add_dependency "hashie"
|
26
|
+
|
27
|
+
s.add_development_dependency "bundler", "~> 1.3"
|
28
|
+
s.add_development_dependency "rake"
|
29
|
+
|
30
|
+
s.add_development_dependency "elasticsearch-extensions"
|
31
|
+
|
32
|
+
s.add_development_dependency "sqlite3"
|
33
|
+
s.add_development_dependency "activesupport", "> 3.0"
|
34
|
+
s.add_development_dependency "activemodel", "> 3.0"
|
35
|
+
s.add_development_dependency "activerecord", "> 4.0"
|
36
|
+
|
37
|
+
s.add_development_dependency "oj"
|
38
|
+
s.add_development_dependency "kaminari"
|
39
|
+
|
40
|
+
s.add_development_dependency "shoulda-context"
|
41
|
+
s.add_development_dependency "mocha"
|
42
|
+
s.add_development_dependency "turn"
|
43
|
+
s.add_development_dependency "yard"
|
44
|
+
s.add_development_dependency "ruby-prof"
|
45
|
+
s.add_development_dependency "pry"
|
46
|
+
s.add_development_dependency "ci_reporter"
|
47
|
+
|
48
|
+
if defined?(RUBY_VERSION) && RUBY_VERSION > '1.9'
|
49
|
+
s.add_development_dependency "simplecov"
|
50
|
+
s.add_development_dependency "cane"
|
51
|
+
s.add_development_dependency "require-prof"
|
52
|
+
s.add_development_dependency "coveralls"
|
53
|
+
end
|
23
54
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# ActiveRecord and Elasticsearch
|
2
|
+
# ==============================
|
3
|
+
#
|
4
|
+
# https://github.com/rails/rails/tree/master/activerecord
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
7
|
+
|
8
|
+
require 'pry'
|
9
|
+
Pry.config.history.file = File.expand_path('../../tmp/elasticsearch_development.pry', __FILE__)
|
10
|
+
|
11
|
+
require 'logger'
|
12
|
+
require 'ansi/core'
|
13
|
+
require 'active_record'
|
14
|
+
require 'kaminari'
|
15
|
+
|
16
|
+
require 'elasticsearch/model'
|
17
|
+
|
18
|
+
ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT)
|
19
|
+
ActiveRecord::Base.establish_connection( adapter: 'sqlite3', database: ":memory:" )
|
20
|
+
|
21
|
+
ActiveRecord::Schema.define(version: 1) do
|
22
|
+
create_table :articles do |t|
|
23
|
+
t.string :title
|
24
|
+
t.date :published_at
|
25
|
+
t.timestamps
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
Kaminari::Hooks.init
|
30
|
+
|
31
|
+
class Article < ActiveRecord::Base
|
32
|
+
end
|
33
|
+
|
34
|
+
# Store data
|
35
|
+
#
|
36
|
+
Article.delete_all
|
37
|
+
Article.create title: 'Foo'
|
38
|
+
Article.create title: 'Bar'
|
39
|
+
Article.create title: 'Foo Foo'
|
40
|
+
|
41
|
+
# Index data
|
42
|
+
#
|
43
|
+
client = Elasticsearch::Client.new log:true
|
44
|
+
|
45
|
+
# client.indices.delete index: 'articles' rescue nil
|
46
|
+
# client.indices.create index: 'articles', body: { mappings: { article: { dynamic: 'strict' }, properties: {} } }
|
47
|
+
|
48
|
+
client.indices.delete index: 'articles' rescue nil
|
49
|
+
client.bulk index: 'articles',
|
50
|
+
type: 'article',
|
51
|
+
body: Article.all.as_json.map { |a| { index: { _id: a.delete('id'), data: a } } },
|
52
|
+
refresh: true
|
53
|
+
|
54
|
+
# Extend the model with Elasticsearch support
|
55
|
+
#
|
56
|
+
Article.__send__ :include, Elasticsearch::Model
|
57
|
+
# Article.__send__ :include, Elasticsearch::Model::Callbacks
|
58
|
+
|
59
|
+
# ActiveRecord::Base.logger.silence do
|
60
|
+
# 10_000.times do |i|
|
61
|
+
# Article.create title: "Foo #{i}"
|
62
|
+
# end
|
63
|
+
# end
|
64
|
+
|
65
|
+
puts '', '-'*Pry::Terminal.width!
|
66
|
+
|
67
|
+
Elasticsearch::Model.client = Elasticsearch::Client.new log: true
|
68
|
+
|
69
|
+
response = Article.search 'foo';
|
70
|
+
|
71
|
+
p response.size
|
72
|
+
p response.results.size
|
73
|
+
p response.records.size
|
74
|
+
|
75
|
+
Pry.start(binding, prompt: lambda { |obj, nest_level, _| '> ' },
|
76
|
+
input: StringIO.new('response.records.to_a'),
|
77
|
+
quiet: true)
|
@@ -0,0 +1,153 @@
|
|
1
|
+
# ActiveRecord associations and Elasticsearch
|
2
|
+
# ===========================================
|
3
|
+
#
|
4
|
+
# https://github.com/rails/rails/tree/master/activerecord
|
5
|
+
# http://guides.rubyonrails.org/association_basics.html
|
6
|
+
|
7
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
8
|
+
|
9
|
+
require 'pry'
|
10
|
+
Pry.config.history.file = File.expand_path('../../tmp/elasticsearch_development.pry', __FILE__)
|
11
|
+
|
12
|
+
require 'logger'
|
13
|
+
require 'ansi/core'
|
14
|
+
require 'active_record'
|
15
|
+
|
16
|
+
require 'elasticsearch/model'
|
17
|
+
|
18
|
+
ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT)
|
19
|
+
ActiveRecord::Base.establish_connection( adapter: 'sqlite3', database: ":memory:" )
|
20
|
+
|
21
|
+
# ----- Schema definition -------------------------------------------------------------------------
|
22
|
+
|
23
|
+
ActiveRecord::Schema.define(version: 1) do
|
24
|
+
create_table :categories do |t|
|
25
|
+
t.string :title
|
26
|
+
t.timestamps
|
27
|
+
end
|
28
|
+
|
29
|
+
create_table :authors do |t|
|
30
|
+
t.string :first_name, :last_name
|
31
|
+
t.timestamps
|
32
|
+
end
|
33
|
+
|
34
|
+
create_table :authorships do |t|
|
35
|
+
t.references :article
|
36
|
+
t.references :author
|
37
|
+
t.timestamps
|
38
|
+
end
|
39
|
+
|
40
|
+
create_table :articles do |t|
|
41
|
+
t.string :title
|
42
|
+
t.timestamps
|
43
|
+
end
|
44
|
+
|
45
|
+
create_table :articles_categories, id: false do |t|
|
46
|
+
t.references :article, :category
|
47
|
+
end
|
48
|
+
|
49
|
+
create_table :comments do |t|
|
50
|
+
t.string :text
|
51
|
+
t.references :article
|
52
|
+
t.timestamps
|
53
|
+
end
|
54
|
+
add_index(:comments, :article_id)
|
55
|
+
end
|
56
|
+
|
57
|
+
# ----- Model definitions -------------------------------------------------------------------------
|
58
|
+
|
59
|
+
class Category < ActiveRecord::Base
|
60
|
+
has_and_belongs_to_many :articles
|
61
|
+
end
|
62
|
+
|
63
|
+
class Author < ActiveRecord::Base
|
64
|
+
has_many :authorships
|
65
|
+
|
66
|
+
def full_name
|
67
|
+
[first_name, last_name].compact.join(' ')
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class Authorship < ActiveRecord::Base
|
72
|
+
belongs_to :author
|
73
|
+
belongs_to :article, touch: true
|
74
|
+
end
|
75
|
+
|
76
|
+
class Article < ActiveRecord::Base
|
77
|
+
has_and_belongs_to_many :categories, after_add: [ lambda { |a,c| a.__elasticsearch__.index_document } ],
|
78
|
+
after_remove: [ lambda { |a,c| a.__elasticsearch__.index_document } ]
|
79
|
+
has_many :authorships
|
80
|
+
has_many :authors, through: :authorships
|
81
|
+
has_many :comments
|
82
|
+
end
|
83
|
+
|
84
|
+
class Comment < ActiveRecord::Base
|
85
|
+
belongs_to :article, touch: true
|
86
|
+
end
|
87
|
+
|
88
|
+
# ----- Search integration ------------------------------------------------------------------------
|
89
|
+
|
90
|
+
module Searchable
|
91
|
+
extend ActiveSupport::Concern
|
92
|
+
|
93
|
+
included do
|
94
|
+
include Elasticsearch::Model
|
95
|
+
include Elasticsearch::Model::Callbacks
|
96
|
+
|
97
|
+
__elasticsearch__.client = Elasticsearch::Client.new log: true
|
98
|
+
__elasticsearch__.client.transport.logger.formatter = proc { |s, d, p, m| "\e[32m#{m}\n\e[0m" }
|
99
|
+
|
100
|
+
include Indexing
|
101
|
+
after_touch() { __elasticsearch__.index_document }
|
102
|
+
end
|
103
|
+
|
104
|
+
module Indexing
|
105
|
+
|
106
|
+
# Customize the JSON serialization for Elasticsearch
|
107
|
+
def as_indexed_json(options={})
|
108
|
+
self.as_json(
|
109
|
+
include: { categories: { only: :title},
|
110
|
+
authors: { methods: [:full_name], only: [:full_name] },
|
111
|
+
comments: { only: :text }
|
112
|
+
})
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
Article.__send__ :include, Searchable
|
118
|
+
|
119
|
+
# ----- Insert data -------------------------------------------------------------------------------
|
120
|
+
|
121
|
+
# Create category
|
122
|
+
#
|
123
|
+
category = Category.create title: 'One'
|
124
|
+
|
125
|
+
# Create author
|
126
|
+
#
|
127
|
+
author = Author.create first_name: 'John', last_name: 'Smith'
|
128
|
+
|
129
|
+
# Create article
|
130
|
+
|
131
|
+
article = Article.create title: 'First Article'
|
132
|
+
|
133
|
+
# Assign category
|
134
|
+
#
|
135
|
+
article.categories << category
|
136
|
+
|
137
|
+
# Assign author
|
138
|
+
#
|
139
|
+
article.authors << author
|
140
|
+
|
141
|
+
# Add comment
|
142
|
+
#
|
143
|
+
article.comments.create text: 'First comment'
|
144
|
+
|
145
|
+
# Load
|
146
|
+
#
|
147
|
+
article = Article.all.includes(:categories, :authors, :comments).first
|
148
|
+
|
149
|
+
# ----- Pry ---------------------------------------------------------------------------------------
|
150
|
+
|
151
|
+
Pry.start(binding, prompt: lambda { |obj, nest_level, _| '> ' },
|
152
|
+
input: StringIO.new('puts "\n\narticle.as_indexed_json\n"; article.as_indexed_json'),
|
153
|
+
quiet: true)
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# Couchbase and Elasticsearch
|
2
|
+
# ===========================
|
3
|
+
#
|
4
|
+
# https://github.com/couchbase/couchbase-ruby-model
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
7
|
+
|
8
|
+
require 'pry'
|
9
|
+
Pry.config.history.file = File.expand_path('../../tmp/elasticsearch_development.pry', __FILE__)
|
10
|
+
|
11
|
+
require 'logger'
|
12
|
+
require 'couchbase/model'
|
13
|
+
|
14
|
+
require 'elasticsearch/model'
|
15
|
+
|
16
|
+
# Documents are stored as JSON objects in Riak but have rich
|
17
|
+
# semantics, including validations and associations.
|
18
|
+
class Article < Couchbase::Model
|
19
|
+
attribute :title
|
20
|
+
attribute :published_at
|
21
|
+
|
22
|
+
# view :all, :limit => 10, :descending => true
|
23
|
+
# TODO: Implement view a la
|
24
|
+
# bucket.save_design_doc <<-JSON
|
25
|
+
# {
|
26
|
+
# "_id": "_design/article",
|
27
|
+
# "language": "javascript",
|
28
|
+
# "views": {
|
29
|
+
# "all": {
|
30
|
+
# "map": "function(doc, meta) { emit(doc.id, doc.title); }"
|
31
|
+
# }
|
32
|
+
# }
|
33
|
+
# }
|
34
|
+
# JSON
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
# Extend the model with Elasticsearch support
|
39
|
+
#
|
40
|
+
Article.__send__ :extend, Elasticsearch::Model::Client::ClassMethods
|
41
|
+
Article.__send__ :extend, Elasticsearch::Model::Searching::ClassMethods
|
42
|
+
Article.__send__ :extend, Elasticsearch::Model::Naming::ClassMethods
|
43
|
+
|
44
|
+
# Create documents in Riak
|
45
|
+
#
|
46
|
+
Article.create id: '1', title: 'Foo' rescue nil
|
47
|
+
Article.create id: '2', title: 'Bar' rescue nil
|
48
|
+
Article.create id: '3', title: 'Foo Foo' rescue nil
|
49
|
+
|
50
|
+
# Index data into Elasticsearch
|
51
|
+
#
|
52
|
+
client = Elasticsearch::Client.new log:true
|
53
|
+
|
54
|
+
client.indices.delete index: 'articles' rescue nil
|
55
|
+
client.bulk index: 'articles',
|
56
|
+
type: 'article',
|
57
|
+
body: Article.find(['1', '2', '3']).map { |a|
|
58
|
+
{ index: { _id: a.id, data: a.attributes } }
|
59
|
+
},
|
60
|
+
refresh: true
|
61
|
+
|
62
|
+
response = Article.search 'foo', index: 'articles', type: 'article';
|
63
|
+
|
64
|
+
Pry.start(binding, prompt: lambda { |obj, nest_level, _| '> ' },
|
65
|
+
input: StringIO.new('response.records.to_a'),
|
66
|
+
quiet: true)
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# DataMapper and Elasticsearch
|
2
|
+
# ============================
|
3
|
+
#
|
4
|
+
# https://github.com/datamapper/dm-core
|
5
|
+
# https://github.com/datamapper/dm-active_model
|
6
|
+
|
7
|
+
|
8
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
9
|
+
|
10
|
+
require 'pry'
|
11
|
+
Pry.config.history.file = File.expand_path('../../tmp/elasticsearch_development.pry', __FILE__)
|
12
|
+
|
13
|
+
require 'logger'
|
14
|
+
require 'ansi/core'
|
15
|
+
|
16
|
+
require 'data_mapper'
|
17
|
+
require 'dm-active_model'
|
18
|
+
|
19
|
+
require 'active_support/all'
|
20
|
+
|
21
|
+
require 'elasticsearch/model'
|
22
|
+
|
23
|
+
DataMapper::Logger.new(STDOUT, :debug)
|
24
|
+
DataMapper.setup(:default, 'sqlite::memory:')
|
25
|
+
|
26
|
+
class Article
|
27
|
+
include DataMapper::Resource
|
28
|
+
|
29
|
+
property :id, Serial
|
30
|
+
property :title, String
|
31
|
+
property :published_at, DateTime
|
32
|
+
end
|
33
|
+
|
34
|
+
DataMapper.auto_migrate!
|
35
|
+
DataMapper.finalize
|
36
|
+
|
37
|
+
Article.create title: 'Foo'
|
38
|
+
Article.create title: 'Bar'
|
39
|
+
Article.create title: 'Foo Foo'
|
40
|
+
|
41
|
+
# Extend the model with Elasticsearch support
|
42
|
+
#
|
43
|
+
Article.__send__ :include, Elasticsearch::Model
|
44
|
+
|
45
|
+
# The DataMapper adapter
|
46
|
+
#
|
47
|
+
module DataMapperAdapter
|
48
|
+
|
49
|
+
# Implement the interface for fetching records
|
50
|
+
#
|
51
|
+
module Records
|
52
|
+
def records
|
53
|
+
klass.all(id: @ids)
|
54
|
+
end
|
55
|
+
|
56
|
+
# ...
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Register the adapter
|
61
|
+
#
|
62
|
+
Elasticsearch::Model::Adapter.register(
|
63
|
+
DataMapperAdapter,
|
64
|
+
lambda { |klass| defined?(::DataMapper::Resource) and klass.ancestors.include?(::DataMapper::Resource) }
|
65
|
+
)
|
66
|
+
|
67
|
+
response = Article.search 'foo';
|
68
|
+
|
69
|
+
Pry.start(binding, prompt: lambda { |obj, nest_level, _| '> ' },
|
70
|
+
input: StringIO.new('response.records.to_a'),
|
71
|
+
quiet: true)
|