#Nested query… default sort

1 messages · Page 1 of 1 (latest)

prisma grove
#

I was able to get sorting to work via a lazy loading nested query using composite identifiers. Using secondary index with a sort key did not work.

Demo Schema:

const schema = a.schema({
  Team: a
    .model({
      name: a.string().required(),
      players: a.hasMany("Player", ["teamId"]),
    })
    .authorization((allow) => [allow.publicApiKey()]),

  Player: a
    .model({
      name: a.string().required(),
      position: a.string(),
      teamId: a.id().required(), 
      jerseyNumber: a.integer().required(),
      team: a.belongsTo("Team", ["teamId"]),
      createdAt: a.datetime(),
    })
    .authorization((allow) => [allow.publicApiKey()])
    .identifier(["teamId", "jerseyNumber"]),
});

Demo Code:

      // First get the team
      const { data: teamData } = await client.models.Team.get({ id: team.id });

      if (teamData) {
        // Then lazy load the players relationship
        // Players are sorted by jersey number
        const playersResult = await teamData.players();
        const playersData = playersResult.data;
        console.log(playersData)
      }

Oddly enough, using a selection set to populate players doesn't result in players sort by jersey number:

      const teamWithPlayersSelectionSet = ["id", "name", "players.*"] as const;

      // Players are not sorted by jersey number
      const { data } = await client.models.Team.get(
        { id: team.id },
        {
          selectionSet: teamWithPlayersSelectionSet,
        }
      );
prisma grove
#

@proper summit And yes, nextToken can be found in the result

const playersResult = await teamData.players();

// inspecting the type of playersResult
const playersResult: {
    data: {
        name: string;
        teamId: string;
        jerseyNumber: number;
        team: (options?: {
           // team fields
        } | null>;
        position?: Nullable<...> | undefined;
        createdAt?: Nullable<...> | undefined;
        readonly updatedAt: string;
    }[];
    nextToken?: string | null; // you have the nextToken here
    errors?: GraphQLFormattedError[];
    extensions?: {
        [key: string]: any;
    };
}

prisma grove
#

Is it possible to share a minimal example of your Schema??

#

If you need sort direction, then you probably just need to directly utilize the secondary index query. Maybe someone else can confirm this to be true.

proper summit
#

The solution was to add a new field to my model (I called it sortedMessages, but you can name it however you like). I defined it as a custom type with:
• nextToken: a.string()
• items: a.ref("YourTableTypeFields")

Then I attached a custom resolver to the table’s sortedMessages field, and inside that resolver I queried using my custom GSI.

This worked out far better than my first approach, where I built a Lambda and pointed the model at it. Nesting data through Lambda was painful, but with this method I can easily reuse the sortedMessages field as a clean, standard nested resolver anywhere I reference the model.