2

也许我还没有掌握 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 和更新的布尔值并更改该单个值,或者我是否需要逐字传递整个对象及其所有子对象,只更新一个顶级字段?

4

3 回答 3

4

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

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

X-Schema-Preview: partial-update-mutation

请注意,由于此 Schema Preview 功能添加了一个新的自动生成突变,因此您必须在执行 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 的变异将充当partialUpdateFQL 的更新函数。

于 2020-06-26T22:53:46.047 回答
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}
}

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

在此处输入图像描述

于 2020-06-26T21:48:02.070 回答
0

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

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

创建事件(数据:创建事件输入){ ... }

更新事件(数据:更新事件输入){ ... }

FaunaDB 为create*update*突变创建了相似的输入类型。但是您可以创建自己的输入类型,如 FaunaDB文档中所述

于 2020-06-27T09:05:50.450 回答