prismagql

Prisma how to get data from relation as using 'where'?


my User prisma schema User model has like[]:

model User {
  likes Like[]
}

and Like model has createdAt.

model Like {
  id Int @id @default(autoincrement())
  user User @relation(fields: [userId], references: [id], onDelete: Cascade)
  userId Int
  createdAt DateTime @default(now())

  @@unique([feedId, userId])
}

I want to get data how many times user links to Like model in this month. So I get data like below.

export default {
  Query: {
    seeAllLikeOrder: protectedResolver(() => {
      const startOfMonth = new Date(
        moment().startOf("month").format("YYYY-MM-DD hh:mm").substring(0, 10)
      );
      const endOfMonth = new Date(
        moment().endOf("month").format("YYYY-MM-DD hh:mm").substring(0, 10)
      );
      return client.user.findMany({
        where: {
          likes: {
            createdAt: {
              gte: startOfMonth,
              lt: endOfMonth,
            },
          },
        },
        orderBy: {
          likes: {
            _count: "desc",
          },
        },
        take: 10,
      });
    }),
  },
};

But error comes:

enter image description here

I think I can't use according to error message.

where: {
          likes: {
            createdAt: {
              gte: startOfMonth,
              lt: endOfMonth,
            },
          },
        },

But i don't understand why.

Because User has Like model and Like has createdAt field.

in this case, how to get data that I want?


Solution

  • The error is pretty descriptive as to what's going on: createdAt is not a valid property of LikeListRelationFilter, and that type only has the properties every, some, or none.

    Your issue is the nested select when querying the likes field:

    return client.user.findMany({
      where: {
        likes: { // This line
          createdAt: {
            gte: startOfMonth,
            lt: endOfMonth,
          },
        },
      },
      orderBy: {
        likes: {
          _count: "desc",
        },
      },
      take: 10,
    });
    

    In Prisma, when you are querying a field and filtering based on the value of a nested field, the API for querying that nested array field will be different than if you were querying prisma.like.findMany. In your situation, your query must look something like this:

    return client.user.findMany({
      where: {
        likes: { // This line is different
          // Find any user where at least one of their likes abides by this condition.
          // Replace with "every" to only search for users where ALL of their likes abide by this condition,
          // or "none" to only search for users where NONE of their likes abide by this condition.
          some: { 
            createdAt: {
              gte: startOfMonth,
              lt: endOfMonth,
            },
          }
        },
      },
      orderBy: {
        likes: {
          _count: "desc",
        },
      },
      take: 10,
    });
    

    Documentation: https://www.prisma.io/docs/concepts/components/prisma-client/filtering-and-sorting

    If the nested field was a single item (not an array of items), you would use is or isNot instead. Here you have an array, so you have to use every, some, or none.