【问题标题】:findFirst query shows irrelevant data in prisma 2findFirst 查询在 prisma 2 中显示不相关的数据
【发布时间】:2021-10-17 21:57:36
【问题描述】:

我想用 id、slug、用户名、userId 参数查询帖子。查询中至少存在一个参数值。不需要全部。

const post = await prisma.post.findFirst({
    where: {
      OR: [
        {
          AND: [
            { published: true },
            {
              OR: [
                { id },
                {
                  AND: [
                    { slug },
                    {
                      author: {
                        profile: {
                          username
                        }
                      }
                    }
                  ]
                }
              ]
            }
          ]
        },
        {
          authorId: userId || undefined
        }
      ]
    },
    ...select
  })

数据库数据(帖子):

[{id: 1, published: false}, {id: 2, published: true}]

查询参数为id: 1,但输出为:

{id: 2, published: true}

我的查询有什么问题吗?

Prisma 模型:

model Post {
  id           String     @id @default(cuid())
  title        String
  body         String
  slug         String
  published    Boolean
  draft        Boolean    @default(false)
  author       User       @relation(fields: [authorId], references: [id])
  authorId     String
}

用户模型:

model User {
  id            String         @id @default(cuid())
  name          String
  email         String         @unique
  password      String?
  posts         Post[]
  profile       Profile?
}

简介型号:

model Profile {
  id                 String         @id @default(cuid())
  bio                String?
  author             User?          @relation(fields: [authorId], references: [id])
  authorId           String?
  phone              String?
  username           String?
}

【问题讨论】:

  • 您能否更清楚地阐明您的要求,因为它有点模棱两可?您是说: 1. 在运行查询期间至少提供了 id、slug、username、userId 变量之一(其余变量未定义/为空)? 2. id、slug、username、userId 变量在查询过程中都是可用的,但只有其中一个需要与数据库中的条目匹配?在 2 的情况下,返回值是有意义的,因为 id 可能不匹配,但另一个字段可能已经匹配。
  • const { id, slug, username, userId } = params; 1. 运行查询时至少提供id、slug、username、userId变量之一(其余变量未定义/为空)。

标签: prisma prisma2


【解决方案1】:

将查询过滤器嵌套在 OR 子句中。

const { id, slug, username, userId  } = params;

const posts = await prisma.post.findFirst({
  where: {
    OR: [
        { id },
        { slug },
        { author: { profile: { username } } },
        { authorId: userId }
    ]
  }
});

【讨论】:

  • 不,如上所述显示错误数据
【解决方案2】:

问题

根据您在 cmets 中提供的说明,您希望:

使用id, slug, username, userId 查询帖子,其中一个或多个对于单个查询可能为空或未定义。如果某个字段为空/未定义,则该字段应在特定查询中被忽略。

解决方案

在我讨论解决方案之前,您需要知道nullundefined 在 Prisma 中具有特殊含义。

  • null 是一个值
  • undefined 表示什么都不做

所以基本上,如果您为任何字段提供 undefined,它实际上会被忽略。 More info about this here

了解此信息后,您需要将参数参数中的 null 值转换为 undefined,因为您只想忽略该特定查询中的字段。您可以按如下方式设置查询:



async function foo(params) {
    const { id, slug, username, userId } = params;

    const post = await prisma.post.findFirst({
        where: {
            id: id ? id : undefined,
            slug: slug ? slug : undefined,
            authorId: userId ? userId : undefined,
            author: username
                ? {
                      profile: {
                          username: username,
                      },
                  }
                : undefined,
        },
    });

}

【讨论】:

  • 感谢您的努力,但这对我没有任何帮助。我认为id: id || undefinedid: id ? id : undefined 更好,我的查询期望是:如果提供userId,则只匹配authorId: userId || undefined 如果提供usernameslug 两者或只提供id,除了userId 然后匹配@987654338 @ & slug 两者或仅id & published: true 两种情况
  • 如果您有一个非常复杂的条件集,最好单独拆分查询。例如,为您提供的每个条件创建一个单独的查询,并根据可用的变量运行适当的查询。在应用程序代码中对复杂条件进行建模通常比在 ORM 中更容易。我相信您也可以在 Prisma 中提出正确的 OR 和 AND 组合,但可能很难阅读/维护。
猜你喜欢
  • 2019-03-17
  • 2021-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
  • 2019-07-20
相关资源
最近更新 更多