es-elasticity 0.5.2 → 0.6.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 34c481f8fef0f48b348e3c487aea2f38992fd83f
4
- data.tar.gz: 9fce147cb9df7c2ae369d795dc4d31a6777ce2a4
3
+ metadata.gz: fe85514d61fcf6a3e0fe8154a2bcf9abf13efae4
4
+ data.tar.gz: aa8fb32667cbf72c30ee881c906b24908cb369cf
5
5
  SHA512:
6
- metadata.gz: 2b2f8782e944c7adfcd11023829d0031657bc669945f65794e04cbd6389f6043569dd06d776e1b39b9589b227f5d1a653c8b594e9f92e6a6ec471c6bd605d1f5
7
- data.tar.gz: 5c7abac9d356d50d60617231fef6ccc7746be8106aa3ad356b49873143f2ccd6815e568334f8c118fe5229339089f27778d0bc51022c696a9159ca062c284bc9
6
+ metadata.gz: b2c0f4c966b6ea8aa54946901fc99c27498b73af2b00388dd6a2b098aec6f88c79e1cb140ac5f0f3af36d025bc85b9b0a6d2f0c8d7c6730a4802a13f876df321
7
+ data.tar.gz: 266c4a46686ed27aa7cbb8eee58cb128f193c41f30612036e541c5a14f1feba659dd080c13c62fb083d126920208efbdd5d127eb5aaf3e2ad4b33c53b34c14e5
data/CHANGELOG CHANGED
@@ -1,3 +1,12 @@
1
+ v0.6.0
2
+ - Change documents to be able to define indexes with multiple doc types. A
3
+ Document class can define subclasses which are of different doc_types and
4
+ all live in the same index's mappings.
5
+ - updated search queries to pass either a list of document types or a single
6
+ document type.
7
+ - Update documents to generate a default document_type from the class name
8
+ so that Documents always have a document type. You'll still usually want to
9
+ manually define the document type, but it's no longer necessary.
1
10
  v0.5.2
2
11
  - Add aggregations to multi_search
3
12
  v0.5.1
@@ -8,7 +8,7 @@ module Elasticity
8
8
  # Configure the given klass, changing default parameters and resetting
9
9
  # some of the internal state.
10
10
  def self.configure(&block)
11
- self.config = IndexConfig.new(Elasticity.config, &block)
11
+ self.config = IndexConfig.new(Elasticity.config, self.name.underscore, &block)
12
12
  end
13
13
 
14
14
  # Define common attributes for all documents
@@ -1,9 +1,12 @@
1
1
  module Elasticity
2
2
  class IndexConfig
3
- ATTRS = [:index_base_name, :document_type, :mapping, :strategy].freeze
3
+ ATTRS = [:index_base_name, :document_type, :mapping, :strategy, :subclasses].freeze
4
+ VALIDATABLE_ATTRS = [:index_base_name, :document_type, :strategy].freeze
5
+
4
6
  attr_accessor *ATTRS
5
7
 
6
- def initialize(elasticity_config)
8
+ def initialize(elasticity_config, default_document_type)
9
+ @document_type = default_document_type
7
10
  @elasticity_config = elasticity_config
8
11
  yield(self)
9
12
  validate!
@@ -20,7 +23,16 @@ module Elasticity
20
23
  end
21
24
 
22
25
  def definition
23
- { settings: @elasticity_config.settings, mappings: { @document_type => @mapping } }
26
+ return @definition if defined?(@definition)
27
+ @definition = { settings: @elasticity_config.settings, mappings: { @document_type => @mapping || {} } }
28
+ subclasses.each do |doc_type, subclass|
29
+ @definition[:mappings][doc_type] = subclass.constantize.mapping
30
+ end if subclasses.present?
31
+ @definition
32
+ end
33
+
34
+ def document_types
35
+ @document_types ||= definition[:mappings].collect { |doc_type, mapping| doc_type }
24
36
  end
25
37
 
26
38
  def fq_index_base_name
@@ -42,7 +54,7 @@ module Elasticity
42
54
  private
43
55
 
44
56
  def validate!
45
- ATTRS.each do |attr|
57
+ VALIDATABLE_ATTRS.each do |attr|
46
58
  raise "#{attr} is not set" if public_send(attr).nil?
