使用 TypeOrm 进行 Postgresql 全文搜索

hna*_*o11 7 postgresql typeorm

有一些方法可以使用 Postgres 和 TypeOrm 处理全文搜索。我看过一些例子,但它们只适用于 Mysql。我怎样才能得到与这个相同的东西,但使用 Postgresql?

@Entity()
export class User {

    @PrimaryGeneratedColumn()
    id: string;

    @Index({ fulltext: true })
    @Column("varchar")
    name: string;
}
Run Code Online (Sandbox Code Playgroud)

并使用查询构建器:

const searchTerm = "John";

const result = await connection.manager.getRepository(User)
            .createQueryBuilder()
            .select()
            .where(`MATCH(name) AGAINST ('${searchTerm}' IN BOOLEAN MODE)`)
            .getMany();
Run Code Online (Sandbox Code Playgroud)

rt_*_*rt_ 19

这是使用 tsvector 的替代方法,其中 query 是输入字符串。

      const songs = await getManager()
        .createQueryBuilder()
        .select('song')
        .from(Models.Song, 'song')
        .where(
          'to_tsvector(song.title) @@ to_tsquery(:query)',
          { query }
        )
        .getMany();
Run Code Online (Sandbox Code Playgroud)

如果您希望包含停用词(您、A 等),并希望进行部分匹配。

      const songs = await getManager()
        .createQueryBuilder()
        .select('song')
        .from(Models.Song, 'song')
        .where(
          `to_tsvector('simple',song.title) @@ to_tsquery('simple', :query)`,
          { query: `${query}:*` }
        )
        .getMany();

Run Code Online (Sandbox Code Playgroud)

如果您还想允许多字串(带空格)。

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

Run Code Online (Sandbox Code Playgroud)


geo*_*rax 9

对于全文搜索 (FTS),我建议您在 WHERE 子句上使用PostgreSQL特定函数。LIKE 和 ILIKE 运算符对于全文搜索来说太简单也太慢了。我建议你也看这个视频。它确实清楚而轻松地解释了如何使用 PostgreSQL 实现这样的功能,并在最后几分钟展示了它如何使用 Node.js 实现它。

我希望这有帮助!如果还有什么我可以帮你的,请告诉我。


loc*_*ock 8

对于不区分大小写的搜索,我通常使用ILIKEPostgreSQL 表达式。例如;

const searchTerm = "John";

const result = await connection.manager.getRepository(User)
  .createQueryBuilder()
  .select()
  .where('name ILIKE :searchTerm', {searchTerm: `%${searchTerm}%`})
  .getMany();
Run Code Online (Sandbox Code Playgroud)

或者,如果您有名字和姓氏列。

const result = await connection.manager.getRepository(User)
  .createQueryBuilder()
  .select()
  .where('first_name ILIKE :searchTerm', {searchTerm: `%${searchTerm}%`})
  .orWhere('last_name ILIKE :searchTerm', {searchTerm: `%${searchTerm}%`})
  .getMany();
Run Code Online (Sandbox Code Playgroud)