如何使用 GraphQL、Firebase 和 Gatsby 查询关系数据

How to query relational data with GraphQL, Firebase and Gatsby

我正在构建一个 Gatsby.js 站点。

站点使用 gatsby-source-firestore plugin to connect to the Firestore 数据源。

我的问题是这样的。如何查询关系数据?同样,一次从两个模型中获取数据,其中 modelA[x] = modelB[y]

我不太了解解析器。我认为没有。

请注意,我目前不考虑 graph.cool。我想坚持使用 Firebase。如果必须(不是 GraphQL),我将在纯 JS 中进行关系数据匹配。

这是我的 gatsby-config.js 的样子:

{
  resolve: 'gatsby-source-firestore',
  options: {
    credential: require('./firebase-key.json'),
    databaseURL: 'https://testblahblah.firebaseio.com',
    types: [
      {
        type: 'Users',
        collection: 'users',
        map: user => ({
          firstName: user.firstName,
          lastName: user.lastName,
          email: user.email,
          ownsHat: user.ownsHat,
          hatId: user.hatId
        })
      },
      {
        type: 'Hats',
        collection: 'hats',
        map: hat => ({
            hatType: hat.hatType,
            hatUserId: hat.hatUserId,
            hatId: hat.hatId
        })
      }
    ]
  }
},

这将引入两个平面数据模型。我可以在页内这样查询:

任意-page.js

export const query = graphql`
  query {
    allUsers {
      edges {
        node {
          ...UserFragment
        }
      }
    }
  }
`

我正在寻找的是一个查询,它允许我在另一个查询中编写一个查询,即查询中的关系数据查询。

export const query = graphql`
  query {
    allUsers {
      edges {
        node {
          ...UserFragment {
              hats (user.userId == hat.userId){
                  type
                  hatId
              }
          }
        }
      }
    }
  }
`

如您所知,这相当于:如何 运行 关系数据的多个 GraphQL 查询。

鉴于 Firestore 的平面性质 JSON,这使得 GraphQL 的关系方面变得困难。

我真的很想更好地理解这一点,非常感谢被指出正确的道路。

我非常热衷于坚持使用 GraphQL 和 Firebase。

谢谢!

我不确定这在 graphql 中是否有效,但在 Gatsby 中,您可以使用 gatsby-node 来创建和更改节点并将 hats 注入每个 user 节点。这是我用来将作者添加到 Post 节点的示例代码:

const mapAuthorsToPostNode = (node, getNodes) => {
    const author = getPostAuthorNode(node, getNodes);
    if (author) node.authors___NODES = [author.id];
};

exports.sourceNodes = ({actions, getNodes, getNode}) => {
    const {createNodeField} = actions;

    getCollectionNodes('posts', getNodes).forEach(node => {
        mapAuthorsToPostNode(node, getNodes);
    });
};

这是一种方法,前提是记录数量不多。如果是,您应该创建一个 hats 页面来显示用户帽子,您可以在其中查询通过用户 ID 过滤的帽子,用户 ID 是通过 paceContext 参数接收的,例如用户 ID。

export const pageQuery = graphql`
    query($userId: String) {
        hats: allHats(
            filter: {
                userId: {eq: $userId}
            }
        ) {
            edges {
                node {
                    ...hatFragment
                }
            }
        }
    }
`;