在 FaunaDB 中更新记录时,如何在不传入每个字段和子对象的情况下更新一个字段?

Posted

技术标签:

【中文标题】在 FaunaDB 中更新记录时,如何在不传入每个字段和子对象的情况下更新一个字段?【英文标题】:When updating a record in FaunaDB, how do I update one field without passing in every field and subobject? 【发布时间】:2020-10-17 12:23:07 【问题描述】:

也许我还没有掌握 GraphQL,但我想更新数据库中的复杂记录。我很难找到解释这一点的文档,它没有使用一个简单的例子。我正在使用 FaunaDB 并尝试在 GraphQL 操场上进行测试,然后在 JS 中实现它。

这是我的架构示例:

type Event 
    name: String!
    email: String!
    eventName: String!
    location: String
    guests: [Guest!]!
    note: String!
    confirmed: Boolean!
    completed: Boolean!
    dateTimeStart: Time
    dateTimeEnd: Time
    sentConfirmation: Boolean!


type Guest @embedded 
    email: String!
    rsvp: Boolean
    results: SurveyAnswers


type SurveyAnswers @embedded 
    ~ 12 various fields

我想更新事件的一个字段:sentConfirmation,就是这样。

我知道事件 ID 以及我想将布尔值更新为什么。

有没有办法编写一个突变来传递一个 ID 和更新的布尔值并更改该单个值,或者我是否需要逐字传递整个对象及其所有子对象一个***字段更新了吗?

【问题讨论】:

你试过了吗? GraphQL 规范正是您所说的:您只需要传入值已更改的键和字段。如果您尝试过但没有成功,也许您可​​以发布有关您遇到的任何错误的更多详细信息。 【参考方案1】:

这应该可以通过调用自动生成的partialUpdate 突变来实现。您可能没有注意到它,因为它目前仅作为 Schema Preview 功能提供。

这实质上意味着为了启用它,您需要将以下标头添加到您的 HTTP 请求中:

X-Schema-Preview: partial-update-mutation

请注意,由于此 Schema Preview 功能添加了一个新的 autogenerated 突变,因此您必须在执行 GraphQL 操作时添加此标头(即,针对/graphql 端点发送请求),而不是导入模式时(即,再次向/import 端点发送请求)。原因基本上是所有自动生成的查询和突变都是在运行时派生的,而不是在导入架构时派生的。

现在,如果您已经添加了上面提到的标头,当调用一些自省查询来读取模式时(例如 GraphQL Playground 所做的那样),您应该注意到有一个新的突变字段和一个新的输入对象:

input PartialUpdateEventInput 
  name: String
  email: String
  eventName: String
  location: String
  guests: [PartialUpdateGuestInput!]
  note: String
  confirmed: Boolean
  completed: Boolean
  dateTimeStart: Time
  dateTimeEnd: Time
  sentConfirmation: Boolean


type Mutation 
  partialUpdateEvent(id: ID!, data: PartialUpdateEventInput!): Event

由于这个新输入对象的所有字段都是可选的,您现在应该可以只更新 sentConfirmation 字段:

mutation PartialUpdate 
  partialUpdateEvent(id: "269434161519919634", data: 
    sentConfirmation: true
  ) 
    _id
  

所有未包含在突变中的字段将不受影响。

与 FQL 建立并行,这意味着 GraphQL 的 update 突变将充当 FQL 的 Replace 函数,而 GraphQL 的 partialUpdate 突变将充当 FQL 的 Update 函数。

【讨论】:

【参考方案2】:

我的第一反应也是:“你试过了吗?”但我立即认为你做到了。您的问题是由于您的所有属性都是强制性的(正如您在属性后面使用感叹号 (!) 标记所指定的那样)。因此,更新时也会检查这些字段。可以说,这可能是不必要的,我会问我的同事我们是否不想改变这一点。

在每种情况下,您都可以通过删除必填字段来“解决”您的问题。在这种情况下,您可以完美地做到:

# Write your query or mutation here
mutation test 
  createEvent(data: 
    name: "Test",
    email: "test@test.com",
    eventName: "lala"
    note: "I am a note",
    confirmed:true,
    completed:true,
    sentConfirmation: false
  )
  _id


接着是:

# Write your query or mutation here
mutation test 
  updateEvent(id: "269430330059915782", data:
    completed:false
  )
  _id

并且您文档的布尔“已完成”字段将被更新。

【讨论】:

我会问我的同事我们是否可能不想改变这一点” - 你可能想透露(如果)你是一个动物数据库的员工。 查看 Leo 的回复。我确实是 FaunaDB 开发倡导者,并联系了 Leo 以进一步帮助您,因为似乎确实有计划并且已经预见到了解决方案。 感谢@BrechtDeRooms 的回复!我仍在学习 GraphQL 和 NoSQL,但我认为设置必填字段只会影响创建而不影响更新,因为我认为我只更新了我需要的内容,因此混淆了为什么它一直要求填写更多字段试图运行更新查询。至少对我来说,当前的功能似乎不直观,因此这个问题被问到一些看起来应该只是简单地工作的东西,但看起来你正在通过预览修复它,顺便说一句,这对我有用!再次感谢!【参考方案3】:

通常,我会创建两种不同的输入类型。在您的情况下,它将是 createEventInputupdateEventInput

createEventInput 中,所有或大多数字段都是必填的,而在updateEventInput 中,您可以有更多可选字段。但是您需要小心,不要最终使用空值更新您的记录,这些字段实际上对于您的内部业务逻辑来说是必需的。

createEvent(data: createEventInput) ...

updateEvent(data: updateEventInput) ...

FaunaDB 为 create*update* 突变创建相似的输入类型。但是您可以创建自己的输入类型,如 FaunaDB docs

中所述

【讨论】:

以上是关于在 FaunaDB 中更新记录时,如何在不传入每个字段和子对象的情况下更新一个字段?的主要内容,如果未能解决你的问题,请参考以下文章

FaunaDB - 如何批量更新单个 graphQL 突变中的条目列表?

如何获取 FaunaDB 类中的所有实例

如何在 FaunaDB 中获取包含子字符串的文档

如何在 FaunaDB 中获取嵌套文档?

蜂巢:如何在不更新的情况下处理 scd 类型 2

如何在 GraphQL 突变中使用 FaunaDB 将数组传递给字段