
2025年6月24日
【Prisma】該当する文字を含むアイテムを取得する
export const searchPosts = async (search: string) => {
const searchWords = search.trim().toLowerCase().split(/\s+/);
return await prisma.post.findMany({
where: {
AND: searchWords.map(word => ({
OR: [
{
title: {
contains: word,
},
},
{
content: {
contains: word,
},
},
],
})),
},
});
};
この場合のAND
とOR
は、仮に2単語(searchWords
は長さ2の配列)だとして、title
かcontent
のどちらか(OR
)で、map()
でループされる単語1つ1つを(AND
)含んでいなければならないという条件を表してます。
つまり、「毎ループ時、title
かcontent
どちらかでその文字を含んでね。」というニュアンスでしょう。
では以下の場合はどうなるのか。
export const searchPosts = async (search: string) => {
const searchWords = search.trim().toLowerCase().split(/\s+/);
return await prisma.post.findMany({
where: {
OR: searchWords.map(word => ({
OR: [
{
title: {
contains: word,
},
},
{
content: {
contains: word,
},
},
],
})),
},
});
};
これは毎ループ時という条件がなくなり、少なくとも1回、title
かcontent
で文字を含んでればいいよといった少し緩い条件になります。
具体例で見てみよう
例えば「React, 初心者」が検索ワードだとします。配列にすると、["React", "初心者"]
。
また、仮データも用意します。
// データ例
const posts = [
{ id: 1, title: "React入門", content: "初心者向けTypeScript解説" },
{ id: 2, title: "Vue.js入門", content: "Reactより簡単でおすすめ" },
{ id: 3, title: "TypeScript基礎", content: "型安全なJavaScript" },
{ id: 4, title: "React初心者ガイド", content: "基本的な使い方を解説" },
];
// 検索ワードの配列
const searchWords = ["React", "初心者"];
パターン1: AND検索の場合
一番最初に述べたパターンの場合です。
prisma.post.findMany({
where: {
AND: searchWords.map(word => ({
OR: [
{
title: {
contains: word,
},
},
{
content: {
contains: word,
},
},
],
})),
},
});
この場合where句で該当するものは、
「毎ループ時、title
かcontent
どちらかでその文字を含んでね」という条件より、
"React"
を、title
またはcontent
に含む"初心者"
を、title
またはcontent
に含む
この両方を満たしているものということになります。
仮データの中でこの条件を満たしているのは以下になります。
{ id: 1, title: "React入門", content: "初心者向けTypeScript解説" },
{ id: 4, title: "React初心者ガイド", content: "基本的な使い方を解説" }
パターン2: OR検索の場合
2番目に述べたパターンの場合です。
prisma.post.findMany({
where: {
OR: searchWords.map(word => ({
OR: [
{
title: {
contains: word,
},
},
{
content: {
contains: word,
},
},
],
})),
},
});
この場合where句で該当するものは、
「少なくとも1回、title
かcontent
どちらかでその文字を含んでね」という条件より、
"React"
を、title
またはcontent
に含む"初心者"
を、title
またはcontent
に含む
これらのどちらかを満たしているものになります。
仮データの中でこの条件を満たしているものは、以下になります。
{ id: 1, title: "React入門", content: "初心者向けTypeScript解説" },
{ id: 2, title: "Vue.js入門", content: "Reactより簡単でおすすめ" },
{ id: 4, title: "React初心者ガイド", content: "基本的な使い方を解説" }
タグ
コメント
シェア: