elasticsearch-persistence 2.0.1 → 5.0.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 +4 -4
- data/README.md +1 -1
- data/elasticsearch-persistence.gemspec +1 -1
- data/examples/music/album.rb +23 -2
- data/examples/music/artist.rb +25 -5
- data/examples/music/artists/index.html.erb +5 -2
- data/examples/music/artists/show.html.erb +46 -43
- data/examples/music/assets/application.css +34 -3
- data/examples/music/assets/blank_artist.png +0 -0
- data/examples/music/index_manager.rb +31 -18
- data/examples/music/search/index.html.erb +10 -8
- data/examples/music/search/search_controller_test.rb +5 -2
- data/examples/music/suggester.rb +50 -26
- data/examples/music/template.rb +75 -38
- data/examples/music/vendor/assets/stylesheets/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/examples/notes/Gemfile +2 -2
- data/examples/notes/application.rb +3 -3
- data/lib/elasticsearch/persistence.rb +4 -1
- data/lib/elasticsearch/persistence/model.rb +1 -1
- data/lib/elasticsearch/persistence/model/base.rb +1 -1
- data/lib/elasticsearch/persistence/model/find.rb +8 -11
- data/lib/elasticsearch/persistence/repository/response/results.rb +2 -2
- data/lib/elasticsearch/persistence/repository/search.rb +12 -2
- data/lib/elasticsearch/persistence/version.rb +1 -1
- data/test/integration/repository/virtus_model_test.rb +5 -1
- data/test/unit/model_find_test.rb +7 -5
- data/test/unit/model_gateway_test.rb +1 -1
- data/test/unit/repository_indexing_test.rb +1 -1
- data/test/unit/repository_response_results_test.rb +1 -1
- data/test/unit/repository_search_test.rb +9 -9
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0de349098f6228ded1b437402e5a39476f0e0ef5
|
4
|
+
data.tar.gz: 1d4b0d9a0842cae6fe45e279eac6d63957604082
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e75f259f5152a34730ceecd9d05ac182d67cb036c06c97c6ed6938c2cf5ea02bf7e5fec7d37a3064cabaf15ae4a5c9fab1c5be235ff138f3a0c714f9e5d93b7
|
7
|
+
data.tar.gz: 8e1ae7bb7659b42c21136fc0bac8624f92e98aa6f102c04fddfac7d9299ad6c376d96af4ff371dd293aff0648d84287446b9251b6f96fe590ab5918b349702bf
|
data/README.md
CHANGED
@@ -593,7 +593,7 @@ retrieve big collections of model instances, using the Elasticsearch's _Scan API
|
|
593
593
|
|
594
594
|
```ruby
|
595
595
|
Article.find_each(_source_include: 'title') { |a| puts "===> #{a.title.upcase}" }
|
596
|
-
# GET http://localhost:9200/articles/article/_search?scroll=5m&
|
596
|
+
# GET http://localhost:9200/articles/article/_search?scroll=5m&size=20
|
597
597
|
# GET http://localhost:9200/_search/scroll?scroll=5m&scroll_id=c2Nhb...
|
598
598
|
# ===> TEST
|
599
599
|
# GET http://localhost:9200/_search/scroll?scroll=5m&scroll_id=c2Nhb...
|
@@ -23,7 +23,7 @@ Gem::Specification.new do |s|
|
|
23
23
|
|
24
24
|
s.required_ruby_version = ">= 1.9.3"
|
25
25
|
|
26
|
-
s.add_dependency "elasticsearch", '
|
26
|
+
s.add_dependency "elasticsearch", '> 1'
|
27
27
|
s.add_dependency "elasticsearch-model", '>= 0.1'
|
28
28
|
s.add_dependency "activesupport", '> 4'
|
29
29
|
s.add_dependency "activemodel", '> 4'
|
data/examples/music/album.rb
CHANGED
@@ -12,9 +12,8 @@ class Album
|
|
12
12
|
|
13
13
|
index_name [Rails.application.engine_name, Rails.env].join('-')
|
14
14
|
|
15
|
+
|
15
16
|
mapping _parent: { type: 'artist' } do
|
16
|
-
indexes :suggest_title, type: 'completion', payloads: true
|
17
|
-
indexes :suggest_track, type: 'completion', payloads: true
|
18
17
|
end
|
19
18
|
|
20
19
|
attribute :artist
|
@@ -30,4 +29,26 @@ class Album
|
|
30
29
|
|
31
30
|
attribute :styles
|
32
31
|
attribute :meta, Meta, mapping: { type: 'object' }
|
32
|
+
|
33
|
+
attribute :suggest, Hashie::Mash, mapping: {
|
34
|
+
type: 'object',
|
35
|
+
properties: {
|
36
|
+
title: {
|
37
|
+
type: 'object',
|
38
|
+
properties: {
|
39
|
+
input: { type: 'completion' },
|
40
|
+
output: { type: 'keyword', index: false },
|
41
|
+
payload: { type: 'object', enabled: false }
|
42
|
+
}
|
43
|
+
},
|
44
|
+
track: {
|
45
|
+
type: 'object',
|
46
|
+
properties: {
|
47
|
+
input: { type: 'completion' },
|
48
|
+
output: { type: 'keyword', index: false },
|
49
|
+
payload: { type: 'object', enabled: false }
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
33
54
|
end
|
data/examples/music/artist.rb
CHANGED
@@ -4,23 +4,43 @@ class Artist
|
|
4
4
|
index_name [Rails.application.engine_name, Rails.env].join('-')
|
5
5
|
|
6
6
|
analyzed_and_raw = { fields: {
|
7
|
-
name: { type: '
|
8
|
-
raw: { type: '
|
7
|
+
name: { type: 'text', analyzer: 'snowball' },
|
8
|
+
raw: { type: 'keyword' }
|
9
9
|
} }
|
10
10
|
|
11
11
|
attribute :name, String, mapping: analyzed_and_raw
|
12
|
-
attribute :suggest_name, String, default: {}, mapping: { type: 'completion', payloads: true }
|
13
12
|
|
14
13
|
attribute :profile
|
15
14
|
attribute :date, Date
|
16
15
|
|
17
16
|
attribute :members, String, default: [], mapping: analyzed_and_raw
|
18
17
|
attribute :members_combined, String, default: [], mapping: { analyzer: 'snowball' }
|
19
|
-
attribute :suggest_member, String, default: {}, mapping: { type: 'completion', payloads: true }
|
20
18
|
|
21
19
|
attribute :urls, String, default: []
|
22
20
|
attribute :album_count, Integer, default: 0
|
23
21
|
|
22
|
+
attribute :suggest, Hashie::Mash, mapping: {
|
23
|
+
type: 'object',
|
24
|
+
properties: {
|
25
|
+
name: {
|
26
|
+
type: 'object',
|
27
|
+
properties: {
|
28
|
+
input: { type: 'completion' },
|
29
|
+
output: { type: 'keyword', index: false },
|
30
|
+
payload: { type: 'object', enabled: false }
|
31
|
+
}
|
32
|
+
},
|
33
|
+
member: {
|
34
|
+
type: 'object',
|
35
|
+
properties: {
|
36
|
+
input: { type: 'completion' },
|
37
|
+
output: { type: 'keyword', index: false },
|
38
|
+
payload: { type: 'object', enabled: false }
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
24
44
|
validates :name, presence: true
|
25
45
|
|
26
46
|
def albums
|
@@ -29,7 +49,7 @@ class Artist
|
|
29
49
|
has_parent: {
|
30
50
|
type: 'artist',
|
31
51
|
query: {
|
32
|
-
|
52
|
+
bool: {
|
33
53
|
filter: {
|
34
54
|
ids: { values: [ self.id ] }
|
35
55
|
}
|
@@ -15,6 +15,7 @@
|
|
15
15
|
<% @artists.each do |artist| %>
|
16
16
|
<%= div_for artist, class: 'result clearfix' do %>
|
17
17
|
<h2>
|
18
|
+
<%= image_tag "http://ruby.elastic.co.s3-website-us-east-1.amazonaws.com/demo/music/bands/#{artist.id}.jpeg", height: '50px', class: 'band' %>
|
18
19
|
<%= link_to artist do %>
|
19
20
|
<span class="name"><%= artist.name %></span>
|
20
21
|
<small><%= pluralize artist.album_count, 'album' %></small>
|
@@ -41,7 +42,7 @@ $.widget( "custom.suggest", $.ui.autocomplete, {
|
|
41
42
|
var category = ul.append( "<li class='ui-autocomplete-category'>" + item.label + "</li>" );
|
42
43
|
|
43
44
|
$.each( item.value, function( index, item ) {
|
44
|
-
var li = $('<li class="ui-autocomplete-item"><a href="<%= Rails.application.config.relative_url_root %>'+ item.
|
45
|
+
var li = $('<li class="ui-autocomplete-item"><a href="<%= Rails.application.config.relative_url_root %>'+ item.url +'">'+ item.text +'</a></li>').data('ui-autocomplete-item', item )
|
45
46
|
category.append(li)
|
46
47
|
} )
|
47
48
|
});
|
@@ -51,7 +52,9 @@ $.widget( "custom.suggest", $.ui.autocomplete, {
|
|
51
52
|
$( "#q" ).suggest({
|
52
53
|
source: '<%= suggest_path %>',
|
53
54
|
select: function(event, ui) {
|
54
|
-
document.location.href = '<%= Rails.application.config.relative_url_root %>'+ui.item.
|
55
|
+
document.location.href = '<%= Rails.application.config.relative_url_root %>'+ui.item.url
|
55
56
|
}
|
56
57
|
});
|
57
58
|
</script>
|
59
|
+
|
60
|
+
<script>$('img.band').error(function(){ $(this).attr('src', '/images/blank_artist.png'); });</script>
|
@@ -1,51 +1,54 @@
|
|
1
|
-
<
|
2
|
-
<
|
3
|
-
<
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
<div class="artist">
|
2
|
+
<header>
|
3
|
+
<h1>
|
4
|
+
<span class="back"><%= link_to "〈".html_safe, artists_path, title: "Back" %></span>
|
5
|
+
<%= image_tag "http://ruby.elastic.co.s3-website-us-east-1.amazonaws.com/demo/music/bands/#{@artist.id}.jpeg", height: '50px', class: 'band' %>
|
6
|
+
<%= @artist.name %>
|
7
|
+
<%= button_to 'Edit', edit_artist_path(@artist), method: 'get' %>
|
8
|
+
</h1>
|
9
|
+
</header>
|
8
10
|
|
9
|
-
<p id="notice"><%= notice %></p>
|
11
|
+
<p id="notice"><%= notice %></p>
|
10
12
|
|
11
|
-
<section class="artist-info">
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
</section>
|
13
|
+
<section class="artist-info">
|
14
|
+
<span><%= @artist.members.to_sentence last_word_connector: ' and ' %></span> |
|
15
|
+
<span><%= pluralize @albums.size, 'album' %></span>
|
16
|
+
<p class="artist-profile"><%= @artist.profile %></p>
|
17
|
+
</section>
|
16
18
|
|
17
|
-
<section class="albums">
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
<section class="albums">
|
20
|
+
<% @albums.each do |album| %>
|
21
|
+
<%= div_for album, class: 'clearfix' do %>
|
22
|
+
<h3>
|
23
|
+
<span class="title"><%= album.title %></span>
|
24
|
+
<div class="info">
|
25
|
+
<small><%= album.meta.formats.join(', ') %></small>
|
26
|
+
<small><%= album.released %></small>
|
27
|
+
</div>
|
28
|
+
</h3>
|
29
|
+
|
30
|
+
<div class="cover">
|
31
|
+
<%= image_tag "http://ruby.elastic.co.s3-website-us-east-1.amazonaws.com/demo/music/covers/#{album.id}.jpeg", width: '100px', class: 'cover' %>
|
25
32
|
</div>
|
26
|
-
</h3>
|
27
33
|
|
28
|
-
|
29
|
-
|
30
|
-
|
34
|
+
<div class="content">
|
35
|
+
<% album.tracklist.in_groups_of(album.tracklist.size/2+1).each_with_index do |half, g| %>
|
36
|
+
<ul class=<%= cycle 'first', 'second' %> start="<%= g < 1 ? 1 : album.tracklist.size/2+2 %>">
|
37
|
+
<% half.compact.each_with_index do |track, i| %>
|
38
|
+
<li>
|
39
|
+
<i class="counter"><%= g < 1 ? i+1 : i+(g*album.tracklist.size/2+2) %></i>
|
40
|
+
<%= track['title'] %>
|
41
|
+
<small><%= track['duration'] %></small>
|
42
|
+
</li>
|
43
|
+
<% end %>
|
44
|
+
</ul>
|
45
|
+
<% end %>
|
46
|
+
</div>
|
47
|
+
<% end %>
|
31
48
|
|
32
|
-
<div class="content">
|
33
|
-
<% album.tracklist.in_groups_of(album.tracklist.size/2+1).each_with_index do |half, g| %>
|
34
|
-
<ul class=<%= cycle 'first', 'second' %> start="<%= g < 1 ? 1 : album.tracklist.size/2+2 %>">
|
35
|
-
<% half.compact.each_with_index do |track, i| %>
|
36
|
-
<li>
|
37
|
-
<i class="counter"><%= g < 1 ? i+1 : i+(g*album.tracklist.size/2+2) %></i>
|
38
|
-
<%= track['title'] %>
|
39
|
-
<small><%= track['duration'] %></small>
|
40
|
-
</li>
|
41
|
-
<% end %>
|
42
|
-
</ul>
|
43
|
-
<% end %>
|
44
|
-
</div>
|
45
49
|
<% end %>
|
46
50
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
</section>
|
51
|
+
<script>$('img').error(function(){ $(this).attr('src', '/images/blank_cover.png'); });</script>
|
52
|
+
<script>$(document.location.hash).effect('highlight', 1500)</script>
|
53
|
+
</section>
|
54
|
+
</div>
|
@@ -100,6 +100,20 @@ h1 form {
|
|
100
100
|
|
101
101
|
.artist h2 {
|
102
102
|
float: left;
|
103
|
+
margin-left: 50px;
|
104
|
+
}
|
105
|
+
|
106
|
+
.artist.search.result h2 {
|
107
|
+
float: none;
|
108
|
+
}
|
109
|
+
|
110
|
+
.artist h1 .back {
|
111
|
+
margin-right: 65px;
|
112
|
+
}
|
113
|
+
|
114
|
+
.artist h1 img.band {
|
115
|
+
left: 120px;
|
116
|
+
top: 50px;
|
103
117
|
}
|
104
118
|
|
105
119
|
.result h2 a,
|
@@ -124,17 +138,17 @@ h1 form {
|
|
124
138
|
text-decoration: underline;
|
125
139
|
}
|
126
140
|
|
127
|
-
.result .small {
|
141
|
+
.result .highlight.small {
|
128
142
|
font-size: 90%;
|
129
143
|
font-weight: 200;
|
130
144
|
padding: 0;
|
131
|
-
margin: 0.25em 0 0.25em
|
145
|
+
margin: 0.25em 0 0.25em 50px;
|
132
146
|
}
|
133
147
|
|
134
148
|
.result .small .label {
|
135
149
|
color: #999;
|
136
150
|
font-size: 80%;
|
137
|
-
min-width: 5em
|
151
|
+
/*min-width: 5em;*/
|
138
152
|
display: inline-block;
|
139
153
|
}
|
140
154
|
|
@@ -156,15 +170,32 @@ h1 form {
|
|
156
170
|
margin: 0.25em 0 0 0;
|
157
171
|
}
|
158
172
|
|
173
|
+
.artist img.band {
|
174
|
+
position: absolute;
|
175
|
+
left: 85px;
|
176
|
+
margin-top: 14px;
|
177
|
+
transform: translate(-50%,-50%);
|
178
|
+
clip-path: circle(20px at center);
|
179
|
+
}
|
180
|
+
|
159
181
|
.album {
|
160
182
|
margin: 0 0 4em 0;
|
161
183
|
}
|
162
184
|
|
185
|
+
.album.search.result {
|
186
|
+
margin: 0;
|
187
|
+
}
|
188
|
+
|
163
189
|
.album .cover {
|
164
190
|
float: left;
|
165
191
|
width: 150px;
|
166
192
|
}
|
167
193
|
|
194
|
+
.album.search.result .cover {
|
195
|
+
width: 40px;
|
196
|
+
margin-right: 10px;
|
197
|
+
}
|
198
|
+
|
168
199
|
.album .cover img {
|
169
200
|
border: 1px solid rgba(0,0,0,0.15);
|
170
201
|
box-shadow: 0px 0px 1px 0px rgba(0,0,0,0.05);
|
Binary file
|
@@ -26,33 +26,46 @@ class IndexManager
|
|
26
26
|
Artist.create artist.update(
|
27
27
|
'album_count' => artist['releases'].size,
|
28
28
|
'members_combined' => artist['members'].join(', '),
|
29
|
-
'
|
30
|
-
'
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
'
|
29
|
+
'suggest' => {
|
30
|
+
'name' => {
|
31
|
+
'input' => { 'input' => artist['namevariations'].unshift(artist['name']).reject { |d| d.to_s.empty? } },
|
32
|
+
'output' => artist['name'],
|
33
|
+
'payload' => {
|
34
|
+
'url' => "/artists/#{artist['id']}"
|
35
|
+
}
|
36
|
+
},
|
37
|
+
'member' => {
|
38
|
+
'input' => { 'input' => artist['members'] },
|
39
|
+
'output' => artist['name'],
|
40
|
+
'payload' => {
|
41
|
+
'url' => "/artists/#{artist['id']}"
|
42
|
+
}
|
43
|
+
}
|
38
44
|
}
|
39
45
|
)
|
40
46
|
|
41
47
|
artist['releases'].each do |album|
|
42
48
|
album.update(
|
43
|
-
'
|
44
|
-
'
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
'
|
49
|
+
'suggest' => {
|
50
|
+
'title' => {
|
51
|
+
'input' => { 'input' => album['title'] },
|
52
|
+
'output' => album['title'],
|
53
|
+
'payload' => {
|
54
|
+
'url' => "/artists/#{artist['id']}#album_#{album['id']}"
|
55
|
+
}
|
56
|
+
},
|
57
|
+
'track' => {
|
58
|
+
'input' => { 'input' => album['tracklist'].map { |d| d['title'] }.reject { |d| d.to_s.empty? } },
|
59
|
+
'output' => album['title'],
|
60
|
+
'payload' => {
|
61
|
+
'url' => "/artists/#{artist['id']}#album_#{album['id']}"
|
62
|
+
}
|
63
|
+
}
|
52
64
|
}
|
53
65
|
)
|
54
66
|
album['notes'] = album['notes'].to_s.gsub(/<.+?>/, '').gsub(/ {2,}/, '')
|
55
67
|
album['released'] = nil if album['released'] < 1
|
68
|
+
|
56
69
|
Album.create album, id: album['id'], parent: artist['id']
|
57
70
|
end
|
58
71
|
end
|
@@ -13,21 +13,22 @@
|
|
13
13
|
|
14
14
|
<section class="artists">
|
15
15
|
<% @artists.each do |artist| %>
|
16
|
-
<%= content_tag :div, class: 'result clearfix' do %>
|
16
|
+
<%= content_tag :div, class: 'artist search result clearfix' do %>
|
17
17
|
<h2>
|
18
|
+
<%= image_tag "http://ruby.elastic.co.s3-website-us-east-1.amazonaws.com/demo/music/bands/#{artist.id}.jpeg", height: '45px', class: 'band' %>
|
18
19
|
<%= link_to artist do %>
|
19
20
|
<span class="name"><%= highlighted(artist, :name) %></span>
|
20
21
|
<small><%= pluralize artist.album_count, 'album' %></small>
|
21
22
|
<% end %>
|
22
23
|
</h2>
|
23
24
|
<% if highlight = highlight(artist, :members_combined) %>
|
24
|
-
<p class="small">
|
25
|
+
<p class="highlight small">
|
25
26
|
<span class="label">Members</span>
|
26
27
|
<%= highlight.first.html_safe %>
|
27
28
|
</p>
|
28
29
|
<% end %>
|
29
30
|
<% if highlight = highlight(artist, :profile) %>
|
30
|
-
<p class="small">
|
31
|
+
<p class="highlight small">
|
31
32
|
<span class="label">Profile</span>
|
32
33
|
<%= highlight.join('…').html_safe %>
|
33
34
|
</p>
|
@@ -38,8 +39,9 @@
|
|
38
39
|
|
39
40
|
<section class="albums">
|
40
41
|
<% @albums.each do |album| %>
|
41
|
-
<%= content_tag :div, class: 'result clearfix' do %>
|
42
|
+
<%= content_tag :div, class: 'album search result clearfix' do %>
|
42
43
|
<h2>
|
44
|
+
<%= image_tag "http://ruby.elastic.co.s3-website-us-east-1.amazonaws.com/demo/music/covers/#{album.id}.jpeg", width: '45px', class: 'cover' %>
|
43
45
|
<%= link_to artist_path(album.artist_id, anchor: "album_#{album.id}") do %>
|
44
46
|
<span class="name"><%= highlighted(album, :title) %></span>
|
45
47
|
<small><%= album.artist %></small>
|
@@ -48,14 +50,14 @@
|
|
48
50
|
</h2>
|
49
51
|
|
50
52
|
<% if highlight = highlight(album, 'tracklist.title') %>
|
51
|
-
<p class="small">
|
53
|
+
<p class="highlight small">
|
52
54
|
<span class="label">Tracks</span>
|
53
55
|
<%= highlight.join('…').html_safe %>
|
54
56
|
</p>
|
55
57
|
<% end %>
|
56
58
|
|
57
59
|
<% if highlight = highlight(album, :notes) %>
|
58
|
-
<p class="small">
|
60
|
+
<p class="highlight small">
|
59
61
|
<span class="label">Notes</span>
|
60
62
|
<%= highlight.map { |d| d.gsub(/^\.\s?/, '') }.join('…').html_safe %>
|
61
63
|
</p>
|
@@ -77,7 +79,7 @@ $.widget( "custom.suggest", $.ui.autocomplete, {
|
|
77
79
|
var category = ul.append( "<li class='ui-autocomplete-category'>" + item.label + "</li>" );
|
78
80
|
|
79
81
|
$.each( item.value, function( index, item ) {
|
80
|
-
var li = $('<li class="ui-autocomplete-item"><a href="<%= Rails.application.config.relative_url_root %>'+ item.
|
82
|
+
var li = $('<li class="ui-autocomplete-item"><a href="<%= Rails.application.config.relative_url_root %>'+ item.url +'">'+ item.text +'</a></li>').data('ui-autocomplete-item', item )
|
81
83
|
category.append(li)
|
82
84
|
} )
|
83
85
|
});
|
@@ -87,7 +89,7 @@ $.widget( "custom.suggest", $.ui.autocomplete, {
|
|
87
89
|
$( "#q" ).suggest({
|
88
90
|
source: '<%= suggest_path %>',
|
89
91
|
select: function(event, ui) {
|
90
|
-
document.location.href = '<%= Rails.application.config.relative_url_root %>'+ui.item.
|
92
|
+
document.location.href = '<%= Rails.application.config.relative_url_root %>'+ui.item.url
|
91
93
|
}
|
92
94
|
});
|
93
95
|
</script>
|
@@ -1,9 +1,12 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class SearchControllerTest < ActionController::TestCase
|
4
|
+
setup do
|
5
|
+
IndexManager.create_index force: true
|
6
|
+
end
|
7
|
+
|
4
8
|
test "should get suggest" do
|
5
|
-
get :suggest
|
9
|
+
get :suggest, term: 'foo'
|
6
10
|
assert_response :success
|
7
11
|
end
|
8
|
-
|
9
12
|
end
|
data/examples/music/suggester.rb
CHANGED
@@ -7,39 +7,63 @@ class Suggester
|
|
7
7
|
|
8
8
|
def response
|
9
9
|
@response ||= begin
|
10
|
-
Elasticsearch::Persistence.client.
|
10
|
+
Elasticsearch::Persistence.client.search \
|
11
11
|
index: Artist.index_name,
|
12
12
|
body: {
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
suggest: {
|
14
|
+
artists: {
|
15
|
+
text: @term,
|
16
|
+
completion: { field: 'suggest.name.input', size: 25 }
|
17
|
+
},
|
18
|
+
members: {
|
19
|
+
text: @term,
|
20
|
+
completion: { field: 'suggest.member.input', size: 25 }
|
21
|
+
},
|
22
|
+
albums: {
|
23
|
+
text: @term,
|
24
|
+
completion: { field: 'suggest.title.input', size: 25 }
|
25
|
+
},
|
26
|
+
tracks: {
|
27
|
+
text: @term,
|
28
|
+
completion: { field: 'suggest.track.input', size: 25 }
|
29
|
+
}
|
16
30
|
},
|
17
|
-
|
18
|
-
text: @term,
|
19
|
-
completion: { field: 'suggest_member', size: 25 }
|
20
|
-
},
|
21
|
-
albums: {
|
22
|
-
text: @term,
|
23
|
-
completion: { field: 'suggest_title', size: 25 }
|
24
|
-
},
|
25
|
-
tracks: {
|
26
|
-
text: @term,
|
27
|
-
completion: { field: 'suggest_track', size: 25 }
|
28
|
-
}
|
31
|
+
_source: ['suggest.*']
|
29
32
|
}
|
30
33
|
end
|
31
34
|
end
|
32
35
|
|
33
36
|
def as_json(options={})
|
34
|
-
response
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
37
|
+
return [] unless response['suggest']
|
38
|
+
|
39
|
+
output = [
|
40
|
+
{ label: 'Bands',
|
41
|
+
value: response['suggest']['artists'][0]['options'].map do |d|
|
42
|
+
{ text: d['_source']['suggest']['name']['output'],
|
43
|
+
url: d['_source']['suggest']['name']['payload']['url'] }
|
44
|
+
end
|
45
|
+
},
|
46
|
+
|
47
|
+
{ label: 'Albums',
|
48
|
+
value: response['suggest']['albums'][0]['options'].map do |d|
|
49
|
+
{ text: d['_source']['suggest']['title']['output'],
|
50
|
+
url: d['_source']['suggest']['title']['payload']['url'] }
|
51
|
+
end
|
52
|
+
},
|
53
|
+
|
54
|
+
{ label: 'Band Members',
|
55
|
+
value: response['suggest']['members'][0]['options'].map do |d|
|
56
|
+
{ text: "#{d['text']} (#{d['_source']['suggest']['member']['output']})",
|
57
|
+
url: d['_source']['suggest']['member']['payload']['url'] }
|
58
|
+
end
|
59
|
+
},
|
60
|
+
|
61
|
+
{ label: 'Album Tracks',
|
62
|
+
value: response['suggest']['tracks'][0]['options'].map do |d|
|
63
|
+
{ text: "#{d['text']} (#{d['_source']['suggest']['track']['output']})",
|
64
|
+
url: d['_source']['suggest']['track']['payload']['url'] }
|
65
|
+
end
|
66
|
+
}
|
67
|
+
]
|
44
68
|
end
|
45
69
|
end
|
data/examples/music/template.rb
CHANGED
@@ -11,8 +11,8 @@
|
|
11
11
|
#
|
12
12
|
# * Git
|
13
13
|
# * Ruby >= 1.9.3
|
14
|
-
# * Rails >=
|
15
|
-
# * Java >=
|
14
|
+
# * Rails >= 5
|
15
|
+
# * Java >= 8 (for Elasticsearch)
|
16
16
|
#
|
17
17
|
# Usage:
|
18
18
|
# ------
|
@@ -25,6 +25,7 @@ STDOUT.sync = true
|
|
25
25
|
STDERR.sync = true
|
26
26
|
|
27
27
|
require 'uri'
|
28
|
+
require 'json'
|
28
29
|
require 'net/http'
|
29
30
|
|
30
31
|
at_exit do
|
@@ -35,29 +36,32 @@ at_exit do
|
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
38
|
-
|
39
|
+
$elasticsearch_url = ENV.fetch('ELASTICSEARCH_URL', 'http://localhost:9200')
|
39
40
|
|
40
|
-
|
41
|
+
# ----- Check & download Elasticsearch ------------------------------------------------------------
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
git commit: "-m 'Initial commit: Clean application'"
|
43
|
+
cluster_info = Net::HTTP.get(URI.parse($elasticsearch_url)) rescue nil
|
44
|
+
cluster_info = JSON.parse(cluster_info) if cluster_info
|
45
45
|
|
46
|
-
|
46
|
+
if cluster_info.nil? || cluster_info['version']['number'] < '5'
|
47
|
+
# Change the port when incompatible Elasticsearch version is running on localhost:9200
|
48
|
+
if $elasticsearch_url == 'http://localhost:9200' && cluster_info && cluster_info['version']['number'] < '5'
|
49
|
+
$change_port = '9280'
|
50
|
+
$elasticsearch_url = "http://localhost:#{$change_port}"
|
51
|
+
end
|
47
52
|
|
48
|
-
unless (Net::HTTP.get(URI.parse('http://localhost:9200')) rescue false)
|
49
53
|
COMMAND = <<-COMMAND.gsub(/^ /, '')
|
50
|
-
curl -# -O "
|
51
|
-
tar -zxf elasticsearch-
|
52
|
-
rm -f elasticsearch-
|
53
|
-
./elasticsearch-
|
54
|
+
curl -# -O "https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.2.1.tar.gz"
|
55
|
+
tar -zxf elasticsearch-5.2.1.tar.gz
|
56
|
+
rm -f elasticsearch-5.2.1.tar.gz
|
57
|
+
./elasticsearch-5.2.1/bin/elasticsearch -d -p #{destination_root}/tmp/pids/elasticsearch.pid #{$change_port.nil? ? '' : "-E http.port=#{$change_port}" }
|
54
58
|
COMMAND
|
55
59
|
|
56
60
|
puts "\n"
|
57
61
|
say_status "ERROR", "Elasticsearch not running!\n", :red
|
58
62
|
puts '-'*80
|
59
|
-
say_status '', "It appears that Elasticsearch is not running on this machine."
|
60
|
-
say_status '', "Is it installed? Do you want me to install it for you with this command?\n\n"
|
63
|
+
say_status '', "It appears that Elasticsearch 5 is not running on this machine."
|
64
|
+
say_status '', "Is it installed? Do you want me to install and run it for you with this command?\n\n"
|
61
65
|
COMMAND.each_line { |l| say_status '', "$ #{l}" }
|
62
66
|
puts
|
63
67
|
say_status '', "(To uninstall, just remove the generated application directory.)"
|
@@ -69,9 +73,9 @@ unless (Net::HTTP.get(URI.parse('http://localhost:9200')) rescue false)
|
|
69
73
|
|
70
74
|
java_info = `java -version 2>&1`
|
71
75
|
|
72
|
-
unless java_info.match /1\.[
|
76
|
+
unless java_info.match /1\.[8-9]/
|
73
77
|
puts
|
74
|
-
say_status "ERROR", "Required Java version (1.
|
78
|
+
say_status "ERROR", "Required Java version (1.8) not found, exiting...", :red
|
75
79
|
exit(1)
|
76
80
|
end
|
77
81
|
|
@@ -81,18 +85,36 @@ unless (Net::HTTP.get(URI.parse('http://localhost:9200')) rescue false)
|
|
81
85
|
commands.each { |command| run command }
|
82
86
|
run "(#{exec})" # Launch Elasticsearch in subshell
|
83
87
|
end
|
88
|
+
|
89
|
+
# Wait for Elasticsearch to be up...
|
90
|
+
#
|
91
|
+
system <<-COMMAND
|
92
|
+
until $(curl --silent --head --fail #{$elasticsearch_url} > /dev/null 2>&1); do
|
93
|
+
printf '.'; sleep 1
|
94
|
+
done
|
95
|
+
COMMAND
|
84
96
|
end
|
85
97
|
end unless ENV['RAILS_NO_ES_INSTALL']
|
86
98
|
|
99
|
+
# ----- Application skeleton ----------------------------------------------------------------------
|
100
|
+
|
101
|
+
run "touch tmp/.gitignore"
|
102
|
+
|
103
|
+
append_to_file ".gitignore", "vendor/elasticsearch-5.2.1/\n"
|
104
|
+
|
105
|
+
git :init
|
106
|
+
git add: "."
|
107
|
+
git commit: "-m 'Initial commit: Clean application'"
|
108
|
+
|
87
109
|
# ----- Add README --------------------------------------------------------------------------------
|
88
110
|
|
89
111
|
puts
|
90
112
|
say_status "README", "Adding Readme...\n", :yellow
|
91
113
|
puts '-'*80, ''; sleep 0.25
|
92
114
|
|
93
|
-
remove_file 'README.
|
115
|
+
remove_file 'README.md'
|
94
116
|
|
95
|
-
create_file 'README.
|
117
|
+
create_file 'README.md', <<-README
|
96
118
|
= Ruby on Rails and Elasticsearch persistence: Example application
|
97
119
|
|
98
120
|
README
|
@@ -101,20 +123,31 @@ README
|
|
101
123
|
git add: "."
|
102
124
|
git commit: "-m 'Added README for the application'"
|
103
125
|
|
104
|
-
# ----- Use
|
126
|
+
# ----- Use Pry as the Rails console --------------------------------------------------------------
|
105
127
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
say_status "Rubygems", "Adding Thin into Gemfile...\n", :yellow
|
110
|
-
puts '-'*80, '';
|
128
|
+
puts
|
129
|
+
say_status "Rubygems", "Adding Pry into Gemfile...\n", :yellow
|
130
|
+
puts '-'*80, '';
|
111
131
|
|
112
|
-
|
113
|
-
|
132
|
+
gem_group :development do
|
133
|
+
gem 'pry'
|
134
|
+
gem 'pry-rails'
|
114
135
|
end
|
115
136
|
|
137
|
+
git add: "Gemfile*"
|
138
|
+
git commit: "-m 'Added Pry into the Gemfile'"
|
139
|
+
|
116
140
|
# ----- Auxiliary gems ----------------------------------------------------------------------------
|
117
141
|
|
142
|
+
puts
|
143
|
+
say_status "Rubygems", "Adding libraries into the Gemfile...\n", :yellow
|
144
|
+
puts '-'*80, ''; sleep 0.75
|
145
|
+
|
146
|
+
gem "simple_form"
|
147
|
+
|
148
|
+
git add: "Gemfile*"
|
149
|
+
git commit: "-m 'Added auxiliary libraries into the Gemfile'"
|
150
|
+
|
118
151
|
# ----- Remove CoffeeScript, Sass and "all that jazz" ---------------------------------------------
|
119
152
|
|
120
153
|
comment_lines 'Gemfile', /gem 'coffee/
|
@@ -128,16 +161,13 @@ puts
|
|
128
161
|
say_status "Rubygems", "Adding Elasticsearch libraries into Gemfile...\n", :yellow
|
129
162
|
puts '-'*80, ''; sleep 0.75
|
130
163
|
|
131
|
-
gem
|
132
|
-
gem
|
133
|
-
|
134
|
-
gem 'elasticsearch', git: '
|
135
|
-
gem 'elasticsearch-model', git: 'git://github.com/elasticsearch/elasticsearch-rails.git', require: 'elasticsearch/model'
|
136
|
-
gem 'elasticsearch-persistence', git: 'git://github.com/elasticsearch/elasticsearch-rails.git', require: 'elasticsearch/persistence/model'
|
137
|
-
gem 'elasticsearch-rails', git: 'git://github.com/elasticsearch/elasticsearch-rails.git'
|
164
|
+
gem 'elasticsearch', git: 'https://github.com/elastic/elasticsearch-ruby.git'
|
165
|
+
gem 'elasticsearch-model', git: 'https://github.com/elastic/elasticsearch-rails.git', require: 'elasticsearch/model'
|
166
|
+
gem 'elasticsearch-persistence', git: 'https://github.com/elastic/elasticsearch-rails.git', require: 'elasticsearch/persistence/model'
|
167
|
+
gem 'elasticsearch-rails', git: 'https://github.com/elastic/elasticsearch-rails.git'
|
138
168
|
|
139
169
|
git add: "Gemfile*"
|
140
|
-
git commit: "-m 'Added libraries into Gemfile'"
|
170
|
+
git commit: "-m 'Added the Elasticsearch libraries into the Gemfile'"
|
141
171
|
|
142
172
|
# ----- Install gems ------------------------------------------------------------------------------
|
143
173
|
|
@@ -173,11 +203,15 @@ if ENV['LOCAL']
|
|
173
203
|
'vendor/assets/javascripts/jquery-ui-1.10.4.custom.min.js'
|
174
204
|
copy_file File.expand_path('../vendor/assets/jquery-ui-1.10.4.custom.min.css', __FILE__),
|
175
205
|
'vendor/assets/stylesheets/ui-lightness/jquery-ui-1.10.4.custom.min.css'
|
206
|
+
copy_file File.expand_path('../vendor/assets/stylesheets/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png', __FILE__),
|
207
|
+
'vendor/assets/stylesheets/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png'
|
176
208
|
else
|
177
209
|
get 'https://raw.githubusercontent.com/elasticsearch/elasticsearch-rails/master/elasticsearch-persistence/examples/music/vendor/assets/jquery-ui-1.10.4.custom.min.js',
|
178
210
|
'vendor/assets/javascripts/jquery-ui-1.10.4.custom.min.js'
|
179
211
|
get 'https://raw.githubusercontent.com/elasticsearch/elasticsearch-rails/master/elasticsearch-persistence/examples/music/vendor/assets/jquery-ui-1.10.4.custom.min.css',
|
180
212
|
'vendor/assets/stylesheets/ui-lightness/jquery-ui-1.10.4.custom.min.css'
|
213
|
+
get 'https://raw.githubusercontent.com/elasticsearch/elasticsearch-rails/master/elasticsearch-persistence/examples/music/vendor/assets/stylesheets/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png',
|
214
|
+
'vendor/assets/stylesheets/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png'
|
181
215
|
end
|
182
216
|
|
183
217
|
append_to_file 'app/assets/javascripts/application.js', "//= require jquery-ui-1.10.4.custom.min.js"
|
@@ -301,6 +335,7 @@ if ENV['LOCAL']
|
|
301
335
|
copy_file File.expand_path('../assets/autocomplete.css', __FILE__), 'app/assets/stylesheets/autocomplete.css'
|
302
336
|
copy_file File.expand_path('../assets/form.css', __FILE__), 'app/assets/stylesheets/form.css'
|
303
337
|
copy_file File.expand_path('../assets/blank_cover.png', __FILE__), 'public/images/blank_cover.png'
|
338
|
+
copy_file File.expand_path('../assets/blank_artist.png', __FILE__), 'public/images/blank_artist.png'
|
304
339
|
else
|
305
340
|
get 'https://raw.githubusercontent.com/elasticsearch/elasticsearch-rails/master/elasticsearch-persistence/examples/music/assets/application.css',
|
306
341
|
'app/assets/stylesheets/application.css'
|
@@ -310,6 +345,8 @@ else
|
|
310
345
|
'app/assets/stylesheets/form.css'
|
311
346
|
get 'https://raw.githubusercontent.com/elasticsearch/elasticsearch-rails/master/elasticsearch-persistence/examples/music/assets/blank_cover.png',
|
312
347
|
'public/images/blank_cover.png'
|
348
|
+
get 'https://raw.githubusercontent.com/elasticsearch/elasticsearch-rails/master/elasticsearch-persistence/examples/music/assets/blank_artist.png',
|
349
|
+
'public/images/blank_artist.png'
|
313
350
|
end
|
314
351
|
|
315
352
|
git add: "."
|
@@ -359,9 +396,9 @@ puts
|
|
359
396
|
say_status "Data", "Import the data...", :yellow
|
360
397
|
puts '-'*80, ''; sleep 0.25
|
361
398
|
|
362
|
-
source = ENV.fetch('DATA_SOURCE', '
|
399
|
+
source = ENV.fetch('DATA_SOURCE', 'https://github.com/elastic/elasticsearch-rails/releases/download/dischord.yml/dischord.yml')
|
363
400
|
|
364
|
-
run "rails runner 'IndexManager.import_from_yaml(\"#{source}\", force: true)'"
|
401
|
+
run "ELASTICSEARCH_URL=#{$elasticsearch_url} rails runner 'IndexManager.import_from_yaml(\"#{source}\", force: true)'"
|
365
402
|
|
366
403
|
# ----- Print Git log -----------------------------------------------------------------------------
|
367
404
|
|
@@ -389,5 +426,5 @@ unless ENV['RAILS_NO_SERVER_START']
|
|
389
426
|
say_status "DONE", "\e[1mStarting the application.\e[0m", :yellow
|
390
427
|
puts "="*80, ""
|
391
428
|
|
392
|
-
run "rails server --port=#{port}"
|
429
|
+
run "ELASTICSEARCH_URL=#{$elasticsearch_url} rails server --port=#{port}"
|
393
430
|
end
|
Binary file
|
data/examples/notes/Gemfile
CHANGED
@@ -9,8 +9,8 @@ gem 'hashie'
|
|
9
9
|
|
10
10
|
gem 'patron'
|
11
11
|
gem 'elasticsearch'
|
12
|
-
gem 'elasticsearch-model',
|
13
|
-
gem 'elasticsearch-persistence',
|
12
|
+
gem 'elasticsearch-model', git: 'https://github.com/elastic/elasticsearch-rails.git'
|
13
|
+
gem 'elasticsearch-persistence', git: 'https://github.com/elastic/elasticsearch-rails.git'
|
14
14
|
|
15
15
|
gem 'sinatra', require: false
|
16
16
|
gem 'thin'
|
@@ -62,8 +62,8 @@ class NoteRepository
|
|
62
62
|
|
63
63
|
mapping do
|
64
64
|
indexes :text, analyzer: 'snowball'
|
65
|
-
indexes :tags,
|
66
|
-
indexes :created_at, type:
|
65
|
+
indexes :tags, type: 'keyword'
|
66
|
+
indexes :created_at, type: 'date'
|
67
67
|
end
|
68
68
|
|
69
69
|
create_index!
|
@@ -105,7 +105,7 @@ class Application < Sinatra::Base
|
|
105
105
|
end
|
106
106
|
|
107
107
|
if filter
|
108
|
-
{
|
108
|
+
{ bool: { must: [ query ], filter: filter } }
|
109
109
|
else
|
110
110
|
query
|
111
111
|
end
|
@@ -113,7 +113,7 @@ module Elasticsearch
|
|
113
113
|
# Store the "hit" information (highlighting, score, ...)
|
114
114
|
#
|
115
115
|
object.instance_variable_set :@hit,
|
116
|
-
|
116
|
+
Elasticsearch::Model::HashWrapper.new(document.except('_index', '_type', '_id', '_version', '_source'))
|
117
117
|
|
118
118
|
object.instance_variable_set(:@persisted, true)
|
119
119
|
object
|
@@ -55,7 +55,7 @@ module Elasticsearch
|
|
55
55
|
gateway.count( query_or_definition, options )
|
56
56
|
end
|
57
57
|
|
58
|
-
# Returns all models efficiently via the Elasticsearch's
|
58
|
+
# Returns all models efficiently via the Elasticsearch's scroll API
|
59
59
|
#
|
60
60
|
# You can restrict the models being returned with a query.
|
61
61
|
#
|
@@ -117,20 +117,17 @@ module Elasticsearch
|
|
117
117
|
|
118
118
|
body = options
|
119
119
|
|
120
|
-
# Get the initial scroll_id
|
120
|
+
# Get the initial batch of documents and the scroll_id
|
121
121
|
#
|
122
122
|
response = gateway.client.search( { index: gateway.index_name,
|
123
123
|
type: gateway.document_type,
|
124
|
-
|
125
|
-
|
126
|
-
size:
|
127
|
-
body:
|
124
|
+
scroll: scroll,
|
125
|
+
sort: ['_doc'],
|
126
|
+
size: 20,
|
127
|
+
body: body }.merge(search_params) )
|
128
128
|
|
129
|
-
# Get the initial batch of documents
|
130
|
-
#
|
131
|
-
response = gateway.client.scroll( { scroll_id: response['_scroll_id'], scroll: scroll } )
|
132
129
|
|
133
|
-
#
|
130
|
+
# Scroll the search object and break when receiving an empty array of hits
|
134
131
|
#
|
135
132
|
while response['hits']['hits'].any? do
|
136
133
|
yield Repository::Response::Results.new(gateway, response)
|
@@ -149,7 +146,7 @@ module Elasticsearch
|
|
149
146
|
#
|
150
147
|
# Person.find_each { |person| puts person.name }
|
151
148
|
#
|
152
|
-
# # # GET http://localhost:9200/people/person/_search?scroll=5m&
|
149
|
+
# # # GET http://localhost:9200/people/person/_search?scroll=5m&size=20
|
153
150
|
# # # GET http://localhost:9200/_search/scroll?scroll=5m&scroll_id=c2Nhbj...
|
154
151
|
# # Test 0
|
155
152
|
# # Test 1
|
@@ -18,7 +18,7 @@ module Elasticsearch
|
|
18
18
|
#
|
19
19
|
def initialize(repository, response, options={})
|
20
20
|
@repository = repository
|
21
|
-
@response =
|
21
|
+
@response = Elasticsearch::Model::HashWrapper.new(response)
|
22
22
|
@options = options
|
23
23
|
end
|
24
24
|
|
@@ -78,7 +78,7 @@ module Elasticsearch
|
|
78
78
|
# results.response.aggregations.titles.buckets.map { |term| "#{term['key']}: #{term['doc_count']}" }
|
79
79
|
# # => ["brown: 1", "dog: 1", ...]
|
80
80
|
#
|
81
|
-
# @return [
|
81
|
+
# @return [Elasticsearch::Model::HashWrapper]
|
82
82
|
#
|
83
83
|
def response
|
84
84
|
@response
|
@@ -75,8 +75,18 @@ module Elasticsearch
|
|
75
75
|
#
|
76
76
|
def count(query_or_definition=nil, options={})
|
77
77
|
query_or_definition ||= { query: { match_all: {} } }
|
78
|
-
|
79
|
-
|
78
|
+
type = document_type || (klass ? __get_type_from_class(klass) : nil )
|
79
|
+
|
80
|
+
case
|
81
|
+
when query_or_definition.respond_to?(:to_hash)
|
82
|
+
response = client.count( { index: index_name, type: type, body: query_or_definition.to_hash }.merge(options) )
|
83
|
+
when query_or_definition.is_a?(String)
|
84
|
+
response = client.count( { index: index_name, type: type, q: query_or_definition }.merge(options) )
|
85
|
+
else
|
86
|
+
raise ArgumentError, "[!] Pass the search definition as a Hash-like object or pass the query as a String, not as [#{query_or_definition.class}]"
|
87
|
+
end
|
88
|
+
|
89
|
+
response['count']
|
80
90
|
end
|
81
91
|
end
|
82
92
|
|
@@ -102,7 +102,11 @@ module Elasticsearch
|
|
102
102
|
should "update the object with a script and params" do
|
103
103
|
response = @repository.save Page.new(title: 'Test Page')
|
104
104
|
|
105
|
-
@repository.update id: response['_id'],
|
105
|
+
@repository.update id: response['_id'],
|
106
|
+
script: {
|
107
|
+
inline: 'ctx._source.views += params.count',
|
108
|
+
params: { count: 3 }
|
109
|
+
}
|
106
110
|
|
107
111
|
page = @repository.find(response['_id'])
|
108
112
|
assert_equal 3, page.views
|
@@ -83,27 +83,29 @@ class Elasticsearch::Persistence::ModelFindTest < Test::Unit::TestCase
|
|
83
83
|
DummyFindModel.all( { query: { match: { title: 'test' } } }, { routing: 'abc123' } )
|
84
84
|
end
|
85
85
|
|
86
|
-
context "finding via
|
86
|
+
context "finding via scroll" do
|
87
87
|
setup do
|
88
88
|
@gateway
|
89
89
|
.expects(:deserialize)
|
90
|
-
.with('_source' => {'foo' => 'bar'})
|
91
90
|
.returns('_source' => {'foo' => 'bar'})
|
91
|
+
.at_least_once
|
92
92
|
|
93
|
+
# 1. Initial batch of documents and the scroll_id
|
93
94
|
@gateway.client
|
94
95
|
.expects(:search)
|
95
96
|
.with do |arguments|
|
96
|
-
assert_equal 'scan', arguments[:search_type]
|
97
97
|
assert_equal 'foo', arguments[:index]
|
98
98
|
assert_equal 'bar', arguments[:type]
|
99
99
|
true
|
100
100
|
end
|
101
|
-
.returns(MultiJson.load('{"_scroll_id":"abc123==", "hits":{"hits":[]}}'))
|
101
|
+
.returns(MultiJson.load('{"_scroll_id":"abc123==", "hits":{"hits":[{"_source":{"foo":"bar_1"}}]}}'))
|
102
102
|
|
103
|
+
# 2. Second batch of documents and the scroll_id
|
104
|
+
# 3. Last, empty batch of documents
|
103
105
|
@gateway.client
|
104
106
|
.expects(:scroll)
|
105
107
|
.twice
|
106
|
-
.returns(MultiJson.load('{"_scroll_id":"abc456==", "hits":{"hits":[{"_source":{"foo":"
|
108
|
+
.returns(MultiJson.load('{"_scroll_id":"abc456==", "hits":{"hits":[{"_source":{"foo":"bar_2"}}]}}'))
|
107
109
|
.then
|
108
110
|
.returns(MultiJson.load('{"_scroll_id":"abc789==", "hits":{"hits":[]}}'))
|
109
111
|
end
|
@@ -70,7 +70,7 @@ class Elasticsearch::Persistence::ModelGatewayTest < Test::Unit::TestCase
|
|
70
70
|
end
|
71
71
|
|
72
72
|
should "properly look up types for classes" do
|
73
|
-
assert_equal '
|
73
|
+
assert_equal 'text', Elasticsearch::Persistence::Model::Utils::lookup_type(String)
|
74
74
|
assert_equal 'integer', Elasticsearch::Persistence::Model::Utils::lookup_type(Integer)
|
75
75
|
assert_equal 'float', Elasticsearch::Persistence::Model::Utils::lookup_type(Float)
|
76
76
|
assert_equal 'date', Elasticsearch::Persistence::Model::Utils::lookup_type(Date)
|
@@ -22,7 +22,7 @@ class Elasticsearch::Persistence::RepositoryIndexingTest < Test::Unit::TestCase
|
|
22
22
|
indexes :title
|
23
23
|
end
|
24
24
|
|
25
|
-
assert_equal( {:"my_document"=>{:properties=>{:title=>{:type=>"
|
25
|
+
assert_equal( {:"my_document"=>{:properties=>{:title=>{:type=>"text"}}}}, subject.mappings.to_hash )
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
@@ -41,7 +41,7 @@ class Elasticsearch::Persistence::RepositoryResponseResultsTest < Test::Unit::Te
|
|
41
41
|
assert_equal 5, subject.response['_shards']['total']
|
42
42
|
end
|
43
43
|
|
44
|
-
should "wrap the response in
|
44
|
+
should "wrap the response in HashWrapper" do
|
45
45
|
assert_equal 5, subject.response._shards.total
|
46
46
|
end
|
47
47
|
|
@@ -96,21 +96,21 @@ class Elasticsearch::Persistence::RepositorySearchTest < Test::Unit::TestCase
|
|
96
96
|
end
|
97
97
|
|
98
98
|
should "return the number of domain objects" do
|
99
|
-
subject.expects(:
|
100
|
-
.returns(Elasticsearch::Persistence::Repository::Response::Results.new( subject, {'hits' => { 'total' => 1 }}))
|
99
|
+
subject.client.expects(:count).returns({'count' => 1})
|
101
100
|
assert_equal 1, subject.count
|
102
101
|
end
|
103
102
|
|
104
|
-
should "pass arguments
|
105
|
-
subject.expects(:
|
106
|
-
.with do |
|
107
|
-
assert_equal '
|
108
|
-
assert_equal
|
103
|
+
should "pass arguments to count" do
|
104
|
+
subject.client.expects(:count)
|
105
|
+
.with do |arguments|
|
106
|
+
assert_equal 'test', arguments[:index]
|
107
|
+
assert_equal 'bar', arguments[:body][:query][:match][:foo]
|
108
|
+
assert_equal true, arguments[:ignore_unavailable]
|
109
109
|
true
|
110
110
|
end
|
111
|
-
.returns(
|
111
|
+
.returns({'count' => 1})
|
112
112
|
|
113
|
-
subject.count( { query: { match: { foo: 'bar' } } }, { ignore_unavailable: true } )
|
113
|
+
assert_equal 1, subject.count( { query: { match: { foo: 'bar' } } }, { ignore_unavailable: true } )
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elasticsearch-persistence
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Karel Minarik
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-04-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: elasticsearch
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: elasticsearch-model
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -329,6 +329,7 @@ files:
|
|
329
329
|
- examples/music/artists/show.html.erb
|
330
330
|
- examples/music/assets/application.css
|
331
331
|
- examples/music/assets/autocomplete.css
|
332
|
+
- examples/music/assets/blank_artist.png
|
332
333
|
- examples/music/assets/blank_cover.png
|
333
334
|
- examples/music/assets/form.css
|
334
335
|
- examples/music/index_manager.rb
|
@@ -340,6 +341,7 @@ files:
|
|
340
341
|
- examples/music/template.rb
|
341
342
|
- examples/music/vendor/assets/jquery-ui-1.10.4.custom.min.css
|
342
343
|
- examples/music/vendor/assets/jquery-ui-1.10.4.custom.min.js
|
344
|
+
- examples/music/vendor/assets/stylesheets/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png
|
343
345
|
- examples/notes/.gitignore
|
344
346
|
- examples/notes/Gemfile
|
345
347
|
- examples/notes/README.markdown
|