为什么我需要这样做:我使用的是graphql+gatsby+contentful。我在Contentful中使用了富文本字段,它允许在markdown中嵌入对象引用。我想显示嵌入的条目。
我的查询如下:
export const pageQuery = graphql`
query BlogPostBySlug($slug: String!) {
richTextField {
content {
nodeType
data {
target {
sys {
id
}
}
}
}
}
}
}
`
richTextField.content
回来时是这样的:
{
"data": {
"target": {
"sys": {
"id": "5wVh2a6XvySacEioOEMyqQ",
}
}
},
}
id"5wVh2a6XvySacEioOEMyqQ"是对另一个数据库条目的引用。我可以看到两种可能的工作方式:
告诉graphql查询中的id引用其他数据库模型并使其自动填充字段的某种方法。这可能吗?
获取此查询的结果,收集所有ID,并构造另一个查询,在其中搜索具有这些ID的条目。看起来apollo可能是一个解决方案,但它对盖茨比来说效果不佳。这可能吗?
最好的方法是什么?
谢谢!:(
richtext字段是相当新的,看起来还没有解决。在这里给盖茨比的人们更多的信息,这样他们就能进步,这可能是件好事。
您可以尝试使用外键来关联节点。
在gatsby-node.js
文件中,您需要添加一个附加有___NODE
的密钥,该密钥具有要链接的sys
节点的id:
exports.sourceNodes = async ({ getNodes, actions, createContentDigest }) => {
// find all the sys nodes - you'll need to alter this filter to get the right one
const sysNodes = getNodes().filter(node => node.internal.type === 'File');
// go through the posts to map the sys nodes
// these nodes may already exist, so you could filter `getNodes` like above
const postData = howeverYouGetDataFromContentful();
postData.forEach(post => {
const sys = sysNodes.find(embedded => embedded.id === post.data.target.embedded.id);
// This will create a brand-new node.
// If your posts already exist, then use `createNodeField` mentioned below
const node = {
id: post.id,
children: [],
internal: {
type: 'post',
mediaType: 'text/json',
contentDigest: createContentDigest(JSON.stringify(post))
},
sys___NODE: sys.id
};
actions.createNode(node);
});
}
如果在调用sourceNodes
时节点已经存在(它们可能与Contentful一起存在(,则可以使用getNodes
对它们进行筛选。您可能还需要使用createNodeField
而不是createNode
,如下所述:https://github.com/gatsbyjs/gatsby/issues/3129#issuecomment-360927436,以避免重新创建节点。