#Schema default value
1 messages · Page 1 of 1 (latest)
Hi @fiery umbra. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
Yes, it is possible to set default values in Convex schemas. This can be done by using the v.optional() function when defining your schema. This function allows you to specify a field as optional, and you can then manually include a default value when reading data from the database.
Here's an example of how you can do this:
// schema.ts
posts: defineTable({
// ... other fields
contentType: v.optional(v.union(v.literal("text"), v.literal("video")))
}),
In this example, a contentType field is added and made optional. When reading posts, you can manually include a default value:
// myFunctions.ts
return (await ctx.db.query("posts")).map((post) => ({
...post,
contentType: post.contentType ?? "text",
}));
If the default value is just a simple value, you can achieve this more easily with Convex Ents:
// schema.ts
posts: defineEnt({
// ... other fields
})
.field(
"contentType",
v.union(v.literal("text"), v.literal("video")),
{ default: "text" }
)
In this case, contentType is not an optional field in the document type, and TypeScript can ensure that you’re always providing it when writing to the database.
For more complex migrations, you might want to use the migration helper to run a specified function over each document in your table, in batches. This can be useful for adding a new field with a default value.
Please refer to these sources for more information:
- Convex Ents: Manage your document relationships (https://stack.convex.dev/ents#default-field-values)
- Data Migrations using Mutations (https://stack.convex.dev/migrating-data-with-mutations#common-use-cases)
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@fiery umbra kapa.ai is still learning and improving, please let us know how it did by reacting below
how do I query records that might have some value in an array
@rancid whale
Let me check the knowledge base for you. One moment! :books:
In Convex, querying records based on array values can be a bit tricky as Convex doesn't support an arrayContains filter. However, there are a few ways you can achieve this:
- Using JavaScript Array Filter: You can fetch all the records and then use JavaScript's array filter method to filter out the records that contain the specific value in the array. Here's an example:
export const postsWithTag = query({
args: { tag: v.string() },
handler: async (ctx, args) => {
const allPosts = await ctx.db.query("posts").collect();
return allPosts.filter((post) => post.tags.includes(args.tag));
},
});
In this example, await ctx.db.query("posts").collect() returns an array of all posts, which is then filtered to only the posts which include args.tag in their array of tags.
Please note that this method might not be efficient for large datasets as it involves fetching all the records into memory.
- Using Relations: Another approach is to use relations. You can create another table with one document per item in the array and query on that table. Here's an example:
// in schema.ts
postTags: defineTable({
postId: v.id("posts"),
tag: v.string(),
}).index("tag", ["tag"])
Then you can query like this:
// in query:
const matchingPostTags = await db.query("postTags").withIndex("tag", q => q.eq("tag", "myTag")).collect();
// fetch those posts
const posts = await Promise.all(matchingPostTags.map(async (pt) => db.get(pt.postId)));
This approach is more efficient as it doesn't involve fetching all the records into memory.
For more information, please refer to these sources:
- Using TypeScript to Write Complex Query Filters (https://stack.convex.dev/complex-filters-in-convex#filter-too-complex-do-it-in-typescript)
- Discord support thread: Can you filter on an array (https://discord.com/channels/1019350475847499849/1101302409218768968)