Prismaとは
Prismaとは型安全なデータアクセスを提供するTypeScriptベースのORMです。
https://www.prisma.io/
やりたかったこと
以下のER図ようなテーブル構成があり、「タグAが紐づいている」、または 「全く紐づけがない」 アイテムを抽出する必要がありました。
「タグID Aが紐づいている」 という条件はsomeを使用することで実現できます。
where: {
{
tagsOnItems: {
some: {
tagId: 'A'
}
}
},
}
しかし 「全く紐づけがない」 という条件が問題でした。
Prismaはオブジェクト型での条件式にexists句やsumの結果による判定を組み込むことができません。以下のようなリレーションにnullを指定する書式にも対応していません。
where: {
{
tagsOnItems: null
},
}
解決策
Prismaにはネガティブなリレーション判定プロパティはnoneしか用意されていないので、noneを使用して以下のように 「紐づけ対象が存在しない」 という条件を構築しました。
where: {
tagsOnItems: {
none: {
itemId: {
not: ''
}
}
}
}
Prismaでは条件の中にカレントアイテムのitemIdを明示的に指定することはできないので、itemIdで紐づいたtagsOnItemsに対してitemId: {not: ''}
(*)とすることで、 「カレントアイテムのitemIdが設定されているレコード」 を絞り込むことができます。
その絞り込まれたレコードに対してnoneを指定することで 「カレントのアイテムIDを持つレコードが存在しない」=「紐づけ対象が存在しない」 という条件を実現しました。
※ itemIdはNOT NULLなので型制約によってitemId: {not: null}という条件が使用できません。そのため空文字を指定しています。
完成形
前述の各条件をORで内包することによって、「タグID Aが紐づいている」、または 「全く紐づけがない」 アイテムを抽出することができました。
where: {
OR: [
{
tagsOnItems: {
some: {
itemId: 'A'
}
}
},
{
tagsOnItems: {
none: {
itemId: {
not: ''
}
}
}
}
]
}