prismaのクエリで1対多の「多に存在しないデータ」という条件で1を取り出す
ユーザー、お知らせ、ユーザーが既読したお知らせ、というデータ(テーブル)があり「ユーザーが既読していない全てのお知らせ」をprismaのクエリのみだけで取り出したい。
schema.prismaは以下
model User { id Int @id @default(autoincrement()) name String readNotifications UserReadNotification[] } model Notification { id Int @id @default(autoincrement()) title String text String alreadyRead UserReadNotification[] } model UserReadNotification { id Int @id @default(autoincrement()) userId Int notificationId Int user User @relation(fields: [userId], references: [id]) notification UserNotification @relation(fields: [notificationId], references: [id]) }
const prisma = new PrismaClient(); const userId = 1 const unreadData = await prisma.Notification.findMany({ where: { alreadyRead: { none: { // noneを指定 userId }, }, }, });
noneはprismaの1:多の「多」からデータをフィルタリングするためのクエリ。 これをつけることで、指定したリレーション(ここではalreadyRead)の全てのデータの指定したカラム(ここではuserId)に指定したデータ(ここではuserId)が存在しなければそのデータを返す。ここではfindManyを使っているので条件を満たすデータを全て返す。 これで、「既読していない全てのお知らせ」言い換えると「UserReadNotificationのuserIdに指定したuserIdが存在しない全てのNotification」を取り出すことができる。
prismaのクエリ便利だな〜と思う。他にも「多」からデータをフィルタリングするためのクエリはある。
シンプルにするために実際に作ったコードを変更しているので、間違ったとこあったらごめんなさい。