#withIndex q.in

7 messages · Page 1 of 1 (latest)

twin mica
#

is there a way to search an indexed table with an array of subjects? i.e.

ctx.db.query('data').withIndex('by_profile', q => q.in('profile', profiles))

where profiles is an array of ids

cosmic jewelBOT
#

Hi @twin mica. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

There isn’t a q.in (or general “IN” / “OR over an array”) operator available inside withIndex, and this is intentional. [Convex syntax; No efficient in]

So this:

ctx.db
  .query("data")
  .withIndex("by_profile", q => q.in("profile", profiles));

is not supported.

The recommended pattern is to run one efficient indexed query per profile id and then merge the results in JavaScript:

async function byProfile(profileId: Id<"profiles">) {
  return await ctx.db
    .query("data")
    .withIndex("by_profile", q => q.eq("profile", profileId))
    .collect();
}

const resultsPerProfile = await Promise.all(profiles.map(byProfile));
const allResults = resultsPerProfile.flat();

This is exactly how you’d translate a SQL WHERE profile IN (...) / OR into Convex. [Union; IN operator thread]

If you need pagination over the union, you can instead use QueryStreams plus mergedStream from convex-helpers to merge multiple indexed streams and then paginate the merged stream. [Union streams; Merging streams]

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@twin mica Kapa.ai is still learning and improving, please let me know how I did by reacting below.

twin mica
#

@cosmic jewel if i just want 1 field from a query, is there any way to narrow down to returning only that field? i assume it would help with redcing noise form subscriptions that triggers when updating fields that the query does not care about

cosmic jewelBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

There’s no built‑in way in Convex today to have a query “select only one field” at the database level or to avoid reactivity when other fields on the same document change.

Convex queries always read whole documents; if you only need one field, you narrow it in code after the query, e.g.:

const docs = await ctx.db.query("messages").collect();
const bodies = docs.map(d => d.body);

This is the recommended pattern and is explicitly documented as the Convex equivalent of SELECT body FROM messages. [Select fields]

The same doc also notes that queries still read entire documents even when you only return a subset of fields, and that this is usually fine because the main bandwidth bottleneck is between client and server, not server and storage. [Select fields]

Regarding subscriptions: the knowledge sources don’t describe any mechanism to make a query “react only to specific fields,” so as far as the docs show, updates to any field in a document that matches the query can cause the subscribed query to re-run. There’s no documented way to change that granularity today.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: