elastic_record 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'elastic_record'
5
- s.version = '0.7.1'
5
+ s.version = '0.7.2'
6
6
  s.summary = 'Use Elastic Search with your objects'
7
7
  s.description = 'Find your records with elastic search'
8
8
 
@@ -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
@@ -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(color: {
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.1
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-02 00:00:00.000000000 Z
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: !ruby/object:Gem::Requirement
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: !ruby/object:Gem::Requirement
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.24
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: