微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在graphql中按时间过滤使用floralDB服务 ..使用解析器 .. UDF实施

如何解决在graphql中按时间过滤使用floralDB服务 ..使用解析器 .. UDF实施

我的graphQL模式如下:

type Todo {
  name: String!
  created_at: Time
}

type Query {
  allTodos: [Todo!]!
  todosByCreatedAtFlag(created_at: Time!): [Todo!]!
}

查询有效。

query {  
  todosByCreatedAtFlag(created_at: "2017-02-08T16:10:33Z") {
    data {
      _id
      name
      created_at
    }
  }
}

谁能指出我如何在graphql中创建大于(或小于)时间查询(使用动物群数据库)。

解决方法

不支持GraphQL范围查询(但是..它们来了!)

FaunaDB不提供现成的 GraphQL 的范围查询,我们正在研究这些功能。

..但有一种解决方法。

这并不意味着它不能进行范围查询,因为 FQL 支持范围查询,并且您始终可以通过从GraphQL到FQL的“转义”来编写更高级的查询用户定义函数(UDF)。

..使用解析器

通过在模式中使用@resolver关键字,您可以通过在FQL的FaunaDB中编写用户定义函数来自己实现GraphQL查询。 bt文档中有一些基本示例,我想您可能需要帮助,所以我为您编写一个简单示例。

我添加了您的架构并添加了两个文档: enter image description here

第一件事是我们的架构将使用解析器进行扩展:

type Todo {
  name: String!
  created_at: Time
}

type Query {
  allTodos: [Todo!]!
  todosByCreatedAtFlag(created_at: Time!): [Todo!]!
  todosByCreatedRange(before: Time,after:Time): [Todo!]! @resolver
}

这一切都是为我们添加一个实现的功能: enter image description here

如果我们通过GraphQL进行调用,则会准确地给出我们之前在屏幕快照中看到的Abort消息,因为该消息尚未实现。但是我们可以看到GraphQL语句实际上调用了该函数。

enter image description here

.. UDF实施

我们要做的第一件事是添加只是写一个名字作为lambda的第一个参数的参数: enter image description here

如果您需要传递多个参数(在我在架构中定义的解析器中执行此操作),这还会采用一个数组: enter image description here

我们将添加索引以支持我们的查询。值用于范围(以及返回值和排序)。我们将添加created_at以覆盖其范围,并添加 ref ,因为我们需要返回值才能将实际文档置于索引之后。 enter image description here

然后我们可以通过编写一个简单的函数(尚不可用)开始

Query(
      Lambda(
        ["before","after"],Paginate(
          Range(Match(Index("todosByCreatedAtRange")),Var("before"),Var("after"))
        )
      )
    )

并可以通过外壳手动调用该函数进行测试。

enter image description here

这确实返回了两个对象(范围包括在内)。 当然,这有一个问题,它不会返回GraphQL期望的结构中的数据,因此我们将得到以下奇怪的错误: enter image description here

我们现在可以做两件事,要么在Schema中定义一个适合这些类型的类型,和/或我们可以调整返回数据。我们将进行后者,并使我们的结果适应预期的[Todo!]!结果显示给你。

第一步,映射结果。我们在这里介绍的唯一一件事就是地图和Lambda。我们还没有做任何特别的事情,我们只是返回引用而不是ts和引用作为示例。

Query(
  Lambda(
    ["before",Map(
      Paginate(
        Range(
          Match(Index("todosByCreatedAtRange")),Var("after")
        )
      ),Lambda(["created_at","ref"],Var("ref"))
    )
  )
)

调用它确实表明该函数现在仅返回引用。 enter image description here

让我们获取实际文件。我知道FQL是冗长的(并且有充分的理由,尽管将来它会变得不太冗长),所以我开始添加评论以澄清问题

Query(
  Lambda(
    ["before",Map(
      // This is just the query to get your range
      Paginate(
        Range(
          Match(Index("todosByCreatedAtRange")),// This is a function that will be executed on each result (with the help of Map)
      Lambda(["created_at",// We'll use Let to structure our queries ( allowing us to use varaibles )
        Let({ 
          todo: Get(Var("ref")) 
        },// And then we return something
        Var("todo")))
    )
  )
)

我们的函数现在返回数据。。 enter image description here

我们仍然需要确保该数据符合GraphQL的期望,并且从模式中我们可以看到它期望的是[Todo!]! (请参阅“文档”标签)和待办事项外观(请参见“架构”标签):

type Todo {
  _id: ID!
  _ts: Long!
  name: String!
  created_at: Time
}

您还可以从docs选项卡中看到,“ non-resolver”查询会自动更改为返回TodoPages。到目前为止,我们编写的函数实际上返回页面。分页结果是如下所示的结果: {数据:[document1,document2,..], 之前:... 之后:.. }

结果不接受页面,而是一个数组,所以我将其更改并检索数据字段:

enter image description here

我们得到了结果。 enter image description here

完整的查询如下:

Query(
  Lambda(
    ["before",Select(
      ["data"],Map(
        Paginate(
          Range(
            Match(Index("todosByCreatedAtRange")),Var("after")
          )
        ),Lambda(
          ["created_at",Let({ todo: Get(Var("ref")) },Var("todo"))
        )
      )
    )
  )
)

免责声明

自定义后,分页也将成为您的责任(例如,传递额外的参数)。您不能再像通常那样仅在GraphQL主体中请求关系了,便不再需要立即获取关系。

关于UDF和GraphQL / FQL混合的好处的一些话

在您回避FQL(是的,我们确实必须添加范围查询并进行此工作)之前,这里是对UDF方法的一些解释,以及为什么无论如何都要考虑一下。

您有时会在GraphQL中遇到不可能的事情(复杂的条件事务,例如,仅当从前一次更新得出的某些结果为真时才更新文档并更新另一个文档)。使用其他GraphQL实现的用户通常通过编写无服务器功能来解决此问题,以防您必须实现高级逻辑或事务。

FaunaDB对此的答案是使用其用户定义函数(UDF)。这不是一个无服务器功能,它是FQL中实现的FaunaDB函数,乍一看似乎很麻烦,但重要的是要意识到它可以为您带来相同的好处(多区域/强一致性,可伸缩性/自由层/按需付费你去)FaunaDB提供的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。