Skip to content

Commit

Permalink
Improve the search speed
Browse files Browse the repository at this point in the history
Add tsvactor_column to store the tsvector - content in the database. This speeds up the search speed on large table, because these value isn't calculated on fly anymore. A dictionary configuration to allow to setup the used PostgreSQL dictionary.
  • Loading branch information
sascha-karnatz committed Dec 19, 2023
1 parent 31d31d4 commit 23d9929
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 8 deletions.
27 changes: 21 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ Run install script:
$ bin/rails g alchemy:pg_search:install
```

> [!NOTE]
> The installation will generate an autogenerated column which can be configured with a language. The default
> value should work for the most languages. If you wish to change this behavior you should add
> the `Alchemy::PgSearch.config`
> into the project initializer before running the install script. (See [Configure Behavior](#configure-behavior))
## Usage

Every `Ingredient` will be indexed unless you tell Alchemy to not index a specific content.
Expand Down Expand Up @@ -88,10 +94,16 @@ Configure the gem in an initializer. The default configurations are:

```ruby
Alchemy::PgSearch.config = {
paginate_per: 10, # amount of results per page
dictionary: 'simple',
paginate_per: 10
}
```

Configuration Name | Default Value | Description
--------------------|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
dictionary | simple | Dictionary for the multisearch tsearch - config, which is used to find the content. The dictionary can impact the amout found documents, because it removes language specific stop words. See more in the [PostgreSQL documentation](https://www.postgresql.org/docs/current/textsearch-dictionaries.html).
paginate_per | 10 | Amount of results per page. The value can be set to `nil` to disable the pagination.

You can also overwrite the default multisearch configuration to use other search strategies. For more information take
a look into the [PgSearch Readme](https://github.com/Casecommons/pg_search#configuring-multi-search).

Expand All @@ -107,7 +119,8 @@ end

### Rendering search results.

In order to render the search results, you'll need a page layout that represents the search result page. Simply mark a page layout as `searchresults: true`. The search form will pick this page as result page.
In order to render the search results, you'll need a page layout that represents the search result page. Simply mark a
page layout as `searchresults: true`. The search form will pick this page as result page.

#### Search Results Page

Expand All @@ -118,24 +131,26 @@ In order to render the search results, you'll need a page layout that represents
unique: true
```

Tip: For maximum flexibility you could also add an element that represents the search results. This lets your editors to place additional elements (maybe a header image or additional text blocks) on the search result page.
Tip: For maximum flexibility you could also add an element that represents the search results. This lets your editors to
place additional elements (maybe a header image or additional text blocks) on the search result page.

```yaml
# page_layouts.yml
- name: search
searchresults: true
unique: true
elements:
- searchresults
- searchresults
autogenerate:
- searchresults
- searchresults
# elements.yml
- name: searchresults
unique: true
```

and then use the view helpers to render the search form on the page layout partial and the search results on the element view partial.
and then use the view helpers to render the search form on the page layout partial and the search results on the element
view partial.

### View Helpers

Expand Down
16 changes: 16 additions & 0 deletions db/migrate/20231218165617_add_searchable_content.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class AddSearchableContent < ActiveRecord::Migration[6.0]
def up
unless column_exists? :pg_search_documents, :searchable_content
execute %|ALTER TABLE pg_search_documents
ADD COLUMN searchable_content tsvector GENERATED ALWAYS AS (
to_tsvector('#{Alchemy::PgSearch.config[:dictionary]}', coalesce(content, ''))
) STORED;|
end
end

def down
if column_exists? :pg_search_documents, :searchable_content
remove_column :pg_search_documents, :searchable_content
end
end
end
1 change: 1 addition & 0 deletions lib/alchemy/pg_search/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module Alchemy
module PgSearch
module Config
@@config = {
dictionary: 'simple',
paginate_per: 10
}

Expand Down
6 changes: 5 additions & 1 deletion lib/alchemy/pg_search/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ class Engine < ::Rails::Engine
# @link https://github.com/Casecommons/pg_search#searching-using-different-search-features
::PgSearch.multisearch_options = {
using: {
tsearch: { prefix: true }
tsearch: {
prefix: true,
dictionary: Alchemy::PgSearch.config[:dictionary],
tsvector_column: 'searchable_content'
}
}
}
end
Expand Down
16 changes: 16 additions & 0 deletions spec/dummy/db/migrate/20231218165617_add_searchable_content.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class AddSearchableContent < ActiveRecord::Migration[6.0]
def up
unless column_exists? :pg_search_documents, :searchable_content
execute %|ALTER TABLE pg_search_documents
ADD COLUMN searchable_content tsvector GENERATED ALWAYS AS (
to_tsvector('#{Alchemy::PgSearch.config[:dictionary]}', coalesce(content, ''))
) STORED;|
end
end

def down
if column_exists? :pg_search_documents, :searchable_content
remove_column :pg_search_documents, :searchable_content
end
end
end
3 changes: 2 additions & 1 deletion spec/dummy/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2023_07_24_074129) do
ActiveRecord::Schema[7.0].define(version: 2023_12_18_165617) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

Expand Down Expand Up @@ -376,6 +376,7 @@
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.bigint "page_id"
t.virtual "searchable_content", type: :tsvector, as: "to_tsvector('simple'::regconfig, COALESCE(content, ''::text))", stored: true
t.index ["page_id"], name: "index_pg_search_documents_on_page_id"
t.index ["searchable_type", "searchable_id"], name: "index_pg_search_documents_on_searchable_type_and_searchable_id"
end
Expand Down

0 comments on commit 23d9929

Please sign in to comment.