elastic_record 0.7.1 → 0.7.2
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.
- data/elastic_record.gemspec +1 -1
- data/lib/elastic_record.rb +1 -0
- data/lib/elastic_record/lucene.rb +43 -0
- data/test/elastic_record/lucene_test.rb +23 -0
- data/test/support/widget.rb +6 -6
- metadata +10 -17
data/elastic_record.gemspec
CHANGED
data/lib/elastic_record.rb
CHANGED
@@ -7,6 +7,7 @@ module ElasticRecord
|
|
7
7
|
autoload :Config, 'elastic_record/config'
|
8
8
|
autoload :Connection, 'elastic_record/connection'
|
9
9
|
autoload :Index, 'elastic_record/index'
|
10
|
+
autoload :Lucene, 'elastic_record/lucene'
|
10
11
|
autoload :Model, 'elastic_record/model'
|
11
12
|
autoload :Relation, 'elastic_record/relation'
|
12
13
|
autoload :Searching, 'elastic_record/searching'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
|
3
|
+
module ElasticRecord
|
4
|
+
class Lucene
|
5
|
+
# Special characters:
|
6
|
+
# + - && || ! ( ) { } [ ] ^ " ~ * ? : \
|
7
|
+
ESCAPE_REGEX = /(\+|-|&&|\|\||!|\(|\)|{|}|\[|\]|`|"|~|\?|:|\\)/
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def escape(query)
|
11
|
+
query.gsub(ESCAPE_REGEX, "\\\\\\1")
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns a lucene query that works like G
|
15
|
+
def smart_query(query, fields)
|
16
|
+
return if query.blank?
|
17
|
+
|
18
|
+
words = Shellwords::shellwords(query)
|
19
|
+
|
20
|
+
words.map do |word|
|
21
|
+
if word =~ /^(\w+):(.+)$/ && fields.include?($1)
|
22
|
+
match_word $2, [$1]
|
23
|
+
else
|
24
|
+
match_word word, fields
|
25
|
+
end
|
26
|
+
end.join(' AND ')
|
27
|
+
end
|
28
|
+
|
29
|
+
def match_word(word, fields)
|
30
|
+
word = escape(word)
|
31
|
+
if word =~ / /
|
32
|
+
word = "\"#{word}\""
|
33
|
+
else
|
34
|
+
word = "#{word}*"
|
35
|
+
end
|
36
|
+
|
37
|
+
or_query = fields.map { |field| "#{field}:#{word}" }.join(' OR ')
|
38
|
+
|
39
|
+
"(#{or_query})"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class ElasticRecord::LuceneTest < MiniTest::Spec
|
4
|
+
def test_escape
|
5
|
+
assert_equal "\\\\", ElasticRecord::Lucene.escape("\\")
|
6
|
+
assert_equal "Matt \\&& Joe", ElasticRecord::Lucene.escape("Matt && Joe")
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_smart_search
|
10
|
+
assert_smart_escape nil, '', ['name']
|
11
|
+
assert_smart_escape nil, nil, ['name']
|
12
|
+
|
13
|
+
assert_smart_escape '(name:foo*)', 'foo', ['name']
|
14
|
+
assert_smart_escape '(name:foo* OR street:foo*)', 'foo', ['name', 'street']
|
15
|
+
assert_smart_escape '(name:"foo bar" OR street:"foo bar") AND (name:faz* OR street:faz*)', '"foo bar" faz', ['name', 'street']
|
16
|
+
assert_smart_escape '(street:"42 place") AND (name:bar*)', 'street:"42 place" name:bar', ['name', 'street']
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def assert_smart_escape(expected, query, fields)
|
21
|
+
assert_equal expected, ElasticRecord::Lucene.smart_query(query, fields)
|
22
|
+
end
|
23
|
+
end
|
data/test/support/widget.rb
CHANGED
@@ -6,10 +6,10 @@ class Widget
|
|
6
6
|
include ElasticRecord::Model
|
7
7
|
include ElasticRecord::Callbacks
|
8
8
|
|
9
|
-
self.elastic_index.mapping[:properties].update(
|
10
|
-
type: 'string',
|
11
|
-
index: 'not_analyzed'
|
12
|
-
|
9
|
+
self.elastic_index.mapping[:properties].update(
|
10
|
+
name: {type: 'string', index: 'analyzed'},
|
11
|
+
color: {type: 'string', index: 'not_analyzed'}
|
12
|
+
)
|
13
13
|
|
14
14
|
class << self
|
15
15
|
def find(ids)
|
@@ -31,7 +31,7 @@ class Widget
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
attr_accessor :id, :color
|
34
|
+
attr_accessor :id, :name, :color
|
35
35
|
def initialize(attributes = {})
|
36
36
|
attributes.each do |key, val|
|
37
37
|
send("#{key}=", val)
|
@@ -39,6 +39,6 @@ class Widget
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def as_search
|
42
|
-
{color: color}
|
42
|
+
{name: name, color: color}
|
43
43
|
end
|
44
44
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elastic_record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: arelastic
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70212670043440 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,15 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
25
|
-
none: false
|
26
|
-
requirements:
|
27
|
-
- - ! '>='
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '0'
|
24
|
+
version_requirements: *70212670043440
|
30
25
|
- !ruby/object:Gem::Dependency
|
31
26
|
name: activemodel
|
32
|
-
requirement: !ruby/object:Gem::Requirement
|
27
|
+
requirement: &70212670041220 !ruby/object:Gem::Requirement
|
33
28
|
none: false
|
34
29
|
requirements:
|
35
30
|
- - ! '>='
|
@@ -37,12 +32,7 @@ dependencies:
|
|
37
32
|
version: '0'
|
38
33
|
type: :runtime
|
39
34
|
prerelease: false
|
40
|
-
version_requirements:
|
41
|
-
none: false
|
42
|
-
requirements:
|
43
|
-
- - ! '>='
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version: '0'
|
35
|
+
version_requirements: *70212670041220
|
46
36
|
description: Find your records with elastic search
|
47
37
|
email: developer@matthewhiggins.com
|
48
38
|
executables: []
|
@@ -67,6 +57,7 @@ files:
|
|
67
57
|
- lib/elastic_record/index/mapping.rb
|
68
58
|
- lib/elastic_record/index/percolator.rb
|
69
59
|
- lib/elastic_record/log_subscriber.rb
|
60
|
+
- lib/elastic_record/lucene.rb
|
70
61
|
- lib/elastic_record/model.rb
|
71
62
|
- lib/elastic_record/orm/active_record.rb
|
72
63
|
- lib/elastic_record/railtie.rb
|
@@ -88,6 +79,7 @@ files:
|
|
88
79
|
- test/elastic_record/index/percolator_test.rb
|
89
80
|
- test/elastic_record/index_test.rb
|
90
81
|
- test/elastic_record/log_subscriber_test.rb
|
82
|
+
- test/elastic_record/lucene_test.rb
|
91
83
|
- test/elastic_record/model_test.rb
|
92
84
|
- test/elastic_record/relation/batches_test.rb
|
93
85
|
- test/elastic_record/relation/delegation_test.rb
|
@@ -120,8 +112,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
112
|
version: 1.8.11
|
121
113
|
requirements: []
|
122
114
|
rubyforge_project:
|
123
|
-
rubygems_version: 1.8.
|
115
|
+
rubygems_version: 1.8.17
|
124
116
|
signing_key:
|
125
117
|
specification_version: 3
|
126
118
|
summary: Use Elastic Search with your objects
|
127
119
|
test_files: []
|
120
|
+
has_rdoc:
|