pg_search 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -3
- data/README.md +36 -0
- data/lib/pg_search/features/trigram.rb +20 -12
- data/lib/pg_search/version.rb +1 -1
- data/spec/integration/pg_search_spec.rb +24 -0
- data/spec/lib/pg_search/features/trigram_spec.rb +25 -10
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc5ae6e460c82b93f20a957e4c5a14454fca1f84
|
4
|
+
data.tar.gz: 2a262bd65fb27b8efa689dde40c289f3a3ebc4fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d9133994756acc700d4cd09e7b9904f1ab89fcc0e3d79e9aff06017a64b96f4ec7239d5267fc1c146f072846de60bf9d36399bfd4171e9a733180a8f7139cfc5
|
7
|
+
data.tar.gz: efbe3aaab68b0495499a8709b0a5a50454beea08b13f645439d4263fd0df6c538080069665b36e769938d4993414ee9d568c3c8f00cf5099900142bbc3014e5c
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# pg_search changelog
|
2
2
|
|
3
|
+
## 0.7.2
|
4
|
+
|
5
|
+
* Add :threshold option for configuring how permissive trigram searches are.
|
6
|
+
|
3
7
|
## 0.7.1
|
4
8
|
|
5
9
|
* Fix issue with {:using => :trigram, :ignoring => :accents} that generated
|
@@ -7,15 +11,15 @@
|
|
7
11
|
|
8
12
|
## 0.7.0
|
9
13
|
|
10
|
-
* Start requiring Ruby 1.9.2 or later
|
14
|
+
* Start requiring Ruby 1.9.2 or later.
|
11
15
|
|
12
16
|
## 0.6.4
|
13
17
|
|
14
|
-
* Fix issue with using more than two features in the same scope
|
18
|
+
* Fix issue with using more than two features in the same scope.
|
15
19
|
|
16
20
|
## 0.6.3
|
17
21
|
|
18
|
-
* Fix issues and deprecations for Active Record 4.0.0.rc1
|
22
|
+
* Fix issues and deprecations for Active Record 4.0.0.rc1.
|
19
23
|
|
20
24
|
## 0.6.2
|
21
25
|
|
data/README.md
CHANGED
@@ -680,6 +680,42 @@ be installed before this feature can be used.
|
|
680
680
|
|
681
681
|
Website.kinda_spelled_like("Yahoo!") # => [yahooo, yohoo]
|
682
682
|
|
683
|
+
##### :threshold
|
684
|
+
|
685
|
+
By default, trigram searches find records which have a similarity of at least 0.3
|
686
|
+
using pg_trgm's calculations. You may specify a custom threshold if you prefer.
|
687
|
+
Higher numbers match more strictly, and thus return fewer results. Lower numbers
|
688
|
+
match more permissively, letting in more results.
|
689
|
+
|
690
|
+
class Vegetable < ActiveRecord::Base
|
691
|
+
include PgSearch
|
692
|
+
|
693
|
+
pg_search_scope :strictly_spelled_like,
|
694
|
+
:against => :name,
|
695
|
+
:using => {
|
696
|
+
:trigram => {
|
697
|
+
:threshold => 0.5
|
698
|
+
}
|
699
|
+
}
|
700
|
+
|
701
|
+
pg_search_scope :roughly_spelled_like,
|
702
|
+
:against => :name,
|
703
|
+
:using => {
|
704
|
+
:trigram => {
|
705
|
+
:threshold => 0.1
|
706
|
+
}
|
707
|
+
}
|
708
|
+
end
|
709
|
+
|
710
|
+
cauliflower = Vegetable.create! :name => "cauliflower"
|
711
|
+
|
712
|
+
Vegetable.roughly_spelled_like("couliflower") # => [cauliflower]
|
713
|
+
Vegetable.strictly_spelled_like("couliflower") # => [cauliflower]
|
714
|
+
|
715
|
+
Vegetable.roughly_spelled_like("collyflower") # => [cauliflower]
|
716
|
+
Vegetable.strictly_spelled_like("collyflower") # => []
|
717
|
+
|
718
|
+
|
683
719
|
### Ignoring accent marks (PostgreSQL 9.0 and newer only)
|
684
720
|
|
685
721
|
Most of the time you will want to ignore accent marks when searching. This
|
@@ -2,25 +2,33 @@ module PgSearch
|
|
2
2
|
module Features
|
3
3
|
class Trigram < Feature
|
4
4
|
def conditions
|
5
|
-
|
6
|
-
Arel::Nodes::
|
7
|
-
|
5
|
+
if options[:threshold]
|
6
|
+
Arel::Nodes::Grouping.new(
|
7
|
+
similarity.gteq(options[:threshold])
|
8
|
+
)
|
9
|
+
else
|
10
|
+
Arel::Nodes::Grouping.new(
|
11
|
+
Arel::Nodes::InfixOperation.new("%", normalized_document, normalized_query)
|
12
|
+
)
|
13
|
+
end
|
8
14
|
end
|
9
15
|
|
10
16
|
def rank
|
11
|
-
Arel::Nodes::Grouping.new(
|
12
|
-
Arel::Nodes::NamedFunction.new(
|
13
|
-
"similarity",
|
14
|
-
[
|
15
|
-
normalized_document,
|
16
|
-
normalized_query
|
17
|
-
]
|
18
|
-
)
|
19
|
-
)
|
17
|
+
Arel::Nodes::Grouping.new(similarity)
|
20
18
|
end
|
21
19
|
|
22
20
|
private
|
23
21
|
|
22
|
+
def similarity
|
23
|
+
Arel::Nodes::NamedFunction.new(
|
24
|
+
"similarity",
|
25
|
+
[
|
26
|
+
normalized_document,
|
27
|
+
normalized_query
|
28
|
+
]
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
24
32
|
def normalized_document
|
25
33
|
Arel::Nodes::Grouping.new(Arel.sql(normalize(document)))
|
26
34
|
end
|
data/lib/pg_search/version.rb
CHANGED
@@ -326,6 +326,30 @@ describe "an Active Record model which includes PgSearch" do
|
|
326
326
|
results = ModelWithPgSearch.with_trigrams('cdefhijkl')
|
327
327
|
results.should == [included]
|
328
328
|
end
|
329
|
+
|
330
|
+
context "when a threshold is specified" do
|
331
|
+
before do
|
332
|
+
ModelWithPgSearch.pg_search_scope :with_strict_trigrams, :against => [:title, :content], :using => {trigram: {threshold: 0.5}}
|
333
|
+
ModelWithPgSearch.pg_search_scope :with_permissive_trigrams, :against => [:title, :content], :using => {trigram: {threshold: 0.1}}
|
334
|
+
end
|
335
|
+
|
336
|
+
it "uses the threshold in the trigram expression" do
|
337
|
+
low_similarity = ModelWithPgSearch.create!(:title => "a")
|
338
|
+
medium_similarity = ModelWithPgSearch.create!(:title => "abc")
|
339
|
+
high_similarity = ModelWithPgSearch.create!(:title => "abcdefghijkl")
|
340
|
+
|
341
|
+
results = ModelWithPgSearch.with_strict_trigrams("abcdefg")
|
342
|
+
expect(results).to include(high_similarity)
|
343
|
+
expect(results).not_to include(medium_similarity, low_similarity)
|
344
|
+
|
345
|
+
results = ModelWithPgSearch.with_trigrams("abcdefg")
|
346
|
+
expect(results).to include(high_similarity, medium_similarity)
|
347
|
+
expect(results).not_to include(low_similarity)
|
348
|
+
|
349
|
+
results = ModelWithPgSearch.with_permissive_trigrams("abcdefg")
|
350
|
+
expect(results).to include(high_similarity, medium_similarity, low_similarity)
|
351
|
+
end
|
352
|
+
end
|
329
353
|
end
|
330
354
|
|
331
355
|
context "using tsearch" do
|
@@ -11,8 +11,12 @@ describe PgSearch::Features::Trigram do
|
|
11
11
|
]}
|
12
12
|
let(:normalizer) { PgSearch::Normalizer.new(config) }
|
13
13
|
let(:config) { OpenStruct.new(:ignore => [], :postgresql_version => 90000) }
|
14
|
-
|
15
|
-
|
14
|
+
|
15
|
+
let(:coalesced_columns) do
|
16
|
+
<<-SQL.strip_heredoc.chomp
|
17
|
+
coalesce(#{Model.quoted_table_name}."name"::text, '') || ' ' || coalesce(#{Model.quoted_table_name}."content"::text, '')
|
18
|
+
SQL
|
19
|
+
end
|
16
20
|
|
17
21
|
with_model :Model do
|
18
22
|
table do |t|
|
@@ -22,24 +26,35 @@ describe PgSearch::Features::Trigram do
|
|
22
26
|
end
|
23
27
|
|
24
28
|
describe 'conditions' do
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
expect(feature.conditions.to_sql).to eq("((#{coalesced_colums}) % '#{query}')")
|
29
|
-
end
|
29
|
+
it 'escapes the search document and query' do
|
30
|
+
config.ignore = []
|
31
|
+
expect(feature.conditions.to_sql).to eq("((#{coalesced_columns}) % '#{query}')")
|
30
32
|
end
|
31
33
|
|
32
|
-
context 'ignoring
|
34
|
+
context 'ignoring accents' do
|
33
35
|
it 'escapes the search document and query, but not the accent function' do
|
34
36
|
config.ignore = [:accents]
|
35
|
-
expect(feature.conditions.to_sql).to eq("((unaccent(#{
|
37
|
+
expect(feature.conditions.to_sql).to eq("((unaccent(#{coalesced_columns})) % unaccent('#{query}'))")
|
36
38
|
end
|
37
39
|
end
|
40
|
+
|
41
|
+
context 'when a threshold is specified' do
|
42
|
+
let(:options) do
|
43
|
+
{ threshold: 0.5 }
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'uses a minimum similarity expression instead of the "%" operator' do
|
47
|
+
expect(feature.conditions.to_sql).to eq(
|
48
|
+
"(similarity((#{coalesced_columns}), '#{query}') >= 0.5)"
|
49
|
+
)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
38
53
|
end
|
39
54
|
|
40
55
|
describe '#rank' do
|
41
56
|
it 'returns an expression using the similarity() function' do
|
42
|
-
expect(feature.rank.to_sql).to eq("(similarity((#{
|
57
|
+
expect(feature.rank.to_sql).to eq("(similarity((#{coalesced_columns}), '#{query}'))")
|
43
58
|
end
|
44
59
|
end
|
45
60
|
end
|