Fix a query

is there something wrong with this query, it isn't working?
await prisma.collection.findFirst({
where: {
id: collectionId,
},
include: {
posts: {
take: consts.ITEMS_PER_PAGE,
skip: (currentPage - 1) * consts.ITEMS_PER_PAGE,
include: {
collection: true,
},
where: {
AND: [
...(surah
? [
{
extraData: {
path: ['surah'],
equals: surah,
},
},
]
: []),
...(verse
? [
{
extraData: {
path: ['verse'],
equals: verse,
},
},
]
: []),
],
},
},
},
})
await prisma.collection.findFirst({
where: {
id: collectionId,
},
include: {
posts: {
take: consts.ITEMS_PER_PAGE,
skip: (currentPage - 1) * consts.ITEMS_PER_PAGE,
include: {
collection: true,
},
where: {
AND: [
...(surah
? [
{
extraData: {
path: ['surah'],
equals: surah,
},
},
]
: []),
...(verse
? [
{
extraData: {
path: ['verse'],
equals: verse,
},
},
]
: []),
],
},
},
},
})
10 Replies
Anas Badran
Anas BadranOP2w ago
the conditioinal verse isn't working. surah conditional works
Nurul
Nurul2w ago
Hey @Anas Badran If you just add the verse condition and not the surah condition, does the verse condition work? Can you enable logging to get the underlying raw SQL query and check if it looks as expected? https://www.prisma.io/docs/orm/prisma-client/observability-and-logging/logging
Logging | Prisma Documentation
Learn how to configure Prisma Client to log the raw SQL queries it sends to the database and other information.
Anas Badran
Anas BadranOP7d ago
No, it doesn't I'm about to change the schema the schema:
model Post {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
title String
title_ Json? @db.JsonB
content String
content_ Json? @db.JsonB
collectionId String
collection Collection @relation(fields: [collectionId], references: [id], onDelete: Cascade)
metadata PostMetadata? @relation(name: "PostMetadata")
// extraData Json? @db.JsonB
extraData PostExtraData[]
extension PostExtensionEnum @default(BASE)
tags Tag[] @relation(name: "PostTags")
order Int?
deletedAt DateTime?
}

model PostExtraData {
id String @id @default(cuid())
key String
value String
postId String
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
}
model Post {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
title String
title_ Json? @db.JsonB
content String
content_ Json? @db.JsonB
collectionId String
collection Collection @relation(fields: [collectionId], references: [id], onDelete: Cascade)
metadata PostMetadata? @relation(name: "PostMetadata")
// extraData Json? @db.JsonB
extraData PostExtraData[]
extension PostExtensionEnum @default(BASE)
tags Tag[] @relation(name: "PostTags")
order Int?
deletedAt DateTime?
}

model PostExtraData {
id String @id @default(cuid())
key String
value String
postId String
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
}
The updated query:
await prisma.collection.findFirst({
where: {
id: collectionId,
},
include: {
posts: {
take: consts.ITEMS_PER_PAGE,
skip: (currentPage - 1) * consts.ITEMS_PER_PAGE,
include: {
collection: true,
extraData: true,
},
where: {
extraData: {
some: {
...(verse && surah
? {
AND: [
{
AND: [
{
key: {
equals: 'verse',
},
value: {
equals: verse,
},
},
],
},

{
AND: [
{
key: {
equals: 'surah',
},
value: {
equals: surah,
},
},
],
},
],
}
: surah
? { key: 'surah', value: surah }
: verse
? { key: 'verse', value: verse }
: {}),
},
},
},
},
},
})
await prisma.collection.findFirst({
where: {
id: collectionId,
},
include: {
posts: {
take: consts.ITEMS_PER_PAGE,
skip: (currentPage - 1) * consts.ITEMS_PER_PAGE,
include: {
collection: true,
extraData: true,
},
where: {
extraData: {
some: {
...(verse && surah
? {
AND: [
{
AND: [
{
key: {
equals: 'verse',
},
value: {
equals: verse,
},
},
],
},

{
AND: [
{
key: {
equals: 'surah',
},
value: {
equals: surah,
},
},
],
},
],
}
: surah
? { key: 'surah', value: surah }
: verse
? { key: 'verse', value: verse }
: {}),
},
},
},
},
},
})
it works for surah alone, or verse alone, but not both together.
Nurul
Nurul7d ago
Do you mind elaborating your usecase on what you are trying to achieve? Based on the query, it looks like you could either receive surah or verse or both of them together, right? And based on what parameters you receive, you want to apply the filter?
Anas Badran
Anas BadranOP7d ago
Yes, you are right I'm using nextjs, and apply the filters based on what I recieve in searchParams I tried this also and it didn't work:
await prisma.collection.findFirst({
where: {
id: collectionId,
},
include: {
posts: {
take: consts.ITEMS_PER_PAGE,
skip: (currentPage - 1) * consts.ITEMS_PER_PAGE,
include: {
collection: true,
extraData: true,
},
where: {
extraData: {
some: {
...(verse && surah
? {
AND: [
{ key: { equals: 'verse' }, value: { equals: verse } },
{ key: { equals: 'surah' }, value: { equals: surah } },
],
}
: surah
? { key: 'surah', value: surah }
: verse
? { key: 'verse', value: verse }
: {}),
},
},
},
},
},
})
await prisma.collection.findFirst({
where: {
id: collectionId,
},
include: {
posts: {
take: consts.ITEMS_PER_PAGE,
skip: (currentPage - 1) * consts.ITEMS_PER_PAGE,
include: {
collection: true,
extraData: true,
},
where: {
extraData: {
some: {
...(verse && surah
? {
AND: [
{ key: { equals: 'verse' }, value: { equals: verse } },
{ key: { equals: 'surah' }, value: { equals: surah } },
],
}
: surah
? { key: 'surah', value: surah }
: verse
? { key: 'verse', value: verse }
: {}),
},
},
},
},
},
})
Nurul
Nurul7d ago
Would something like this work then?
let result;

