키워드
는 연관 상품을 검색할 때 사용합니다. ( 키워드는 공백 기준으로 분리해서 입력받습니다. )
기존 방식은 product
테이블에 키워드를 문자열을 그대로 넣는 방식을 사용했습니다.
이후에 검색어 자동완성 기능을 만들려고 할 때 곰곰이 생각해 보니 키워드가 중복될 때의 데이터가 반복되는 문제가 있으며, 가져올 때도 더 편하고 쉽게 구분해서 가져오도록 하려다 보니까 키워드 테이블을 따로 분리해서 N : M
관계로 생성하는 것이 더 좋다고 생각해서 분리했습니다.
기존 스키마 정의 ( prisma )
model Product {
id Int @id @default(autoincrement())
name String @db.VarChar(30)
price Int
description String @db.MediumText
image String?
keywords String @db.VarChar(40)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
records Record[]
answers Answer[]
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId Int
@@index([userId])
}
현재 스키마 정의 ( prisma )
model Product {
id Int @id @default(autoincrement())
name String @db.VarChar(30)
price Int
description String @db.MediumText
image String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
records Record[]
answers Answer[]
keywords Keyword[]
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId Int
@@index([userId])
}
model Keyword {
id Int @id @default(autoincrement())
keyword String @unique @db.VarChar(20)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
products Product[]
}
// async 함수 내부에 있다고 가정
const createdProduct = await prisma.product.create({
data: {
name,
price: +price,
description,
image: photo ? photo : null,
keywords,
user: {
connect: {
id: user?.id,
},
},
},
});
// async 함수 내부에 있다고 가정
const createdProduct = await prisma.product.create({
data: {
name,
price: +price,
description,
image: photo ? photo : null,
user: {
connect: {
id: user?.id,
},
},
},
});
// 키워드 생성 or 찾고 상품과 연결
const keywordsPromise = (keywords as string).split(" ").map((keyword) =>
prisma.keyword.upsert({
create: {
keyword,
products: {
connect: {
id: createdProduct.id,
},
},
},
update: {
products: {
connect: {
id: createdProduct.id,
},
},
},
where: {
keyword,
},
})
);
await Promise.all(keywordsPromise);
나머지 상품 가져오기, 연관 상품 가져오기 등의 코드도 변경된 형태에 맞게 수정했습니다.