🦔
Prismaで多対多の検索
昔理解できてなかった時にちょっとハマったのでメモ。
よくある構成です。
Article
id | title | content |
---|---|---|
1 | タイトル1 | ... |
2 | タイトル2 | ... |
3 | タイトル3 | ... |
4 | タイトル4 | ... |
Category
id | name |
---|---|
1 | カテゴリ1 |
2 | カテゴリ2 |
3 | カテゴリ3 |
ArticleOnCategory
articleId | categoryId |
---|---|
1 | 1 |
1 | 2 |
1 | 3 |
2 | 1 |
3 | 3 |
4 | 1 |
4 | 2 |
カテゴリ1とカテゴリ2の両方に属する記事の抽出
ダメな例
await prisma.article.findMany({
where: {
ArticleOnCategory: {
every: {
categoryId: {
in: [1, 2]
}
}
}
}
})
正しい方法
await prisma.article.findMany({
where: {
AND: [
{ArticleOnCategory: {some: {categoryId: 1}}},
{ArticleOnCategory: {some: {categoryId: 2}}}
]
}
})
配列から組み立てる
const categoryIds = [1, 2]
await prisma.article.findMany({
where: {
AND: categoryIds.map(categoryId => {
return {ArticleOnCategory: {some: {categoryId}}}
})
}
})
カテゴリ1とカテゴリ2のいずれかに属する記事の抽出
ORの場合はどっちでもOK。
await prisma.article.findMany({
where: {
ArticleOnCategory: {
some: {
categoryId: {
in: [1, 2]
}
}
}
}
})
await prisma.article.findMany({
where: {
OR: [
{ArticleOnCategory: {some: {categoryId: 1}}},
{ArticleOnCategory: {some: {categoryId: 2}}}
]
}
})
Discussion