【问题标题】:How to join two collections in Fauna DB如何在 Fauna DB 中加入两个集合
【发布时间】:2022-01-14 01:27:30
【问题描述】:

我是 FaunaDb FQL 的新手,我正在尝试通过索引从 2 个集合中查询数据,但我就是不明白。我从 FaunaDB GUI 创建了索引:

索引 #1(users_waitlist)(无条款):

  • data.waitlist_meta(这是对产品集合的引用)
  • data.first_name
  • data.last_name
  • data.email
  • data.mobile_number
  • 参考

索引 #2(产品)(无条款)

  • 数据名称
  • data.dateStart
  • data.dateEnd
  • 参考

在 users 集合中,当用户订阅产品的候补名单时,我们将 waitlist_meta 更改为产品 ref,因此,我创建了 users_waitlist 索引。

如果我这样查询:

Paginate(Match(Index('users_waitlist')))

它通过将 users_waitlist 索引中的所有文档提供给我来工作

但是我怎样才能从 users_waitlist 中引用的产品索引中检索文档呢?

我希望我的问题是有道理的,我真的提前谢谢你

【问题讨论】:

    标签: faunadb


    【解决方案1】:

    对于这个答案,我创建了一些与您概述的类似的示例数据:

    > CreateCollection({ name: "users" })
    {
      ref: Collection("users"),
      ts: 1642027810090000,
      history_days: 30,
      name: 'users'
    }
    
    > CreateCollection({ name: "products" })
    {
      ref: Collection("products"),
      ts: 1642027821280000,
      history_days: 30,
      name: 'products'
    }
    
    > Create(
      Collection("products"),
      {
        data: {
          name: "grapple grommets",
          dateStart: Now(),
          dateEnd: TimeAdd(Now(), 30, "days"),
        }
      }
    )
    {
      ref: Ref(Collection("products"), "320622240400933376"),
      ts: 1642028045960000,
      data: {
        name: 'grapple grommets',
        dateStart: Time("2022-01-12T22:54:05.933Z"),
        dateEnd: Time("2022-02-11T22:54:05.933Z")
      }
    }
    
    > Create(
      Collection("users"),
      {
        data: {
          first_name: "Test",
          last_name: "User",
          email: "test@test.test",
          mobile_number: "+1 (123) 456-7890",
          product: Ref(Collection("products"), "320622240400933376")
        }
      }
    )
    
    {
      ref: Index("users_waitlist"),
      ts: 1642029519070000,
      active: true,
      serialized: true,
      name: 'users_waitlist',
      source: Collection("users"),
      values: [
        { field: [ 'data', 'product' ] },
        { field: [ 'data', 'first_name' ] },
        { field: [ 'data', 'last_name' ] },
        { field: [ 'data', 'email' ] },
        { field: [ 'data', 'mobile_number' ] },
        { field: [ 'ref' ] }
      ],
      partitions: 8
    }
    {
      ref: Index("users_waitlist"),
      ts: 1642028625760000,
      active: true,
      serialized: true,
      name: 'users_waitlist',
      source: Collection("users"),
      values: [
        { field: [ 'data', 'product' ] },
        { field: [ 'data', 'first_name' ] },
        { field: [ 'data', 'last_name' ] },
        { field: [ 'data', 'email' ] },
        { field: [ 'data', 'mobile_number' ] },
     
      ],
      partitions: 8
    }
    

    有了这些,您的示例查询将按预期工作:

    > Paginate(Match(Index("users_waitlist")))
    {
      data: [
        [
          Ref(Collection("products"), "320622240400933376"),
          'Test',
          'User',
          'test@test.test',
          '+1 (123) 456-7890'
        ]
      ]
    }
    

    我们需要修改查询以检索关联的产品。这应该如何反映在结果中?由于可能会有多个用户,每个用户都有一个关联的产品,因此一种解决方案是返回一个包含关联产品文档的对象。

    为此,我们需要使用Map 遍历所有分页结果,然后使用Let 对产品文档执行Get 并为结果组合一个对象。像这样的:

    Map(
      Paginate(Match(Index("users_waitlist"))),
      Lambda(
        [ "product_ref", "first", "last", "email", "mobile", "ref" ],
        Let(
          {
            product: Get(Var("product_ref")),
          },
          {
            product: Var("product"),
            first_name: Var("first"),
            last_name: Var("last"),
            email: Var("email"),
            mobile_number: Var("mobile"),
            ref: Var("ref"),
          }
        )
      )
    )
    {
      data: [
        {
          product: {
            ref: Ref(Collection("products"), "320622240400933376"),
            ts: 1642028045960000,
            data: {
              name: 'grapple grommets',
              dateStart: Time("2022-01-12T22:54:05.933Z"),
              dateEnd: Time("2022-02-11T22:54:05.933Z")
            }
          },
          first_name: 'Test',
          last_name: 'User',
          email: 'test@test.test',
          mobile_number: '+1 (123) 456-7890',
          ref: Ref(Collection("users"), "320622637091914240")
        }
      ]
    }
    

    尽管 FQL 相当冗长和复杂,但它具有强大的功能,可以根据需要以任何方式组合结果。

    更新:如果文档没有引用集,盲目地尝试获取文档会导致错误。您可以通过首先检查存储引用的字段是否确实有引用以及该引用是否存在来防止出现这种情况。

    为此,请在查询中替换此行:

            product: Get(Var("product_ref")),
    

    与:

            product: If(
              IsRef(Var("product_ref")),
              If(
                Exists(Var("product_ref")),
                Get(Var("product_ref")),
                {}
              ),
              {},
            ),
    

    如果product不是引用,或者引用不存在,则返回值为空对象。

    【讨论】:

    • 如何添加一个条件,仅当产品的 Ref 存在时才返回查询。只有一些用户有 Ref,因此,我收到一个错误:"description": "Ref or Set expected, Null provided."
    • 我已经更新了答案以演示该技术。感谢您的跟进,因为这可能是其他人会遇到的问题。
    • 谢谢你1000次!通过这个例子,它不仅有效,而且我学到了很多东西。干杯!
    猜你喜欢
    • 2017-08-10
    • 2020-09-03
    • 2021-04-20
    • 2021-11-25
    • 2012-09-15
    • 2015-04-10
    • 2021-11-22
    • 2020-06-05
    相关资源
    最近更新 更多