elasticsearch-persistence 2.0.1 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|