2 votes

Tri imbriqué en GraphQL

J'utilise Contentful comme CMS, dans lequel je dispose des modèles de contenu "Category" et "Subcategory". Chaque sous-catégorie a une catégorie comme parent. Les deux modèles ont une propriété appelée order que je définis dans le CMS pour décider de l'ordre dans lequel ils apparaîtront dans la navigation.

Voici ma requête GraphQL :

query {
  allContentfulCategory(sort: {fields: [order, subcategory___order]}) {
    edges {
      node {
        order
        title
        subcategory {
          order
          title
        }
      }
    }
  }
}

Le premier tri fonctionne correctement et la requête affiche mes catégories par le champ d'ordre, plutôt que dans l'ordre inverse de création qui semble être la sortie par défaut de Contentful (les catégories les plus récentes apparaissent en premier).

Cependant, ma deuxième sorte de subcategory___order qui s'est inspiré de cet article de blog n'est pas évalué. En d'autres termes, les sous-catégories (par catégorie) s'affichent dans l'ordre inverse de sorte que l'élément supérieur a un ordre de 8, et il diminue à 7, et 6, et ainsi de suite.

Par exemple, disons que j'ai la catégorie "Animaux" avec l'ordre 2, et "Arbres" avec l'ordre 1. Mon contenu dans l'ordre inverse de création : "Chat" (ordre 3), "Chien" (ordre 1), "Poulet" (ordre 2), "Bouleau" (ordre 2), "Chêne" (ordre 3), et "Saule" (ordre 1).

Ceux-ci se présenteront à travers la requête de la manière suivante :

Trees (1):
  Birch (2)
  Oak (3)
  Willow (1)
Animals (2):
  Cat (3)
  Dog (1)
  Chicken (2)

Je ne trouve pas le moyen de faire en sorte que la requête GraphQL exécute les deux commandes de tri simultanément afin que mes données soient classées selon l'ordre que j'ai défini dans le CMS.

Merci d'avance !

Edit : Voici une solution de composant :

Dans chaque nœud de catégorie issu de ma requête, je peux accéder aux sous-catégories et à leur ordre dans un tableau.

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>
         )
      })}

L'élément clé ici est la façon dont je trie le tableau par ordre de sous-catégorie dans le composant :

category.node.subcategory.sort((a, b) => {return a.order - b.order})

Pour être clair, ce n'est pas une solution satisfaisante, et cela ne répond pas à ma question sur la façon dont je pourrais écrire plusieurs tris GraphQL. Mais ce code fait ce que je voulais en ce qui concerne l'organisation des sous-catégories.

2voto

Derek Nguyen Points 5989

Vous interrogez category et non subcategory :

query {
  allContentfulCategory(sort: {fields: [order, subcategory___order]}) {
    edges {
      node {
        order
        title
        subcategory {
          order
          title
        }
      }
    }
  }
}

Dans la requête ci-dessus, seul le tableau retourné data.allContentfulCategory.edges est trié. Gatsby ne triera pas les données immergées dans category.subcategory .

De plus, le deuxième champ que vous avez spécifié ( subcategory___order ) ne sera pris en compte que si le premier champ ( order ) est le même. Puisque chaque catégorie a un ordre unique, subcategory ne sera jamais utilisé.

S'il vous est possible de faire une demande pour quelque chose comme allContentfulSubcategory à la place, cela fonctionnera.

Sinon, vous pouvez déplacer la logique de tri vers le moment de la construction en utilisant la commande createSchemaCustomization . Je ne sais pas à quoi ressemble votre schéma, il ne s'agit donc que d'un exemple :

// gatsby-node.js
exports.createSchemaCustomization = ({ actions, schema }) => {
  const { createTypes } = actions
  const typeDefs = [
    schema.buildObjectType({
      name: "ContentfulCategory",
      fields: {
        subcategory: {
          type: "[ContentfulSubcategory]",
          resolve: (src) => {
            const subcategories = src.subcategory
            return subcategories.sort()
          }
        },
      },
      interfaces: ["Node"],
      extensions: { infer: true },
    }),
  ]
  createTypes(typeDefs)
}

Si vous devez utiliser createSchemaCustomization voir les docs Gatsby sur le sujet ici .

Les informations des docteurs peuvent être accablantes, j'ai aussi J'ai écrit un peu sur cette API ici . Il s'agit davantage d'une extension de champ, mais la fonction de résolveur est fondamentalement la même.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X