为什么需要这样做:我正在使用graphql + gatsby +内容丰富。我正在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可能是一个解决方案,但不适用于gatsby。这可能吗?
最好的方法是什么?
谢谢! :)
答案 0 :(得分:0)
richtext字段是一个相当新的字段,看来还没有解决。最好给盖茨比人更多的信息here,以便他们进步。
答案 1 :(得分:0)
您可以尝试使用foreign keys来关联节点。
在您的gatsby-node.js
文件中,您需要添加一个附加有___NODE
且ID为sys
的节点的密钥来链接:
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以避免重新创建节点。