There is some way to handle full text search with Postgres and TypeOrm. I've seen some examples but they only work with Mysql. How can I get the equivalent of this but with Postgresql?
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: string;
@Index({ fulltext: true })
@Column("varchar")
name: string;
}
And use query builder:
const searchTerm = "John";
const result = await connection.manager.getRepository(User)
.createQueryBuilder()
.select()
.where(`MATCH(name) AGAINST ('${searchTerm}' IN BOOLEAN MODE)`)
.getMany();
Implementing Full-text search in PostgreSQL. Full-Text search refers to the technique of searching a single document or a collection in a full-text database.
If you need to search all values that have a particular word or phrase in a SQL database table with Typeorm, here is a quick example. This will correspond to a SQL table with the id, fullName, username and description columns. MySQL FUll-Text Search with MATCH ... AGAINST
MySQL FUll-Text Search with MATCH ... AGAINST If you want to use the MySql fulltext feature, you need to create a fulltext index with @Index ( { fulltext: true }) and use query builder to build a query with SQL syntax. This will search for the specified search text in the fullName, username or description columns using the MATCH () ...
PostgreSQL provides two predefined ranking functions, which take into account lexical, proximity, and structural information; that is, they consider how often the query terms appear in the document, how close together the terms are in the document, and how important is the part of the document where they occur.
Here's an alternative using tsvector, where query is the input string.
const songs = await getManager()
.createQueryBuilder()
.select('song')
.from(Models.Song, 'song')
.where(
'to_tsvector(song.title) @@ to_tsquery(:query)',
{ query }
)
.getMany();
If you wish to include stop words (You, A, etc), and want partial matching.
const songs = await getManager()
.createQueryBuilder()
.select('song')
.from(Models.Song, 'song')
.where(
`to_tsvector('simple',song.title) @@ to_tsquery('simple', :query)`,
{ query: `${query}:*` }
)
.getMany();
If you also want to allow for multi word strings (with spaces).
const formattedQuery = query.trim().replace(/ /g, ' & ');
const songs = await getManager()
.createQueryBuilder()
.select('song')
.from(Models.Song, 'song')
.where(
`to_tsvector('simple',song.title) @@ to_tsquery('simple', :query)`,
{ query: `${formattedQuery}:*` }
)
.getMany();
For Full-Text Search (FTS), I would recommend you to use PostgreSQL specific functions on the WHERE clause. The LIKE & ILIKE operators are too simple and too slow for a Full-Text Search. I suggest you also watch this video. It really explains clearly and easily on how to implement such a feature with PostgreSQL and at the last minutes, it shows how it implements it with Node.js.
I hope that helps! Please let me know if there is anything else I can help you with.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With