if (verse && surah) {
// Condition 1: Both verse and surah are provided
result = await prisma.collection.findFirst({
where: { id: collectionId },
include: {
posts: {
take: consts.ITEMS_PER_PAGE,
skip: (currentPage - 1) * consts.ITEMS_PER_PAGE,
include: { collection: true, extraData: true },
where: {
extraData: {
some: {
AND: [
{ key: 'verse', value: verse },
{ key: 'surah', value: surah }
]
}
}
}
}
}
});
} else if (surah) {
// Condition 2: Only surah is provided
result = await prisma.collection.findFirst({
where: { id: collectionId },
include: {
posts: {
take: consts.ITEMS_PER_PAGE,
skip: (currentPage - 1) * consts.ITEMS_PER_PAGE,
include: { collection: true, extraData: true },
where: {
extraData: {
some: { key: 'surah', value: surah }
}
}
}
}
});
} else if (verse) {
// Condition 3: Only verse is provided
result = await prisma.collection.findFirst({
where: { id: collectionId },
include: {
posts: {
take: consts.ITEMS_PER_PAGE,
skip: (currentPage - 1) * consts.ITEMS_PER_PAGE,
include: { collection: true, extraData: true },
where: {
extraData: {
some: { key: 'verse', value: verse }
}
}
}
}
});
}
let result;

if (verse && surah) {
// Condition 1: Both verse and surah are provided
result = await prisma.collection.findFirst({
where: { id: collectionId },
include: {
posts: {
take: consts.ITEMS_PER_PAGE,
skip: (currentPage - 1) * consts.ITEMS_PER_PAGE,
include: { collection: true, extraData: true },
where: {
extraData: {
some: {
AND: [
{ key: 'verse', value: verse },
{ key: 'surah', value: surah }
]
}
}
}
}
}
});
} else if (surah) {
// Condition 2: Only surah is provided
result = await prisma.collection.findFirst({
where: { id: collectionId },
include: {
posts: {
take: consts.ITEMS_PER_PAGE,
skip: (currentPage - 1) * consts.ITEMS_PER_PAGE,
include: { collection: true, extraData: true },
where: {
extraData: {
some: { key: 'surah', value: surah }
}
}
}
}
});
} else if (verse) {
// Condition 3: Only verse is provided
result = await prisma.collection.findFirst({
where: { id: collectionId },
include: {
posts: {
take: consts.ITEMS_PER_PAGE,
skip: (currentPage - 1) * consts.ITEMS_PER_PAGE,
include: { collection: true, extraData: true },
where: {
extraData: {
some: { key: 'verse', value: verse }
}
}
}
}
});
}
else {
// No filters provided, fetch all posts
result = await prisma.collection.findFirst({
where: { id: collectionId },
include: {
posts: {
take: consts.ITEMS_PER_PAGE,
skip: (currentPage - 1) * consts.ITEMS_PER_PAGE,
include: { collection: true, extraData: true }
}
}
});
}
else {
// No filters provided, fetch all posts
result = await prisma.collection.findFirst({
where: { id: collectionId },
include: {
posts: {
take: consts.ITEMS_PER_PAGE,
skip: (currentPage - 1) * consts.ITEMS_PER_PAGE,
include: { collection: true, extraData: true }
}
}
});
}
This is a bit verbose, but makes it easy to understand and debug
Anas Badran
Anas BadranOP7d ago
it didn't work
Nurul
Nurul7d ago
Which conditions didn't work as expected?
Anas Badran
Anas BadranOP6d ago
Verse and surah together Surah or verse alone works fine FOR SIMPLIFIYNG The code below works, when commenting either part of AND, but when putting them together doesn't work
const result = await prisma.post.findMany({
where: {
extension: 'SURAH_WITH_VERSE',

extraData: {
some: {
AND: [
{
key: 'surah',
value: '2',
},
// {
// key: 'verse',
// value: '283',
// },
],
},
},
},
select: {
title: true,
extraData: true,
},
});
const result = await prisma.post.findMany({
where: {
extension: 'SURAH_WITH_VERSE',

extraData: {
some: {
AND: [
{
key: 'surah',
value: '2',
},
// {
// key: 'verse',
// value: '283',
// },
],
},
},
},
select: {
title: true,
extraData: true,
},
});
Nurul
Nurul2d ago
Hmm, do you get the same issue if you use every?
Want results from more Discord servers?
Add your server