#something about index
13 messages · Page 1 of 1 (latest)
Hi @uncut tide. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
Your approach is almost correct, but you need to ensure that:
- The index "by_webhook_item" is defined in your schema with the fields in the correct order: first "webhookId", then "itemId".
- The callback function passed to
.withIndexshould use the arrow function syntax.
Here's the correct way to write this query:
const delivery = await ctx.db
.query("webhook_deliveries")
.withIndex("by_webhook_item", q =>
q.eq("webhookId", args.webhookId).eq("itemId", args.itemId)
)
.first();
And your schema should define the index like this:
export default defineSchema({
webhook_deliveries: defineTable({
webhookId: v.id("webhooks"),
itemId: v.id("items"),
// ... other fields
}).index("by_webhook_item", ["webhookId", "itemId"]),
});
This ensures that your query efficiently uses the index to find the document matching both webhookId and itemId in the correct order. The .first() method will return the first matching document or null if none is found. Remember, the order of fields in the index definition and in the query must match and start from the first field in the index see docs.
If you use the .withIndex method as shown, Convex will efficiently jump to the correct range in the index and return the result see example.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@uncut tide Kapa.ai is still learning and improving, please let me know how I did by reacting below.
yes but i'm getting this @timid tusk Property 'eq' does not exist on type 'IndexRange'.ts(2339)
Let me check the knowledge base for you again. One moment! :books:
The error Property 'eq' does not exist on type 'IndexRange' usually means that you are trying to call .eq() after a method that returns an IndexRange, not an IndexRangeBuilder. In Convex, you must call .eq() in the correct order and only on the fields defined in your index, and you cannot chain .eq() after a range method like .gt(), .gte(), .lt(), or .lte().
Common causes:
- You might be missing the arrow function syntax in
.withIndex. - You might be calling
.eq()outside the callback, or after a range method.
Correct usage:
const delivery = await ctx.db
.query("webhook_deliveries")
.withIndex("by_webhook_item", q =>
q.eq("webhookId", args.webhookId).eq("itemId", args.itemId)
)
.first();
Incorrect usage (causes your error):
// ❌ This is incorrect and will cause the error you saw:
.withIndex("by_webhook_item", q.eq("webhookId", args.webhookId).eq("itemId", args.itemId))
Notice the difference:
- The correct version uses an arrow function:
q => q.eq(...).eq(...) - The incorrect version tries to call
.eq()directly onq, which is not valid.
Reference:
The callback you pass to
.withIndexshould use the arrow function syntax, and you must step through fields in index order. Each equality expression must compare a different index field, starting from the beginning and in order see docs.
If you follow the correct pattern, the error should go away. If you still see the error, double-check your index definition and the order of fields in both the schema and the query.
If you need to use range queries (like .gt() or .lt()), remember that after a range method, you cannot chain .eq()—you can only use one range per index field, and in the correct order see docs.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@uncut tide Kapa.ai is still learning and improving, please let me know how I did by reacting below.
yes i'm using the first one you suggest @timid tusk
Let me check the knowledge base for you again. One moment! :books:
If you are using the correct arrow function syntax in your .withIndex call, like this:
const delivery = await ctx.db
.query("webhook_deliveries")
.withIndex("by_webhook_item", q =>
q.eq("webhookId", args.webhookId).eq("itemId", args.itemId)
)
.first();
but you are still seeing the error Property 'eq' does not exist on type 'IndexRange', there are a few possible causes based on the knowledge sources:
-
Index Definition Order: Make sure your index in the schema is defined with the fields in the exact order you are querying them. For example:
.index("by_webhook_item", ["webhookId", "itemId"])The order in the query must match the order in the index definition see: Indexing Multiple Fields.
-
TypeScript Context: If your TypeScript context does not know about your schema, you may get type errors. This can happen if you are not using the correct context type (e.g.,
MutationCtxorQueryCtxfrom your generated Convex types). This is a common issue and is discussed in Discord threads—make sure your handler is typed correctly so TypeScript knows about your schema and indexes see: Discord thread. -
Convex Dev Not Running: If you have recently changed your schema, make sure you have run
npx convex devso that your generated types are up to date. Otherwise, TypeScript may not recognize your new index. -
Arrow Function Syntax: Double-check that you are using the arrow function syntax in
.withIndex, not passing the result of.eq()directly as the second argument. The correct usage is:.withIndex("by_webhook_item", q => q.eq("webhookId", args.webhookId).eq("itemId", args.itemId))
Not:
.withIndex("by_webhook_item", q.eq("webhookId", args.webhookId).eq("itemId", args.itemId))