Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Postgresql full text search with TypeOrm

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();
like image 317
hnakao11 Avatar asked Jan 21 '20 21:01

hnakao11


People also ask

What is full-text search in PostgreSQL?

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.

How to search all values in a SQL table with typeorm?

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

How to do a full text search in MySQL?

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 () ...

How does PostgreSQL rank data?

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.


2 Answers

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();

like image 184
rt_ Avatar answered Sep 18 '22 15:09

rt_


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.

like image 25
georgekrax Avatar answered Sep 18 '22 15:09

georgekrax