在 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】:通常,我会创建两种不同的输入类型。在您的情况下,它将是 createEventInput
和 updateEventInput
。
在createEventInput
中,所有或大多数字段都是必填的,而在updateEventInput
中,您可以有更多可选字段。但是您需要小心,不要最终使用空值更新您的记录,这些字段实际上对于您的内部业务逻辑来说是必需的。
createEvent(data: createEventInput) ...
updateEvent(data: updateEventInput) ...
FaunaDB 为 create*
和 update*
突变创建相似的输入类型。但是您可以创建自己的输入类型,如 FaunaDB docs
【讨论】:
以上是关于在 FaunaDB 中更新记录时,如何在不传入每个字段和子对象的情况下更新一个字段?的主要内容,如果未能解决你的问题,请参考以下文章