keystone icon indicating copy to clipboard operation
keystone copied to clipboard

Add select and include to findOne and findMany

Open MurzNN opened this issue 2 years ago • 12 comments

Now findOne and findMany functions in DB API misses ability to select specific fields only, and include relationship fields too.

It is my try to add this missing functionality.

Prisma allows query specific fields, here is the documentation https://www.prisma.io/docs/concepts/components/prisma-client/select-fields#select-specific-fields

So seems we simply can pass those variables from Keystone API to Prisma API.

Here is usage example of this feature directly in Prisma, based on examples/blog:

    async onConnect(context) {
      const result = await context.prisma.author.findMany({
        take: 2,
        select: {
          name: true,
          posts: {
            select: {
              id: true,
            },
          },
        },
      });
      console.log(result[0]);

And here is desired behavior in Keystone DB API:

      const result = await context.db.Author.findMany({
        take: 2,
        select: {
          name: true,
          posts: {
            select: {
              id: true,
            },
          },
        },
      });
      const result2 = await context.db.Author.findMany({
        take: 2,
        include: {
          posts: true,
        },
      });

Resolves https://github.com/keystonejs/keystone/issues/7198

MurzNN avatar Jan 19 '22 08:01 MurzNN

🦋 Changeset detected

Latest commit: f92018999641b1af94c1891cee78bce36f1ffab6

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 15 packages
Name Type
@keystone-6/core Minor
@keystone-6/auth Major
@keystone-6/cloudinary Major
@keystone-6/fields-document Major
@keystone-6/session-store-redis Major
@keystone-6/example-auth Patch
@keystone-6/examples-app-basic Patch
@keystone-6/example-ecommerce Patch
@keystone-6/example-graphql-api-endpoint Patch
@keystone-6/example-roles Patch
@keystone-6/example-sandbox Patch
@keystone-6/example-testing Patch
@keystone-6/example-with-auth Patch
@keystone-6/website Patch
@keystone-6/example-document-field Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

changeset-bot[bot] avatar Jan 19 '22 08:01 changeset-bot[bot]

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/keystonejs/keystone-next-docs/Dw9hkkQjRzoVGwFbYr5P2SPfsr2q
✅ Preview: https://keystone-next-docs-git-fork-murznn-db-api-fin-5f95c5-keystonejs.vercel.app

vercel[bot] avatar Jan 19 '22 08:01 vercel[bot]

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

codesandbox-ci[bot] avatar Jan 19 '22 08:01 codesandbox-ci[bot]

Problems now only are:

  1. Keystone's Prisma somehow misses the Prisma type, so this line:
import { Prisma } from '@prisma/client';

produces a TS error because of missing types. But if I add @prisma/client in separate project, those types are exist.

  1. Those new arguments are stripped in some parent functions, so in actual functions we are receiving object without select and include keys.

MurzNN avatar Jan 19 '22 08:01 MurzNN

This would be a great feature for some more heavy processing in some custom mutations for example.

fkrauthan avatar Oct 28 '22 22:10 fkrauthan

@emmatown if this was only on find* functions, wouldn't we be able to ignore hooks, and only the return type from the call itself would need to be adjusted?

dcousens avatar Oct 29 '22 06:10 dcousens

I think we can add this functionality with the caveat that no read hooks could exist for the underlying item or fields...

Alternatively, we can change the type of item passed into read hooks to be Partial<typeof item>, to indicate that hooks could receive any subset of item fields.

Alternatively, maybe this is an opt-in behaviour, with something like db.selectable: true which will change the types of item to Partial<typeof item>, that way it's non-breaking, but additionally not painful in the typical scenario? :thinking:

dcousens avatar Sep 26 '23 23:09 dcousens