47
59
  end
48
60
  end
@@ -32,6 +32,7 @@ module Elasticity
32
32
 
33
33
  delegate(
34
34
  :document_type,
35
+ :document_types,
35
36
  :mapping,
36
37
  :ref_index_name,
37
38
  to: :@index_config
@@ -82,7 +83,7 @@ module Elasticity
82
83
  # structure Elasticsearch expects.
83
84
  # Returns a DocumentSearch object.
84
85
  def search(body)
85
- search_obj = Search.build(@index_config.client, @strategy.search_index, document_type, body)
86
+ search_obj = Search.build(@index_config.client, @strategy.search_index, document_types, body)
86
87
  Search::DocumentProxy.new(search_obj, self.method(:map_hit))
87
88
  end
88
89
 
@@ -152,8 +153,11 @@ module Elasticity
152
153
 
153
154
  highlighted = @document_klass.new(highlighted_attrs)
154
155
  end
155
-
156
- @document_klass.new(attrs.merge(highlighted: highlighted))
156
+ if @document_klass.config.subclasses.present?
157
+ @document_klass.config.subclasses[hit["_type"].to_sym].constantize.new(attrs.merge(highlighted: highlighted))
158
+ else
159
+ @document_klass.new(attrs.merge(highlighted: highlighted))
160
+ end
157
161
  end
158
162
  end
159
163
  end
@@ -1,38 +1,38 @@
1
1
  module Elasticity
2
2
  module Search
3
- def self.build(client, index_name, document_type, body)
4
- search_def = Search::Definition.new(index_name, document_type, body)
3
+ def self.build(client, index_name, document_types, body)
4
+ search_def = Search::Definition.new(index_name, document_types, body)
5
5
  Search::Facade.new(client, search_def)
6
6
  end
7
7
 
8
8
  # Elasticity::Search::Definition is a struct that encapsulates all the data specific to one
9
9
  # ElasticSearch search.
10
10
  class Definition
11
- attr_accessor :index_name, :document_type, :body
11
+ attr_accessor :index_name, :document_types, :body
12
12
 
13
- def initialize(index_name, document_type, body)
13
+ def initialize(index_name, document_types, body)
14
14
  @index_name = index_name
15
- @document_type = document_type
15
+ @document_types = document_types
16
16
  @body = body.deep_symbolize_keys!
17
17
  end
18
18
 
19
19
  def update(body_changes)
20
- self.class.new(@index_name, @document_type, @body.deep_merge(body_changes))
20
+ self.class.new(@index_name, @document_types, @body.deep_merge(body_changes))
21
21
  end
22
22
 
23
23
  def to_count_args
24
- { index: @index_name, type: @document_type}.tap do |args|
24
+ { index: @index_name, type: @document_types}.tap do |args|
25
25
  body = @body.slice(:query)
26
26
  args[:body] = body if body.present?
27
27
  end
28
28
  end
29
29
 
30
30
  def to_search_args
31
- { index: @index_name, type: @document_type, body: @body }
31
+ { index: @index_name, type: @document_types, body: @body }
32
32
  end
33
33
 
34
34
  def to_msearch_args
35
- { index: @index_name, type: @document_type, search: @body }
35
+ { index: @index_name, type: @document_types, search: @body }
36
36
  end
37
37
  end
38
38
 
@@ -1,3 +1,3 @@
1
1
  module Elasticity
2
- VERSION = "0.5.2"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -2,6 +2,10 @@ RSpec.describe "Persistence", elasticsearch: true do
2
2
  describe "single index strategy" do
3
3
  subject do
4
4
  Class.new(Elasticity::Document) do
5
+ def self.name
6
+ 'SomeClass'
7
+ end
8
+
5
9
  configure do |c|
6
10
  c.index_base_name = "users"
7
11
  c.document_type = "user"
@@ -66,9 +70,93 @@ RSpec.describe "Persistence", elasticsearch: true do
66
70
  end
67
71
  end
68
72
 
73
+ describe 'multi mapping index' do
74
+ class Animal < Elasticity::Document
75
+ configure do |c|
76
+ c.index_base_name = "cats_and_dogs"
77
+ c.strategy = Elasticity::Strategies::SingleIndex
78
+ c.subclasses = { cat: "Cat", dog: "Dog" }
79
+ end
80
+ end
81
+
82
+ class Cat < Animal
83
+ configure do |c|
84
+ c.index_base_name = "cats_and_dogs"
85
+ c.strategy = Elasticity::Strategies::SingleIndex
86
+ c.document_type = "cat"
87
+ c.mapping = { properties: {
88
+ name: { type: "string" },
89
+ age: { type: "integer" }
90
+ } }
91
+ end
92
+
93
+ attr_accessor :name, :age
94
+
95
+ def to_document
96
+ { name: name, age: age }
97
+ end
98
+ end
99
+
100
+ class Dog < Animal
101
+ configure do |c|
102
+ c.index_base_name = "cats_and_dogs"
103
+ c.strategy = Elasticity::Strategies::SingleIndex
104
+ c.document_type = "dog"
105
+ c.mapping = { properties: {
106
+ name: { type: "string" },
107
+ age: { type: "integer" },
108
+ hungry: { type: "boolean" }
109
+ } }
110
+ end
111
+ attr_accessor :name, :age, :hungry
112
+
113
+ def to_document
114
+ { name: name, age: age, hungry: hungry }
115
+ end
116
+ end
117
+
118
+ before do
119
+ Animal.recreate_index
120
+ @elastic_search_client.cluster.health wait_for_status: 'yellow'
121
+ end
122
+
123
+ it "successful index, update, search, count and deletes" do
124
+ cat = Cat.new(name: "felix", age: 10)
125
+ dog = Dog.new(name: "fido", age: 4, hungry: true)
126
+
127
+ cat.update
128
+ dog.update
129
+
130
+ Animal.flush_index
131
+
132
+ results = Animal.search({})
133
+ expect(results.total).to eq 2
134
+ expect(results.map(&:class)).to include(Cat, Dog)
135
+
136
+ results = Cat.search({})
137
+ expect(results.total).to eq 1
138
+ expect(results.first.class).to eq Cat
139
+
140
+ results = Dog.search({})
141
+ expect(results.total).to eq 1
142
+ expect(results.first.class).to eq Dog
143
+
144
+ cat.delete
145
+ Animal.flush_index
146
+
147
+ results = Animal.search({})
148
+ expect(results.total).to eq 1
149
+ expect(results.map(&:class)).to include(Dog)
150
+ end
151
+ end
152
+
69
153
  describe "alias index strategy" do
70
154
  subject do
71
155
  Class.new(Elasticity::Document) do
156
+ def self.name
157
+ "SomeClass"
158
+ end
159
+
72
160
  configure do |c|
73
161
  c.index_base_name = "users"
74
162
  c.document_type = "user"
@@ -1,6 +1,10 @@
1
1
  RSpec.describe "Segmented indexes", elasticsearch: true do
2
2
  subject do
3
3
  Class.new(Elasticity::SegmentedDocument) do
4
+ def self.name
5
+ "SomeClass"
6
+ end
7
+
4
8
  configure do |c|
5
9
  c.index_base_name = "people"
6
10
  c.document_type = "person"
@@ -16,6 +16,10 @@ RSpec.describe Elasticity::Document do
16
16
 
17
17
  let :klass do
18
18
  Class.new(described_class) do
19
+ def self.name
20
+ "SomeClass"
21
+ end
22
+
19
23
  configure do |c|
20
24
  c.index_base_name = "class_names"
21
25
  c.document_type = "class_name"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: es-elasticity
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Kochenburger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-14 00:00:00.000000000 Z
11
+ date: 2016-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -230,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
230
230
  version: '0'
231
231
  requirements: []
232
232
  rubyforge_project:
233
- rubygems_version: 2.2.2
233
+ rubygems_version: 2.4.5
234
234
  signing_key:
235
235
  specification_version: 4
236
236
  summary: ActiveModel-based library for working with Elasticsearch
@@ -243,3 +243,4 @@ test_files:
243
243
  - spec/units/multi_search_spec.rb
244
244
  - spec/units/search_spec.rb
245
245
  - spec/units/strategies/single_index_spec.rb
246
+ has_rdoc: