#Should I avoid this ent query?

9 messages · Page 1 of 1 (latest)

upper pike
#

This is an example from ents docs:

export const listTeamInvites = query({
  args: { teamId: v.id("teams") },
  async handler(ctx, { teamId }) {
    return await ctx
      .table("teams")
      .getX(teamId)
      .edge("invites")
      .map(async (invite) => ({
        _id: invite._id,
        email: invite.email,
        role: (await invite.edge("role")).name,
      })); // `{ _id: Id<"invites">, email: string, role: string }[]`
  },
});

It's likely there are just a few roles so I guess it's fine but let's say there are many roles or let's say it's ever growing collection i.e "posts". Should I try to avoid this kind of query and doing i.e title: (await invite.edge("posts")).title

My example might be silly with "posts" but just want to make a point and to understand if this is ok for larger collections then just "roles".

neat briarBOT
#

Thanks for posting in #1088161997662724167.
Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets.

    - Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.)
    - Use [search.convex.dev](https://search.convex.dev) to search Docs, Stack, and Discord all at once.
    - Additionally, you can post your questions in the Convex Community's #1228095053885476985 channel to receive a response from AI.
    - Avoid tagging staff unless specifically instructed.

    Thank you!
upper pike
#

ok here is more concrete example that I'm working on:

export const remove = authMutation({
  args: {},
  handler: async (ctx, args) => {
    // Get user account
    const account = await ctx.table("accounts").getX(ctx.user.currentAccountId);

    // Find unpaid receipts
    const unpaidBillingReceipts = await account
      .edge("billings")
      .map(async (b) => {
        const billingReceipt = await b.edge("billingReceipt").doc();
        // This is unpaid billing because no billingReceipt record with data property
        if (!billingReceipt?.data) return true; 
      })
      .filter(Boolean);

    // Do not delete account that has unpaid billing
    if (unpaidBillingReceipts.length > 0) return { unpaid: true };

    // Delete account ...

This is my ents database relations:

 billings: defineEnt({
   // fields ...
 })
    .edge("account")
    .edge("billingReceipt", { ref: true })
    .edge("feeTier"),

 billingReceipts: defineEnt({
   // fields ...
 }).edge("billing"),

I'm trying to understand if there is a better way todo this query or this is completely fine.

boreal gulch
#

What's your concern here, why might this not be fine?

upper pike
#

That "map" function that could potentially go through many records. I guess it's a special ".map" in convex right?

boreal gulch
#

Like Array.map, this really will run your callback function which fetches the billing receipt. But what's the concern with that? Even though these functions run in the database, fetching a document is always going to be slower than running a function like this.

Backing up, what are you worried about here generally? The query being too slow?

#

Going through many records is exactly what this code does, in order to return those records aka documents to the client. Adding a map isn't bad.

upper pike
#

Thanks for the response. I'm just generally thinking whether this is good/bad/can be better

wintry palm
#

Mapping over relations this way is best practice, whether using ents or not. The only concern would be if you anticipate returning too many documents within a single query, in which case you'll need to limit through something like .take() or .paginate().