rom-elasticsearch 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 647ee55a0a3fab8ec9b20787922a1b94e4254ed54a9eacff365bfc9516662523
4
- data.tar.gz: b522b81b7944c512495062ba3dd6243c7da932ca39b0efbec8935c6027df6fdb
3
+ metadata.gz: aa9cb00a1c12ce6fe7272e59acb19a5a1cb473b4a31c5fd9355bebd4e3993234
4
+ data.tar.gz: 2c1338c63fe76a413386fb48c5b7afba3602f8b51b7c8473422c2f9e996966f7
5
5
  SHA512:
6
- metadata.gz: d717a78441c7777e2871fb177dcafdde2420ba039a358aaa9403d1aa0bad4a9d6e7936e1446f44ce0b4ee5dc7b1c0d92853816a470b3a25c03ebe046c5a6d767
7
- data.tar.gz: '0379f5ac4de1ede62a6cf21cd5412595bb18674a537a84672b91f667f1179420fcd9d4a30b3220f413eb6215e0e7abaa55cc2c1487b109a32bf648ea71816346'
6
+ metadata.gz: 7984f2495ca0645cbbe39a7a34f2b6015f16c1c54c7736f96abda000a0669175b28e6a1ee6eefe89e452c33656f40d785562ccf536bd2938c180a84867bc8f04
7
+ data.tar.gz: 5f8a73f4038e26f8173739bafa40af575b8599e2318e947943b31d91c21d5b0ea36847f69eb25d094b5202128a81dc8ebb3dac33be64a33ce9ec9c02da435d99
@@ -1,3 +1,12 @@
1
+ # v0.3.0 2018-03-12
2
+
3
+ ### Added
4
+
5
+ * Support for multi-index relations via `schema(multi: true)` (solnic)
6
+ * Datasets can be configured to include `_metadata` in resulting tuples (solnic)
7
+
8
+ [Compare v0.2.1...v0.3.0](https://github.com/rom-rb/rom-elasticsearch/compare/v0.2.1...v0.3.0)
9
+
1
10
  # v0.2.1 2018-02-06
2
11
 
3
12
  ### Fixed
@@ -41,10 +41,31 @@ module ROM
41
41
  # @return [Hash] default body
42
42
  option :body, default: -> { EMPTY_HASH }
43
43
 
44
+ # @!attribute [r] include_metadata
45
+ # @return [Bool]
46
+ option :include_metadata, default: -> { false }
47
+
44
48
  # @!attribute [r] response
45
49
  # @return [Hash] memoized response from the client
46
50
  option :response, optional: true, reader: false
47
51
 
52
+ # @!attribute [r] tuple_proc
53
+ # @return [Proc] low-level tuple processing function used in #each
54
+ attr_reader :tuple_proc
55
+
56
+ # default tuple proc which extracts raw source data from response item
57
+ TUPLE_PROC = -> t { t[SOURCE_KEY] }
58
+
59
+ # tuple proc used when :include_metadata is enabled, resulting tuples
60
+ # will include raw response hash under _metadata key
61
+ TUPLE_PROC_WITH_METADATA = -> t { TUPLE_PROC[t].merge(_metadata: t) }
62
+
63
+ # @api private
64
+ def initialize(*args)
65
+ super
66
+ @tuple_proc = options[:include_metadata] ? TUPLE_PROC_WITH_METADATA : TUPLE_PROC
67
+ end
68
+
48
69
  # Put new data under configured index
49
70
  #
50
71
  # @param [Hash] data
@@ -109,9 +130,7 @@ module ROM
109
130
  # @api public
110
131
  def each
111
132
  return to_enum unless block_given?
112
- view.each do |result|
113
- yield(result[SOURCE_KEY])
114
- end
133
+ view.each { |result| yield(tuple_proc[result]) }
115
134
  rescue ::Elasticsearch::Transport::Transport::Error => e
116
135
  raise SearchError.new(e, options)
117
136
  end
@@ -4,6 +4,7 @@ require 'uri'
4
4
  require 'rom/gateway'
5
5
  require 'rom/support/inflector'
6
6
  require 'rom/elasticsearch/dataset'
7
+ require 'rom/elasticsearch/index_name'
7
8
 
8
9
  module ROM
9
10
  module Elasticsearch
@@ -73,7 +74,8 @@ module ROM
73
74
  #
74
75
  # @api public
75
76
  def dataset(index)
76
- Dataset.new(client, params: { index: index, type: Inflector.singularize(index).to_sym })
77
+ idx_name = IndexName[index]
78
+ Dataset.new(client, params: { index: idx_name.to_sym, type: idx_name.type })
77
79
  end
78
80
  alias_method :[], :dataset
79
81
  end
@@ -0,0 +1,40 @@
1
+ require 'rom/support/inflector'
2
+
3
+ module ROM
4
+ module Elasticsearch
5
+ # @api private
6
+ class IndexName
7
+ # @api private
8
+ attr_reader :name
9
+
10
+ # @api private
11
+ attr_reader :types
12
+
13
+ def self.[](name, types = nil)
14
+ if name.is_a?(self)
15
+ name
16
+ else
17
+ new(name, types)
18
+ end
19
+ end
20
+
21
+ # @api private
22
+ def initialize(name, types = nil)
23
+ @name = name
24
+ @types = types
25
+ freeze
26
+ end
27
+
28
+ # @api private
29
+ def type
30
+ types ? Array(types).join(',') : Inflector.singularize(name).to_sym
31
+ end
32
+
33
+ # @api private
34
+ def to_sym
35
+ name
36
+ end
37
+ end
38
+
39
+ end
40
+ end
@@ -1,4 +1,6 @@
1
1
  require 'rom/relation'
2
+
3
+ require 'rom/elasticsearch/index_name'
2
4
  require 'rom/elasticsearch/relation/loaded'
3
5
  require 'rom/elasticsearch/types'
4
6
  require 'rom/elasticsearch/schema'
@@ -90,6 +92,25 @@ module ROM
90
92
  # @param [Hash] index_settings_hash
91
93
  defines :index_settings
92
94
 
95
+ # @!method self.multi_index_types
96
+ # Manage index types for multi-index search
97
+ #
98
+ # @overload multi_index_types
99
+ # @return [Array<Symbol>] a list of index types
100
+ #
101
+ # @overload multi_index_types(types)
102
+ # @return [Array<Symbol>] a list of index types
103
+ #
104
+ # @example
105
+ # class Search < ROM::Relation[:elasticsearch]
106
+ # multi_index_types :pages, :posts
107
+ #
108
+ # schema(multi: true) do
109
+ # # define your schema
110
+ # end
111
+ # end
112
+ defines :multi_index_types
113
+
93
114
  schema_class Elasticsearch::Schema
94
115
  schema_attr_class Elasticsearch::Attribute
95
116
 
@@ -120,6 +141,17 @@ module ROM
120
141
  } }.freeze
