Skip to content

Commit

Permalink
Merge pull request #201 from serggl/bugfix/200
Browse files Browse the repository at this point in the history
[fixes #200] Fix JSON generator for atomic updates of array fields
  • Loading branch information
jrochkind committed Dec 15, 2021
2 parents 0f2ce40 + 0453b0d commit 25a3bf0
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 2 deletions.
11 changes: 9 additions & 2 deletions lib/rsolr/document.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module RSolr
class Document
CHILD_DOCUMENT_KEY = '_childDocuments_'.freeze
ATOMIC_MULTI_VALUE_OPERATIONS = %i[set add add-distinct remove]

# "attrs" is a hash for setting the "doc" xml attributes
# "fields" is an array of Field objects
Expand Down Expand Up @@ -48,8 +49,14 @@ def add_field(name, values, options = {})
def as_json
@fields.group_by(&:name).each_with_object({}) do |(field, values), result|
v = values.map(&:as_json)
if v.length > 1 && v.first.is_a?(Hash) && v.first.key?(:value)
v = v.first.merge(value: v.map { |single| single[:value] })
if v.length > 1 && v.first.is_a?(Hash)
if v.first.key?(:value)
v = v.first.merge(value: v.map { |single| single[:value] })
else
(v.first.keys & ATOMIC_MULTI_VALUE_OPERATIONS).each do |op|
v = [{ op => v.map { |single| single[op] } }]
end
end
end
v = v.first if v.length == 1 && field.to_s != CHILD_DOCUMENT_KEY
result[field] = v
Expand Down
50 changes: 50 additions & 0 deletions spec/api/json_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,56 @@ def to_h
expect(message).to eq [{ id: '1', name: { boost: 3, value: test_values } }]
end

context 'for atomic updates with arrays' do
let(:test_values) { %w[value1 value2] }

it 'creates single field from array values on SET' do
expect(
JSON.parse(
generator.add(id: 'set-id') { |doc| doc.add_field(:name, test_values, update: :set) },
symbolize_names: true
)
).to eq [{ id: 'set-id', name: { set: test_values } }]
end

it 'creates single field from array values on ADD' do
expect(
JSON.parse(
generator.add(id: 'add-id') { |doc| doc.add_field(:name, test_values, update: :add) },
symbolize_names: true
)
).to eq [{ id: 'add-id', name: { add: test_values } }]
end

it 'creates single field from array values on ADD-DISTINCT' do
expect(
JSON.parse(
generator.add(id: 'add-distinct-id') { |doc| doc.add_field(:name, test_values, update: :'add-distinct') },
symbolize_names: true
)
).to eq [{ id: 'add-distinct-id', name: { 'add-distinct': test_values } }]
end

it 'creates single field from array values on REMOVE' do
expect(
JSON.parse(
generator.add(id: 'remove-id') { |doc| doc.add_field(:name, test_values, update: :remove) },
symbolize_names: true
)
).to eq [{ id: 'remove-id', name: { remove: test_values } }]
end

it 'creates single field from array values for child document update' do
test_nested_values = [{id: 1, name: 'value1'}, {id: 1, name: 'value2'}]
expect(
JSON.parse(
generator.add(id: 'set-id') { |doc| doc.add_field(:child_documents, test_nested_values, update: :set) },
symbolize_names: true
)
).to eq [{ id: 'set-id', child_documents: { set: test_nested_values } }]
end
end

describe '#commit' do
it 'generates a commit command' do
expect(JSON.parse(generator.commit, symbolize_names: true)).to eq(commit: {})
Expand Down

0 comments on commit 25a3bf0

Please sign in to comment.