
Discover how to Perform Full-Text Search on a PostgreSQL Database, enabling efficient retrieval of relevant information from extensive text datasets with advanced indexing and search features.
A PostgreSQL full-text search allows you to find records that match certain keywords with a high degree of accuracy. This query technique is fast because it implements indices, advanced query functions, and rules. In a production environment, you should use full-text search to address limitations posed by pattern matching search expressions.
For instance, in an e-commerce website, a customer searches for Party Dress. A pattern matching search algorithm can't return records with partial matches like Party Ready Dress. Therefore, pattern matches are inaccurate and slow because they don't implement indices. PostgreSQL full-text search addresses these problems. It provides flexibility, accuracy, and speed to find records and rank results according to relevance.
To accomplishment this, PostgreSQL uses the to_tsvector() and the to_tsquery() functions. This guide walks you through the process of implementing a full-text search in your PostgreSQL database.
To follow along with this guide, you require:
Follow the steps below to set up a sample database, create a table, and insert some test records.
SSH to your Linux server as a non-root sudo user.
Log in to the PostgreSQL server as the postgres user.
Enter the password and press Enter to proceed.
Create a sample e_commerce database.
Output.
Switch to the new e_commerce database.
Output.
Create a products table. This table stores the products' details including the unique product_id, product_name, and retail_price. Use the SERIAL keyword on the PRIMARY KEY column to allow the PostgreSQL server to assign new product_ids automatically for new records.
Output.
Insert sample data into the products table.
Output.
Ensure the sample data is in place by running a SELECT statement against the products table.
Output.
The power of the PostgreSQL full-text searches lies in the to_tsvector() and the to_tsquery() functions. Here is a summary of how each function works.
This function calls an internal PostgreSQL parser to break down a document or column values into individual words(tokens). The function further reduces the tokens to lexemes(base words) so that a word like coming converts to come and mangoes becomes mango. In the end, the to_tsvector() function returns a tsvector list containing all base words and their positions with stop words like a and the stripped.
Run the to_tsvector() function against the phrase, "The big boys are coming to eat the mangoes after their fathers accepted their apologies" to see how it works.
The above to_tsvector() command outputs the tsvector list below. All words are now stemmed to their base terms and stop words like the, are, to, and after are now excluded.
The to_tsquery() function converts a keyword or keyphrase to normalized tokens. In other words, the to_tsquery() function compiles a search term into a structure that the PostgreSQL server can understand when locating documents/records in a tsvector list.
With a basic knowledge of how the two full-text search functions work, you can now test them in your database.
When performing a full-text searches on a PostgreSQL database, you must implement the to_tsvector() and to_tsquery() functions together with a match operator @@.
The match operator returns a boolean value (either t or f) when you run a keyword search (tsquery) against a tsvector document.
Run a regular search using the keyword rib against your products table before implementing the full-text functions.
The regular search output below shows two records: the RIB MEAT and RIBENA JUICE. However, the above search method is not intelligent enough to know that RIB is unrelated to RIBENA JUICE.
Perform the same search again using the to_tsvector and to_tsquery() functions.
From the output below, it's clear that the full-text search is intelligent enough to know that RIBENA JUICE is not related to RIB and, therefore, returns only one record. That is the RIB MEAT.
Perform another full-text search using the MOUSE keyword.
The above query returns three records, as shown below.
To offer more flexibility when searching large recordsets, the PostgreSQL database server supports different search operators as detailed below.
Use the AND/& operator to return only the records/documents containing all the & separated list of keywords.
Run the query below to return all DELL WIRELESS products.
The query above returns the following output.
Use the OR/| operator to return records matching one or more search keywords.
Execute the following query to return all products from the LOGITECH and HP brands.
The query above returns the following result.
Use the NOT/! operator to exclude records containing a particular keyword.
Run the following statement to exclude all DELL products from the search result.
The output below displays all products without the DELL products.
Use the double quotation mark '' operator to return records that match the exact search term.
Run the command below to search for the phrase DELL WIRELESS KEYBOARD.
From the output below, only one record exactly matches the DELL WIRELESS KEYBOARD keyword.
You may combine multiple search operators in a single query to perform more complex full-text queries.
Run the query below to return the WIRELESS MOUSE products from the DELL or HP companies only.
The query returns the two products below.
In a PostgreSQL database, the full-text functions work fast because the tsvector data type implements indices. The only difficult task that the database server does during the search is computing the vectors. To speed up operations when working with large datasets, a good practice is to pre-compute the vectors and store them alongside your records in a separate column.
With this approach, the database server computes the vectors only once unless you update the existing records. This speeds up the full-text search operations by a large margin. Follow the steps below to add pre-computed vectors into your products table.
Add a TSVECTOR data type column to the products table and name it product_name_tokens.
Output.
Update the records in the products table to include new vector information by converting the product names using the statement to_tsvector(p.product_name).
Output.
Query the products table to make sure you've computed the vectors successfully.
The output below shows the records together with the pre-computed vectors. Press Q to proceed.
Run a query against the TSVECTOR data type column (product_name_tokens) to search for the keyword RIBENA.
As you can see from the output below, your query works as expected without the need to compute the vectors during the search operation.
In this guide, you've used the PostgreSQL inbuilt functions to implement full-text searches in a sample database. You're also able to use basic full-text search operators like &, |, and !. Towards the end, you've learned how to save time by pre-computing vectors when working with large datasets. Use the knowledge in this guide to power your next PostgreSQL search engine project.
0 Comments
Be the first to comment and share your perspective with the community.