pg_search 2.3.7 → 2.3.8
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/.github/workflows/ci.yml +41 -34
- data/.github/workflows/codeql.yml +87 -0
- data/.standard.yml +2 -2
- data/CHANGELOG.md +12 -0
- data/Gemfile +4 -2
- data/README.md +88 -86
- data/Rakefile +1 -7
- data/lib/pg_search/configuration.rb +10 -26
- data/lib/pg_search/features/tsearch.rb +17 -25
- data/lib/pg_search/model.rb +6 -8
- data/lib/pg_search/multisearch/rebuilder.rb +4 -3
- data/lib/pg_search/normalizer.rb +12 -2
- data/lib/pg_search/scope_options.rb +10 -3
- data/lib/pg_search/version.rb +1 -1
- data/pg_search.gemspec +3 -3
- data/spec/integration/associations_spec.rb +12 -0
- data/spec/integration/deprecation_spec.rb +5 -1
- data/spec/integration/pagination_spec.rb +1 -0
- data/spec/integration/pg_search_spec.rb +30 -1
- data/spec/integration/single_table_inheritance_spec.rb +2 -0
- data/spec/lib/pg_search/configuration/association_spec.rb +2 -0
- data/spec/lib/pg_search/configuration/foreign_column_spec.rb +1 -0
- data/spec/lib/pg_search/features/trigram_spec.rb +5 -6
- data/spec/lib/pg_search/multisearch/rebuilder_spec.rb +53 -3
- data/spec/lib/pg_search/multisearch_spec.rb +2 -2
- data/spec/lib/pg_search/multisearchable_spec.rb +8 -0
- data/spec/lib/pg_search/normalizer_spec.rb +4 -4
- data/spec/lib/pg_search_spec.rb +4 -0
- data/spec/spec_helper.rb +0 -13
- metadata +9 -13
- data/spec/.rubocop.yml +0 -27
- data/spec/integration/.rubocop.yml +0 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 19d829bcebb6f71fe198f833221ac95046c86fc8a464050ee018480e811c17cc
|
|
4
|
+
data.tar.gz: 20e57c883dda915b997ef6dbfe15244f8662c3900ee847538a1d1be358a4bc81
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: abd3ce5a816507a6cfe608fedea53d6c7fa4b104d1e85ea3e1e87b074d33160002fded3d2595aac5edfd43a6b59bfdffaf1cbc7a9ffdeace30bf5d01ae81af25
|
|
7
|
+
data.tar.gz: '092545c6d541290cb8f089718d472f98167be48bd20d1f6efb922d8fe5f38f175131b8d79f291c6c6b6465fc39cea2f824c1141fb3689e9ef9dddef9e85376cb'
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -12,9 +12,18 @@ on:
|
|
|
12
12
|
- cron: "0 18 * * 6" # Saturdays at 12pm CST
|
|
13
13
|
workflow_dispatch:
|
|
14
14
|
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
|
|
18
|
+
concurrency:
|
|
19
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
20
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
21
|
+
|
|
15
22
|
jobs:
|
|
16
23
|
test:
|
|
24
|
+
name: Ruby ${{ matrix.ruby-version }} / Active Record ${{ matrix.active-record.label }}
|
|
17
25
|
runs-on: ubuntu-latest
|
|
26
|
+
timeout-minutes: 20
|
|
18
27
|
services:
|
|
19
28
|
postgres:
|
|
20
29
|
image: postgres:latest
|
|
@@ -32,49 +41,47 @@ jobs:
|
|
|
32
41
|
CI: true
|
|
33
42
|
PGHOST: 127.0.0.1
|
|
34
43
|
PGUSER: postgres
|
|
35
|
-
PGPASS: postgres
|
|
36
44
|
strategy:
|
|
37
45
|
fail-fast: false
|
|
38
46
|
matrix:
|
|
39
|
-
ruby-version: [
|
|
40
|
-
active-record
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
- ACTIVE_RECORD_VERSION="~> 7.2.0"
|
|
47
|
+
ruby-version: ["3.3", "3.4", "4.0"]
|
|
48
|
+
active-record:
|
|
49
|
+
- { label: "7.2", env: "ACTIVE_RECORD_VERSION=~> 7.2.0" }
|
|
50
|
+
- { label: "8.0", env: "ACTIVE_RECORD_VERSION=~> 8.0.0" }
|
|
51
|
+
- { label: "8.1", env: "ACTIVE_RECORD_VERSION=~> 8.1.0" }
|
|
45
52
|
allow-failure: [false]
|
|
46
|
-
exclude:
|
|
47
|
-
- ruby-version: '3.0'
|
|
48
|
-
active-record-version-env: ACTIVE_RECORD_VERSION="~> 7.2.0"
|
|
49
53
|
include:
|
|
50
|
-
- ruby-version:
|
|
51
|
-
active-record
|
|
54
|
+
- ruby-version: "4.0"
|
|
55
|
+
active-record: { label: "main", env: "ACTIVE_RECORD_BRANCH=main" }
|
|
52
56
|
allow-failure: true
|
|
53
|
-
- ruby-version:
|
|
54
|
-
active-record-
|
|
57
|
+
- ruby-version: "4.0"
|
|
58
|
+
active-record: { label: "8-1-stable", env: "ACTIVE_RECORD_BRANCH=8-1-stable" }
|
|
55
59
|
allow-failure: true
|
|
56
|
-
- ruby-version:
|
|
57
|
-
active-record-
|
|
60
|
+
- ruby-version: "4.0"
|
|
61
|
+
active-record: { label: "8-0-stable", env: "ACTIVE_RECORD_BRANCH=8-0-stable" }
|
|
58
62
|
allow-failure: true
|
|
59
|
-
- ruby-version:
|
|
60
|
-
active-record-
|
|
63
|
+
- ruby-version: "4.0"
|
|
64
|
+
active-record: { label: "7-2-stable", env: "ACTIVE_RECORD_BRANCH=7-2-stable" }
|
|
61
65
|
allow-failure: true
|
|
62
|
-
- ruby-version:
|
|
63
|
-
active-record
|
|
66
|
+
- ruby-version: "ruby-head"
|
|
67
|
+
active-record: { label: "8.1", env: "ACTIVE_RECORD_VERSION=~> 8.1.0" }
|
|
64
68
|
allow-failure: true
|
|
65
69
|
continue-on-error: ${{ matrix.allow-failure }}
|
|
66
70
|
steps:
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
71
|
+
- uses: actions/checkout@v6
|
|
72
|
+
- name: Select ActiveRecord version
|
|
73
|
+
env:
|
|
74
|
+
ACTIVE_RECORD_ENV: ${{ matrix.active-record.env }}
|
|
75
|
+
run: echo "$ACTIVE_RECORD_ENV" >> "$GITHUB_ENV"
|
|
76
|
+
- name: Set up Ruby
|
|
77
|
+
uses: ruby/setup-ruby@v1
|
|
78
|
+
with:
|
|
79
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
80
|
+
bundler-cache: true
|
|
81
|
+
cache-version: ${{ matrix.active-record.env }}
|
|
82
|
+
- name: Set up test database
|
|
83
|
+
env:
|
|
84
|
+
PGPASSWORD: postgres
|
|
85
|
+
run: createdb pg_search_test
|
|
86
|
+
- name: Run tests
|
|
87
|
+
run: bundle exec rake
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# For most projects, this workflow file will not need changing; you simply need
|
|
2
|
+
# to commit it to your repository.
|
|
3
|
+
#
|
|
4
|
+
# You may wish to alter this file to override the set of languages analyzed,
|
|
5
|
+
# or to provide custom queries or build logic.
|
|
6
|
+
#
|
|
7
|
+
# ******** NOTE ********
|
|
8
|
+
# We have attempted to detect the languages in your repository. Please check
|
|
9
|
+
# the `language` matrix defined below to confirm you have the correct set of
|
|
10
|
+
# supported CodeQL languages.
|
|
11
|
+
#
|
|
12
|
+
name: "CodeQL Advanced"
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
push:
|
|
16
|
+
branches: [ "master" ]
|
|
17
|
+
pull_request:
|
|
18
|
+
branches: [ "master" ]
|
|
19
|
+
schedule:
|
|
20
|
+
- cron: '28 0 * * 1'
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
analyze:
|
|
24
|
+
name: Analyze (${{ matrix.language }})
|
|
25
|
+
# Runner size impacts CodeQL analysis time. To learn more, please see:
|
|
26
|
+
# - https://gh.io/recommended-hardware-resources-for-running-codeql
|
|
27
|
+
# - https://gh.io/supported-runners-and-hardware-resources
|
|
28
|
+
# - https://gh.io/using-larger-runners (GitHub.com only)
|
|
29
|
+
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
permissions:
|
|
32
|
+
# required for all workflows
|
|
33
|
+
security-events: write
|
|
34
|
+
|
|
35
|
+
# required to fetch internal or private CodeQL packs
|
|
36
|
+
packages: read
|
|
37
|
+
|
|
38
|
+
# only required for workflows in private repositories
|
|
39
|
+
actions: read
|
|
40
|
+
contents: read
|
|
41
|
+
|
|
42
|
+
strategy:
|
|
43
|
+
fail-fast: false
|
|
44
|
+
matrix:
|
|
45
|
+
include:
|
|
46
|
+
- language: actions
|
|
47
|
+
build-mode: none
|
|
48
|
+
- language: ruby
|
|
49
|
+
build-mode: none
|
|
50
|
+
steps:
|
|
51
|
+
- name: Checkout repository
|
|
52
|
+
uses: actions/checkout@v4
|
|
53
|
+
|
|
54
|
+
# Initializes the CodeQL tools for scanning.
|
|
55
|
+
- name: Initialize CodeQL
|
|
56
|
+
uses: github/codeql-action/init@v4
|
|
57
|
+
with:
|
|
58
|
+
languages: ${{ matrix.language }}
|
|
59
|
+
build-mode: ${{ matrix.build-mode }}
|
|
60
|
+
# If you wish to specify custom queries, you can do so here or in a config file.
|
|
61
|
+
# By default, queries listed here will override any specified in a config file.
|
|
62
|
+
# Prefix the list here with "+" to use these queries and those in the config file.
|
|
63
|
+
|
|
64
|
+
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
|
65
|
+
# queries: security-extended,security-and-quality
|
|
66
|
+
|
|
67
|
+
# If the analyze step fails for one of the languages you are analyzing with
|
|
68
|
+
# "We were unable to automatically build your code", modify the matrix above
|
|
69
|
+
# to set the build mode to "manual" for that language. Then modify this step
|
|
70
|
+
# to build your code.
|
|
71
|
+
# ℹ️ Command-line programs to run using the OS shell.
|
|
72
|
+
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
|
73
|
+
- name: Run manual build steps
|
|
74
|
+
if: matrix.build-mode == 'manual'
|
|
75
|
+
shell: bash
|
|
76
|
+
run: |
|
|
77
|
+
echo 'If you are using a "manual" build mode for one or more of the' \
|
|
78
|
+
'languages you are analyzing, replace this with the commands to build' \
|
|
79
|
+
'your code, for example:'
|
|
80
|
+
echo ' make bootstrap'
|
|
81
|
+
echo ' make release'
|
|
82
|
+
exit 1
|
|
83
|
+
|
|
84
|
+
- name: Perform CodeQL Analysis
|
|
85
|
+
uses: github/codeql-action/analyze@v4
|
|
86
|
+
with:
|
|
87
|
+
category: "/language:${{matrix.language}}"
|
data/.standard.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# pg_search changelog
|
|
2
2
|
|
|
3
|
+
## 2.3.8
|
|
4
|
+
|
|
5
|
+
* Drop support for Ruby 3.0, 3.1, and 3.2
|
|
6
|
+
* Drop support for Active Record 6.1, 7.0, and 7.1
|
|
7
|
+
* Support Ruby 3.4 and 4.0
|
|
8
|
+
* Support Active Record 8.0 and 8.1
|
|
9
|
+
* Fix ordered searches and associated ordering that use the internal rank join (fatkodima)
|
|
10
|
+
* Sanitize query characters introduced by unaccent normalization (Misha Doronin)
|
|
11
|
+
* Support keyword arguments for dynamic rank and highlight accessors (Manuel Meurer)
|
|
12
|
+
* Quote custom primary key and inheritance column identifiers in multisearch rebuild SQL
|
|
13
|
+
* Improve documentation (Olli)
|
|
14
|
+
|
|
3
15
|
## 2.3.7
|
|
4
16
|
|
|
5
17
|
* Drop support for Ruby 2.6 and 2.7
|
data/Gemfile
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
source "https://rubygems.org"
|
|
3
|
+
source "https://rubygems.org", cooldown: 7
|
|
4
4
|
|
|
5
5
|
gemspec
|
|
6
6
|
|
|
@@ -14,15 +14,17 @@ end
|
|
|
14
14
|
|
|
15
15
|
gem "activerecord", ENV.fetch("ACTIVE_RECORD_VERSION", nil) if ENV["ACTIVE_RECORD_VERSION"] # standard:disable Bundler/DuplicatedGem
|
|
16
16
|
|
|
17
|
+
gem "benchmark"
|
|
17
18
|
gem "debug"
|
|
18
19
|
gem "irb"
|
|
20
|
+
gem "mutex_m"
|
|
19
21
|
gem "rake"
|
|
20
22
|
gem "rspec"
|
|
23
|
+
gem "ruby-lsp"
|
|
21
24
|
gem "simplecov"
|
|
22
25
|
gem "simplecov-lcov"
|
|
23
26
|
gem "standard", require: false
|
|
24
27
|
gem "standard-rails", require: false
|
|
25
28
|
gem "standard-rspec", require: false
|
|
26
|
-
gem "undercover"
|
|
27
29
|
gem "warning"
|
|
28
30
|
gem "with_model"
|
data/README.md
CHANGED
|
@@ -13,10 +13,10 @@ Read the blog post introducing PgSearch at https://tanzu.vmware.com/content/blog
|
|
|
13
13
|
|
|
14
14
|
## REQUIREMENTS
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
- Ruby 3.3+
|
|
17
|
+
- Active Record 7.2+
|
|
18
|
+
- PostgreSQL 9.2+
|
|
19
|
+
- [PostgreSQL extensions](https://github.com/Casecommons/pg_search/wiki/Installing-PostgreSQL-Extensions) for certain features
|
|
20
20
|
|
|
21
21
|
## INSTALL
|
|
22
22
|
|
|
@@ -51,45 +51,46 @@ end
|
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
### Contents
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
54
|
+
|
|
55
|
+
- [Multi-search vs. search scopes](#multi-search-vs-search-scopes)
|
|
56
|
+
- [Multi-search](#multi-search)
|
|
57
|
+
- [Setup](#setup)
|
|
58
|
+
- [`multisearchable`](#multisearchable)
|
|
59
|
+
- [More Options ](#more-options)
|
|
60
|
+
- [Multi-search associations](#multi-search-associations)
|
|
61
|
+
- [Searching in the global search index](#searching-in-the-global-search-index)
|
|
62
|
+
- [Chaining method calls onto the results](#chaining-method-calls-onto-the-results)
|
|
63
|
+
- [Configuring multi-search](#configuring-multi-search)
|
|
64
|
+
- [Rebuilding search documents for a given class](#rebuilding-search-documents-for-a-given-class)
|
|
65
|
+
- [Disabling multi-search indexing temporarily](#disabling-multi-search-indexing-temporarily)
|
|
66
|
+
- [`pg_search_scope`](#pg_search_scope)
|
|
67
|
+
- [Searching against one column](#searching-against-one-column)
|
|
68
|
+
- [Searching against multiple columns](#searching-against-multiple-columns)
|
|
69
|
+
- [Dynamic search scopes](#dynamic-search-scopes)
|
|
70
|
+
- [Searching through associations](#searching-through-associations)
|
|
71
|
+
- [Searching using different search features](#searching-using-different-search-features)
|
|
72
|
+
- [`:tsearch` (Full Text Search)](#tsearch-full-text-search)
|
|
73
|
+
- [Weighting](#weighting)
|
|
74
|
+
- [`:prefix` (PostgreSQL 8.4 and newer only)](#prefix-postgresql-84-and-newer-only)
|
|
75
|
+
- [`:negation`](#negation)
|
|
76
|
+
- [`:dictionary`](#dictionary)
|
|
77
|
+
- [`:normalization`](#normalization)
|
|
78
|
+
- [`:any_word`](#any_word)
|
|
79
|
+
- [`:sort_only`](#sort_only)
|
|
80
|
+
- [`:highlight`](#highlight)
|
|
81
|
+
- [`:dmetaphone` (Double Metaphone soundalike search)](#dmetaphone-double-metaphone-soundalike-search)
|
|
82
|
+
- [`:trigram` (Trigram search)](#trigram-trigram-search)
|
|
83
|
+
- [`:threshold`](#threshold)
|
|
84
|
+
- [`:word_similarity`](#word_similarity)
|
|
85
|
+
- [Limiting Fields When Combining Features](#limiting-fields-when-combining-features)
|
|
86
|
+
- [Ignoring accent marks](#ignoring-accent-marks)
|
|
87
|
+
- [Using tsvector columns](#using-tsvector-columns)
|
|
88
|
+
- [Combining multiple tsvectors](#combining-multiple-tsvectors)
|
|
89
|
+
- [Configuring ranking and ordering](#configuring-ranking-and-ordering)
|
|
90
|
+
- [`:ranked_by` (Choosing a ranking algorithm)](#ranked_by-choosing-a-ranking-algorithm)
|
|
91
|
+
- [`:order_within_rank` (Breaking ties)](#order_within_rank-breaking-ties)
|
|
92
|
+
- [`PgSearch#pg_search_rank` (Reading a record's rank as a Float)](#pgsearchpg_search_rank-reading-a-records-rank-as-a-float)
|
|
93
|
+
- [Search rank and chained scopes](#search-rank-and-chained-scopes)
|
|
93
94
|
|
|
94
95
|
### Multi-search vs. search scopes
|
|
95
96
|
|
|
@@ -246,8 +247,8 @@ This allows much faster searches without joins later on by doing something like:
|
|
|
246
247
|
PgSearch.multisearch(params['search']).where(author_id: 2)
|
|
247
248
|
```
|
|
248
249
|
|
|
249
|
-
|
|
250
|
-
the additional attribute to be included in the pg_search_documents
|
|
250
|
+
_NOTE: You must currently manually call `record.update_pg_search_document` for
|
|
251
|
+
the additional attribute to be included in the pg_search_documents table_
|
|
251
252
|
|
|
252
253
|
#### Multi-search associations
|
|
253
254
|
|
|
@@ -331,18 +332,18 @@ To regenerate the documents for a given class, run:
|
|
|
331
332
|
PgSearch::Multisearch.rebuild(Product)
|
|
332
333
|
```
|
|
333
334
|
|
|
334
|
-
The
|
|
335
|
+
The `rebuild` method will delete all the documents for the given class
|
|
335
336
|
before regenerating them. In some situations this may not be desirable,
|
|
336
|
-
such as when you're using single-table inheritance and
|
|
337
|
-
is your base class. You can prevent
|
|
337
|
+
such as when you're using single-table inheritance and `searchable_type`
|
|
338
|
+
is your base class. You can prevent `rebuild` from deleting your records
|
|
338
339
|
like so:
|
|
339
340
|
|
|
340
341
|
```ruby
|
|
341
342
|
PgSearch::Multisearch.rebuild(Product, clean_up: false)
|
|
342
343
|
```
|
|
343
344
|
|
|
344
|
-
|
|
345
|
-
you can pass
|
|
345
|
+
`rebuild` runs inside a single transaction. To run outside of a transaction,
|
|
346
|
+
you can pass `transactional: false` like so:
|
|
346
347
|
|
|
347
348
|
```ruby
|
|
348
349
|
PgSearch::Multisearch.rebuild(Product, transactional: false)
|
|
@@ -399,7 +400,8 @@ class Movie < ActiveRecord::Base
|
|
|
399
400
|
end
|
|
400
401
|
end
|
|
401
402
|
```
|
|
402
|
-
|
|
403
|
+
|
|
404
|
+
**Note:** If using PostgreSQL before 9.1, replace the `CONCAT_WS()` function call with double-pipe concatenation, eg. `(movies.name || ' ' || directors.name)`. However, now be aware that if _any_ of the joined values is NULL then the final `content` value will also be NULL, whereas `CONCAT_WS()` will selectively ignore NULL values.
|
|
403
405
|
|
|
404
406
|
#### Disabling multi-search indexing temporarily
|
|
405
407
|
|
|
@@ -569,11 +571,10 @@ end
|
|
|
569
571
|
|
|
570
572
|
The currently implemented features are
|
|
571
573
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
574
|
+
- :tsearch - [Full text search](http://www.postgresql.org/docs/current/static/textsearch-intro.html), which is built-in to PostgreSQL
|
|
575
|
+
- :trigram - [Trigram search](http://www.postgresql.org/docs/current/static/pgtrgm.html), which
|
|
576
|
+
requires the trigram extension
|
|
577
|
+
- :dmetaphone - [Double Metaphone search](http://www.postgresql.org/docs/current/static/fuzzystrmatch.html#AEN177521), which requires the fuzzystrmatch extension
|
|
577
578
|
|
|
578
579
|
#### :tsearch (Full Text Search)
|
|
579
580
|
|
|
@@ -581,6 +582,7 @@ PostgreSQL's built-in full text search supports weighting, prefix searches,
|
|
|
581
582
|
and stemming in multiple languages.
|
|
582
583
|
|
|
583
584
|
##### Weighting
|
|
585
|
+
|
|
584
586
|
Each searchable column can be given a weight of "A", "B", "C", or "D". Columns
|
|
585
587
|
with earlier letters are weighted higher than those with later letters. So, in
|
|
586
588
|
the following example, the title is the most important, followed by the
|
|
@@ -644,6 +646,7 @@ robin = Superhero.create name: 'Robin'
|
|
|
644
646
|
|
|
645
647
|
Superhero.whose_name_starts_with("Bat") # => [batman, batgirl]
|
|
646
648
|
```
|
|
649
|
+
|
|
647
650
|
##### :negation
|
|
648
651
|
|
|
649
652
|
PostgreSQL's full text search matches all search terms by default. If you want
|
|
@@ -804,7 +807,6 @@ Person.search('ash hines') # => [exact, one_exact_one_close, one_exact]
|
|
|
804
807
|
Adding .with_pg_search_highlight after the pg_search_scope you can access to
|
|
805
808
|
`pg_highlight` attribute for each object.
|
|
806
809
|
|
|
807
|
-
|
|
808
810
|
```ruby
|
|
809
811
|
class Person < ActiveRecord::Base
|
|
810
812
|
include PgSearch::Model
|
|
@@ -815,8 +817,8 @@ class Person < ActiveRecord::Base
|
|
|
815
817
|
highlight: {
|
|
816
818
|
StartSel: '<b>',
|
|
817
819
|
StopSel: '</b>',
|
|
818
|
-
|
|
819
|
-
|
|
820
|
+
MinWords: 123,
|
|
821
|
+
MaxWords: 456,
|
|
820
822
|
ShortWord: 4,
|
|
821
823
|
HighlightAll: true,
|
|
822
824
|
MaxFragments: 3,
|
|
@@ -1053,31 +1055,31 @@ as it offloads creation of the tsvector that the tsquery is evaluated against.
|
|
|
1053
1055
|
|
|
1054
1056
|
To use this functionality you'll need to do a few things:
|
|
1055
1057
|
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1058
|
+
- Create a column of type tsvector that you'd like to search against. If you
|
|
1059
|
+
want to search using multiple search methods, for example tsearch and
|
|
1060
|
+
dmetaphone, you'll need a column for each.
|
|
1061
|
+
- Create a trigger function that will update the column(s) using the
|
|
1062
|
+
expression appropriate for that type of search. See:
|
|
1063
|
+
[the PostgreSQL documentation for text search triggers](http://www.postgresql.org/docs/current/static/textsearch-features.html#TEXTSEARCH-UPDATE-TRIGGERS)
|
|
1064
|
+
- Should you have any pre-existing data in the table, update the
|
|
1065
|
+
newly-created tsvector columns with the expression that your trigger
|
|
1066
|
+
function uses.
|
|
1067
|
+
- Add the option to pg_search_scope, e.g:
|
|
1068
|
+
|
|
1069
|
+
```ruby
|
|
1070
|
+
pg_search_scope :fast_content_search,
|
|
1071
|
+
against: :content,
|
|
1072
|
+
using: {
|
|
1073
|
+
dmetaphone: {
|
|
1074
|
+
tsvector_column: 'tsvector_content_dmetaphone'
|
|
1075
|
+
},
|
|
1076
|
+
tsearch: {
|
|
1077
|
+
dictionary: 'english',
|
|
1078
|
+
tsvector_column: 'tsvector_content_tsearch'
|
|
1079
|
+
},
|
|
1080
|
+
trigram: {} # trigram does not use tsvectors
|
|
1081
|
+
}
|
|
1082
|
+
```
|
|
1081
1083
|
|
|
1082
1084
|
Please note that the :against column is only used when the tsvector_column is
|
|
1083
1085
|
not present for the search type.
|
|
@@ -1190,9 +1192,9 @@ shirt_brands[1].pg_search_rank #=> 0.0607927
|
|
|
1190
1192
|
|
|
1191
1193
|
#### Search rank and chained scopes
|
|
1192
1194
|
|
|
1193
|
-
Each PgSearch scope generates a named subquery for the search rank.
|
|
1195
|
+
Each PgSearch scope generates a named subquery for the search rank. If you
|
|
1194
1196
|
chain multiple scopes then PgSearch will generate a ranking query for each
|
|
1195
|
-
scope, so the ranking queries must have unique names.
|
|
1197
|
+
scope, so the ranking queries must have unique names. If you need to reference
|
|
1196
1198
|
the ranking query (e.g. in a GROUP BY clause) you can regenerate the subquery
|
|
1197
1199
|
name with the `PgScope::Configuration.alias` method by passing the name of the
|
|
1198
1200
|
queried table.
|
data/Rakefile
CHANGED
|
@@ -8,10 +8,4 @@ RSpec::Core::RakeTask.new(:spec)
|
|
|
8
8
|
|
|
9
9
|
require "standard/rake"
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
task :undercover do
|
|
13
|
-
system("git fetch --unshallow") if ENV["CI"]
|
|
14
|
-
exit(1) unless system("bin/undercover --compare origin/master")
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
task default: %w[spec standard undercover]
|
|
11
|
+
task default: %w[spec standard]
|
|
@@ -23,9 +23,7 @@ module PgSearch
|
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
def columns
|
|
27
|
-
regular_columns + associated_columns
|
|
28
|
-
end
|
|
26
|
+
def columns = regular_columns + associated_columns
|
|
29
27
|
|
|
30
28
|
def regular_columns
|
|
31
29
|
return [] unless options[:against]
|
|
@@ -43,37 +41,21 @@ module PgSearch
|
|
|
43
41
|
end.flatten
|
|
44
42
|
end
|
|
45
43
|
|
|
46
|
-
def associated_columns
|
|
47
|
-
associations.map(&:columns).flatten
|
|
48
|
-
end
|
|
44
|
+
def associated_columns = associations.map(&:columns).flatten
|
|
49
45
|
|
|
50
|
-
def query
|
|
51
|
-
options[:query].to_s
|
|
52
|
-
end
|
|
46
|
+
def query = options[:query].to_s
|
|
53
47
|
|
|
54
|
-
def ignore
|
|
55
|
-
Array(options[:ignoring])
|
|
56
|
-
end
|
|
48
|
+
def ignore = Array(options[:ignoring])
|
|
57
49
|
|
|
58
|
-
def ranking_sql
|
|
59
|
-
options[:ranked_by]
|
|
60
|
-
end
|
|
50
|
+
def ranking_sql = options[:ranked_by]
|
|
61
51
|
|
|
62
|
-
def features
|
|
63
|
-
Array(options[:using])
|
|
64
|
-
end
|
|
52
|
+
def features = Array(options[:using])
|
|
65
53
|
|
|
66
54
|
def feature_options
|
|
67
|
-
@feature_options ||=
|
|
68
|
-
features.map do |feature_name, feature_options|
|
|
69
|
-
hash[feature_name] = feature_options
|
|
70
|
-
end
|
|
71
|
-
end
|
|
55
|
+
@feature_options ||= features.to_h { |name, opts| [name, opts] }
|
|
72
56
|
end
|
|
73
57
|
|
|
74
|
-
def order_within_rank
|
|
75
|
-
options[:order_within_rank]
|
|
76
|
-
end
|
|
58
|
+
def order_within_rank = options[:order_within_rank]
|
|
77
59
|
|
|
78
60
|
private
|
|
79
61
|
|
|
@@ -83,6 +65,7 @@ module PgSearch
|
|
|
83
65
|
{using: :tsearch}
|
|
84
66
|
end
|
|
85
67
|
|
|
68
|
+
# standard:disable Lint/UselessConstantScoping
|
|
86
69
|
VALID_KEYS = %w[
|
|
87
70
|
against ranked_by ignoring using query associated_against order_within_rank
|
|
88
71
|
].map(&:to_sym)
|
|
@@ -90,6 +73,7 @@ module PgSearch
|
|
|
90
73
|
VALID_VALUES = {
|
|
91
74
|
ignoring: [:accents]
|
|
92
75
|
}.freeze
|
|
76
|
+
# standard:enable Lint/UselessConstantScoping
|
|
93
77
|
|
|
94
78
|
def assert_valid_options(options)
|
|
95
79
|
unless options[:against] || options[:associated_against] || using_tsvector_column?(options[:using])
|