i.sona
i.sona2mo ago

using convex-ents mapping feature

how do i combine map with afilter or getX(index) . something like
const team = ctx
.table('teams')
.get(ctx.viewerX().teamId)
.map((t: Ent<'teams'>) => {
return {
team: t.doc(),
teamLocations: t.edgeX('teamLocations').docs(),
workdaySettings: t.edgeX('workdaySetting').doc(),
calendarBlocks: t
.edgeX('calendarBlocks')
.filter((q: any) => q.gte(q.field('startDate'), Date.now()))
.docs(),
appointmentTypes: t.edgeX('appointmentTypes').docs()
}
})
const team = ctx
.table('teams')
.get(ctx.viewerX().teamId)
.map((t: Ent<'teams'>) => {
return {
team: t.doc(),
teamLocations: t.edgeX('teamLocations').docs(),
workdaySettings: t.edgeX('workdaySetting').doc(),
calendarBlocks: t
.edgeX('calendarBlocks')
.filter((q: any) => q.gte(q.field('startDate'), Date.now()))
.docs(),
appointmentTypes: t.edgeX('appointmentTypes').docs()
}
})

or
const team = await ctx.table('teams')
.filter((q: any) => q.eq(q.field('teamId'), ctx.viewerX().teamId))
.map((t: Ent<'teams'>) => {
return {
team: t.doc(),
teamLocations: t.edgeX('teamLocations').docs(),
workdaySettings: t.edgeX('workdaySetting').doc(),
calendarBlocks: t
.edgeX('calendarBlocks')
.filter((q: any) => q.gte(q.field('startDate'), Date.now()))
.docs(),
appointmentTypes: t.edgeX('appointmentTypes').docs()
}
})
.firstx()
const team = await ctx.table('teams')
.filter((q: any) => q.eq(q.field('teamId'), ctx.viewerX().teamId))
.map((t: Ent<'teams'>) => {
return {
team: t.doc(),
teamLocations: t.edgeX('teamLocations').docs(),
workdaySettings: t.edgeX('workdaySetting').doc(),
calendarBlocks: t
.edgeX('calendarBlocks')
.filter((q: any) => q.gte(q.field('startDate'), Date.now()))
.docs(),
appointmentTypes: t.edgeX('appointmentTypes').docs()
}
})
.firstx()
should be possible , such that the mapping is on a subset of data instead of the whole table being transversed , when there is a very large dataset.
9 Replies
Convex Bot
Convex Bot2mo ago
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 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!
erquhart
erquhart2mo ago
Collect the filter result and then use Promise.all to map over the results in parallel. Example from docs: https://docs.convex.dev/database/reading-data/#join
i.sona
i.sonaOP2mo ago
I want to stick to convex-ents, the question is related to convex-ents
erquhart
erquhart2mo ago
Reading Ents from the Database - Convex Ents
Relations, default values, unique fields and more for Convex
erquhart
erquhart2mo ago
That right sidebar in the docs there has lots of ents methods to browse through for different use cases.
ampp
ampp2mo ago
.get is only used for returning a single ent .getMany is not worth the trouble unless you already have a array of Id's .filter is not using a index and will eventually blow up when the table grows larger use: https://labs.convex.dev/convex-ents/read#listing-ents-filtered-by-index
Reading Ents from the Database - Convex Ents
Relations, default values, unique fields and more for Convex
i.sona
i.sonaOP2mo ago
I am aware of Al the suggested but none of them answers the question. In a map I can build an abitrary type based on relationship , but with a map in convex-ents you can’t narrow the table scans with an index or a filter , it only applies to all entities in a table. You only apply everything else after the fact which in itself like filter becomes costly as data grows . I should be able to map on an index and attach related data (like a join) in one transaction. I guess convex needs sdks like Kysely or even genql (best lib I know of ontop of graphql)
ampp
ampp2mo ago
I'm confused as i havent ran into any limitations. I do:
await ctx
.table('members', 'by_memberId', (q) =>
q.eq('memberId', args.memberId)
)
.order('asc')
.map(async (member) => {
etc
await ctx
.table('members', 'by_memberId', (q) =>
q.eq('memberId', args.memberId)
)
.order('asc')
.map(async (member) => {
etc
Most of the time i .paginate before the .map
deen
deen2mo ago
You can "map" over a single ent using the .then property. Using .edgeX with another index isn't supported. Instead use something like: calendarBlocks: await ctx.table('calendarBlocks', 'teamId_startDate', q => ... ).docs() But you can still enjoy the convenience of .edgeX for collecting edges which don't require any additional filtering. It's still more concise API than vanilla convex.

Did you find this page helpful?