Reactjs GraphQL中的嵌套排序
我使用Contentful作为CMS,其中有内容模型“Category”和“Subcategory”。每个子类别都有一个类别作为其父类别。两个模型都有一个名为Reactjs GraphQL中的嵌套排序,reactjs,graphql,gatsby,Reactjs,Graphql,Gatsby,我使用Contentful作为CMS,其中有内容模型“Category”和“Subcategory”。每个子类别都有一个类别作为其父类别。两个模型都有一个名为order的属性,我在CMS中设置了该属性,以确定它们在导航上的显示顺序 以下是我的GraphQL查询: query { allContentfulCategory(sort: {fields: [order, subcategory___order]}) { edges { node { order
order
的属性,我在CMS中设置了该属性,以确定它们在导航上的显示顺序
以下是我的GraphQL查询:
query {
allContentfulCategory(sort: {fields: [order, subcategory___order]}) {
edges {
node {
order
title
subcategory {
order
title
}
}
}
}
}
第一次排序工作正常,查询按顺序字段输出my categories,而不是按相反的创建顺序输出,这似乎是Contentful的默认输出(最新的类别首先显示)
然而,我的第二种子类别uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。换句话说,子类别(每个类别)以相反的顺序显示,因此顶部项目的顺序为8,并减少到7和6,依此类推
例如,假设我的类别“动物”的顺序为2,而“树”的顺序为1。我的内容以相反的顺序创作:“猫”(第3顺序)、“狗”(第1顺序)、“鸡”(第2顺序)、“桦树”(第2顺序)、“橡树”(第3顺序)和“柳树”(第1顺序)
这些将通过如下方式进行查询:
Trees (1):
Birch (2)
Oak (3)
Willow (1)
Animals (2):
Cat (3)
Dog (1)
Chicken (2)
我无法找到一种方法使GraphQL查询同时执行两个排序命令,以便根据我在CMS中设置的顺序对数据进行排序
非常感谢
编辑:这里有一个组件解决方案:
在来自查询的每个类别节点中,我可以访问子类别及其在数组中的顺序
const categories = data.allContentfulCategory.edges
{categories.map((category) => {
return (
<div>
{category.node.subcategory && category.node.subcategory.sort((a, b) => {return a.order - b.order}).map((subcategory) => {
return (
<div>
<p>{subcategory.title}</p>
</div>
)
})}
</div>
)
})}
const categories=data.allcontentfulcontegority.edges
{categories.map((categority)=>{
返回(
{category.node.subcategory&&category.node.subcategory.sort((a,b)=>{return a.order-b.order}).map((subcategory)=>{
返回(
{子类别.标题}
)
})}
)
})}
这里的关键元素是如何在组件中按子类别顺序对数组进行排序:
category.node.subcategory.sort((a,b)=>{return a.order-b.order})
很明显,这不是一个令人满意的解决方案,也不能回答我关于如何编写多个GraphQL排序的问题。但是,这段代码在组织子类别方面实现了我想要的功能。您查询的是类别
,而不是子类别
:
query {
allContentfulCategory(sort: {fields: [order, subcategory___order]}) {
edges {
node {
order
title
subcategory {
order
title
}
}
}
}
}
在上面的查询中,仅对返回的数组data.allContentfulCategory.edges
进行排序。盖茨比不会对嵌套在category.subcategory
中的数据进行排序
此外,仅当第一个字段(顺序
)相同时,才会考虑指定的第二个字段(子类别
)。由于每个类别都有唯一的顺序,子类别
将永远不会被使用
如果您可以查询类似于allContentfulSubcategory
的内容,那么它将起作用
否则,您可以使用createSchemaCustomization
将排序逻辑移动到构建时。我不知道您的模式是什么样子,所以这只是一个示例:
//gatsby-node.js
exports.createSchemaCustomization=({actions,schema})=>{
const{createTypes}=actions
常量typeDefs=[
schema.buildObjectType({
名称:“ContentfulCategory”,
字段:{
子类别:{
类型:“[ContentfulSubcategory]”,
解析:(src)=>{
常量子类别=src.subcategory
返回子类别。排序()
}
},
},
接口:[“节点”],
扩展名:{推断:真},
}),
]
createTypes(typeDefs)
}
如果需要使用createSchemaCustomization
,请参阅
我还认为,这些文档的信息可能会让人不知所措。更多的是关于字段扩展,但是解析器函数基本上是相同的。IMHO不受支持(排序不符合graphql规范,取决于实现)-感谢您解释问题所在,并提供看起来非常优雅的解决方案。您可以在我对问题的编辑中看到,我找到了一个基于组件的解决方案。您能否谈谈哪一个对性能/实践等更有利,CreateSchemaCustazization还是仅仅在组件级别排序?顺便说一句,在你的博客上有一个整洁的设计!谢谢@22moonriver!我认为在实践中,在组件中执行排序没有任何区别,除非您拥有大量数据。使用createSchemaCustomization,排序将仅在gatsby构建期间执行,而不会在客户端执行(与基于组件的解决方案类似)