🦔
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