121
142
  )
122
143
 
144
+ # Define a schema for the relation
145
+ #
146
+ # @return [self]
147
+ def self.schema(dataset = nil, multi: false, **opts, &block)
148
+ if multi
149
+ super(IndexName[:_all, multi_index_types], **opts, &block)
150
+ else
151
+ super(dataset, **opts, &block)
152
+ end
153
+ end
154
+
123
155
  # Load a relation
124
156
  #
125
157
  # @return [Loaded]
@@ -286,7 +318,7 @@ module ROM
286
318
  #
287
319
  # @api private
288
320
  def index_params
289
- { index: name.dataset,
321
+ { index: name.dataset.to_sym,
290
322
  body: {
291
323
  settings: self.class.index_settings,
292
324
  mappings: { dataset.type => { properties: schema.to_properties } } } }
@@ -1,5 +1,5 @@
1
1
  module ROM
2
2
  module Elasticsearch
3
- VERSION = '0.2.1'.freeze
3
+ VERSION = '0.3.0'.freeze
4
4
  end
5
5
  end
@@ -0,0 +1,60 @@
1
+ RSpec.describe ROM::Elasticsearch::Relation, '.schema' do
2
+ subject(:relation) { relations[:search] }
3
+
4
+ include_context 'setup'
5
+
6
+ let(:posts) { relations[:posts] }
7
+ let(:pages) { relations[:pages] }
8
+
9
+ before do
10
+ conf.relation(:posts) do
11
+ schema(:posts) do
12
+ attribute :id, ROM::Elasticsearch::Types::ID
13
+ attribute :title, ROM::Elasticsearch::Types.Text
14
+ end
15
+ end
16
+
17
+ conf.relation(:pages) do
18
+ schema(:pages) do
19
+ attribute :id, ROM::Elasticsearch::Types::ID
20
+ attribute :title, ROM::Elasticsearch::Types.Text
21
+ end
22
+ end
23
+
24
+ conf.relation(:search) do
25
+ multi_index_types %i[post page]
26
+
27
+ schema(multi: true) do
28
+ attribute :id, ROM::Elasticsearch::Types::ID
29
+ attribute :title, ROM::Elasticsearch::Types.Text
30
+ end
31
+ end
32
+
33
+ posts.create_index
34
+ pages.create_index
35
+ end
36
+
37
+ after do
38
+ posts.delete_index
39
+ pages.delete_index
40
+ end
41
+
42
+ it 'search through specified indices' do
43
+ posts.command(:create).call(id: 1, title: 'Post 1')
44
+ posts.command(:create).call(id: 2, title: 'Post 2')
45
+
46
+ pages.command(:create).call(id: 1, title: 'Page 1')
47
+ pages.command(:create).call(id: 2, title: 'Page 2')
48
+
49
+ posts.refresh
50
+ pages.refresh
51
+
52
+ result = relation.query(match: { title: 'Post'})
53
+
54
+ expect(result.to_a).to eql([{ id: 1, title: 'Post 1'}, { id: 2, title: 'Post 2'}])
55
+
56
+ result = relation.query(match: { title: '1'})
57
+
58
+ expect(result.to_a).to eql([{ id: 1, title: 'Page 1'}, { id: 1, title: 'Post 1'}])
59
+ end
60
+ end
@@ -23,4 +23,29 @@ RSpec.describe ROM::Elasticsearch::Relation, '#dataset' do
23
23
  expect(relation.dataset.type).to eql(:user)
24
24
  end
25
25
  end
26
+
27
+ context 'overridding default dataset object' do
28
+ let(:users) { relations[:users] }
29
+
30
+ before do
31
+ conf.relation(:users) do
32
+ dataset do
33
+ with(include_metadata: true)
34
+ end
35
+
36
+ schema do
37
+ attribute :id, ROM::Types::Int
38
+ attribute :name, ROM::Types::String
39
+ attribute :_metadata, ROM::Types::Hash.symbolized(_index: 'string')
40
+ end
41
+ end
42
+
43
+ users.create_index
44
+ users.command(:create).call(id: 1, name: 'Jane')
45
+ end
46
+
47
+ it 'uses customized dataset' do
48
+ expect(relation.to_a).to eql([{ id: 1, name: 'Jane', _metadata: { _index: 'users' } }])
49
+ end
50
+ end
26
51
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rom-elasticsearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hannes Nevalainen
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-02-06 00:00:00.000000000 Z
12
+ date: 2018-03-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rom-core
@@ -108,6 +108,7 @@ files:
108
108
  - lib/rom/elasticsearch/dataset.rb
109
109
  - lib/rom/elasticsearch/errors.rb
110
110
  - lib/rom/elasticsearch/gateway.rb
111
+ - lib/rom/elasticsearch/index_name.rb
111
112
  - lib/rom/elasticsearch/plugins/relation/query_dsl.rb
112
113
  - lib/rom/elasticsearch/query_methods.rb
113
114
  - lib/rom/elasticsearch/relation.rb
@@ -117,6 +118,7 @@ files:
117
118
  - lib/rom/elasticsearch/version.rb
118
119
  - rom-elasticsearch.gemspec
119
120
  - spec/integration/rom/elasticsearch/relation/command_spec.rb
121
+ - spec/integration/rom/elasticsearch/relation/multi_index_spec.rb
120
122
  - spec/integration/rom/elasticsearch/relation/schema_spec.rb
121
123
  - spec/shared/setup.rb
122
124
  - spec/shared/unit/user_fixtures.rb
@@ -169,6 +171,7 @@ specification_version: 4
169
171
  summary: ROM adapter for Elasticsearch
170
172
  test_files:
171
173
  - spec/integration/rom/elasticsearch/relation/command_spec.rb
174
+ - spec/integration/rom/elasticsearch/relation/multi_index_spec.rb
172
175
  - spec/integration/rom/elasticsearch/relation/schema_spec.rb
173
176
  - spec/shared/setup.rb
174
177
  - spec/shared/unit/user_fixtures.rb