Drizzle | 생성된 컬럼을 사용한 전체 텍스트 검색
This guide assumes familiarity with:
- Get started with PostgreSQL
- Select statement
- Indexes
- sql operator
- Full-text search
- Generated columns
이 가이드는 Drizzle과 생성된 컬럼을 사용하여 PostgreSQL에서 전체 텍스트 검색을 구현하는 방법을 설명합니다. 생성된 컬럼은 항상 다른 컬럼으로부터 계산되는 특수한 컬럼입니다. 테이블을 쿼리할 때마다 컬럼의 값을 계산할 필요가 없기 때문에 유용합니다:
schema.ts
migration.sql
import { SQL, sql } from 'drizzle-orm';
import { index, pgTable, serial, text, customType } from 'drizzle-orm/pg-core';
export const tsvector = customType<{
data: string;
}>({
dataType() {
return `tsvector`;
},
});
export const posts = pgTable(
'posts',
{
id: serial('id').primaryKey(),
title: text('title').notNull(),
body: text('body').notNull(),
bodySearch: tsvector('body_search')
.notNull()
.generatedAlwaysAs((): SQL => sql`to_tsvector('english', ${posts.body})`),
},
(t) => [
index('idx_body_search').using('gin', t.bodySearch),
]
);테이블에 행을 삽입할 때, 생성된 컬럼의 값은 컬럼을 생성할 때 제공한 표현식으로부터 계산됩니다:
import { posts } from './schema';
const db = drizzle(...);
const body = "Golden leaves cover the quiet streets as a crisp breeze fills the air, bringing the scent of rain and the promise of change"
await db.insert(posts).values({
body,
title: "The Beauty of Autumn",
}
).returning();[
{
id: 1,
title: 'The Beauty of Autumn',
body: 'Golden leaves cover the quiet streets as a crisp breeze fills the air, bringing the scent of rain and the promise of change',
bodySearch: "'air':13 'breez':10 'bring':14 'chang':23 'cover':3 'crisp':9 'fill':11 'golden':1 'leav':2 'promis':21 'quiet':5 'rain':18 'scent':16 'street':6"
}
]다음은 Drizzle ORM으로 PostgreSQL에서 생성된 컬럼을 사용하여 전체 텍스트 검색을 구현하는 방법입니다. @@ 연산자는 직접 일치를 위해 사용됩니다:
const searchParam = "bring";
await db
.select()
.from(posts)
.where(sql`${posts.bodySearch} @@ to_tsquery('english', ${searchParam})`);select * from posts where body_search @@ to_tsquery('english', 'bring');다음은 생성된 컬럼을 사용한 더 고급 스키마입니다. search 컬럼은 title과 body 컬럼으로부터 생성되며, setweight() 함수는 전체 텍스트 검색을 위해 컬럼에 서로 다른 가중치를 할당하는 데 사용됩니다.
이는 일반적으로 제목과 본문과 같이 문서의 다른 부분에서 오는 항목을 표시하는 데 사용됩니다.
schema.ts
migration.sql
import { SQL, sql } from 'drizzle-orm';
import { index, pgTable, serial, text, customType } from 'drizzle-orm/pg-core';
export const tsvector = customType<{
data: string;
}>({
dataType() {
return `tsvector`;
},
});
export const posts = pgTable(
'posts',
{
id: serial('id').primaryKey(),
title: text('title').notNull(),
body: text('body').notNull(),
search: tsvector('search')
.notNull()
.generatedAlwaysAs(
(): SQL =>
sql`setweight(to_tsvector('english', ${posts.title}), 'A')
||
setweight(to_tsvector('english', ${posts.body}), 'B')`,
),
},
(t) => [
index('idx_search').using('gin', t.search),
],
);다음은 전체 텍스트 검색으로 테이블을 쿼리하는 방법입니다:
const search = 'travel';
await db
.select()
.from(posts)
.where(sql`${posts.search} @@ to_tsquery('english', ${search})`);select * from posts where search @@ to_tsquery('english', 'travel');