docs: document composite indices + primary key changes (#7902)
This commit is contained in:
1 parent
a84e5a6ced
commit
6cb28eedf7
13 files changed
+205
-93
No files matched your search
@@ -0,0 +1,13 @@
|
|||||||
|
export const metadata = {
|
||||||
|
title: `${pageNumber} Data Model Default Properties`,
|
||||||
|
}
|
||||||
|
|
||||||
|
# {metadata.title}
|
||||||
|
|
||||||
|
In this chapter, you'll learn about the properties available by default in your data model.
|
||||||
|
|
||||||
|
When you create a data model, the following properties are created for you by Medusa:
|
||||||
|
|
||||||
|
- `created_at`: A `dateTime` property that stores when a record of the data model was created.
|
||||||
|
- `updated_at`: A `dateTime` property that stores when a record of the data model was updated.
|
||||||
|
- `deleted_at`: A `dateTime` property that stores when a record of the data model was deleted. When you delete a record, Medusa soft-deletes it by setting the `deleted_at` property to the current date.
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
export const metadata = {
|
||||||
|
title: `${pageNumber} Data Model Index`,
|
||||||
|
}
|
||||||
|
|
||||||
|
# {metadata.title}
|
||||||
|
|
||||||
|
In this chapter, you’ll learn how to define indices on a data model.
|
||||||
|
|
||||||
|
## Define Index on Property
|
||||||
|
|
||||||
|
Define an index on a property using the `model` utility's `index` method.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
export const highlights = [
|
||||||
|
["5", "index", "Define an index on the `name` property."],
|
||||||
|
["6", '"IDX_MY_CUSTOM_NAME"', "Index name is optional."]
|
||||||
|
]
|
||||||
|
|
||||||
|
```ts highlights={highlights}
|
||||||
|
import { model } from "@medusajs/utils"
|
||||||
|
|
||||||
|
const MyCustom = model.define("my_custom", {
|
||||||
|
id: model.id().primaryKey(),
|
||||||
|
name: model.text().index(
|
||||||
|
"IDX_MY_CUSTOM_NAME"
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
export default MyCustom
|
||||||
|
```
|
||||||
|
|
||||||
|
The `index` method optionally accepts the name of the index as a parameter.
|
||||||
|
|
||||||
|
In this example, you define an index on the `name` property.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Define Index on Data Model
|
||||||
|
|
||||||
|
A data model has an `indexes` method that defines indices on the data model.
|
||||||
|
|
||||||
|
The index can be on multiple columns (composite index). For example:
|
||||||
|
|
||||||
|
export const dataModelIndexHighlights = [
|
||||||
|
["7", "indexes", "Define indices on the data model."],
|
||||||
|
["9", "on", "Specify the properties to define the index on."]
|
||||||
|
]
|
||||||
|
|
||||||
|
```ts highlights={dataModelIndexHighlights}
|
||||||
|
import { model } from "@medusajs/utils"
|
||||||
|
|
||||||
|
const MyCustom = model.define("my_custom", {
|
||||||
|
id: model.id().primaryKey(),
|
||||||
|
name: model.text(),
|
||||||
|
age: model.number()
|
||||||
|
}).indexes([
|
||||||
|
{
|
||||||
|
on: ["name", "age"],
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
export default MyCustom
|
||||||
|
```
|
||||||
|
|
||||||
|
The `indexes` method receives an array of indices as a parameter. Each index is an object with a required `on` property indicating the properties to apply the index on.
|
||||||
|
|
||||||
|
In the above example, you define a composite index on the `name` and `age` properties.
|
||||||
|
|
||||||
|
### Index Conditions
|
||||||
|
|
||||||
|
An index can have conditions. For example:
|
||||||
|
|
||||||
|
export const conditionHighlights = [
|
||||||
|
["10", "where", "Specify conditions on properties."],
|
||||||
|
["11", "", "Create the index when `age` is `30`."]
|
||||||
|
]
|
||||||
|
|
||||||
|
```ts highlights={conditionHighlights}
|
||||||
|
import { model } from "@medusajs/utils"
|
||||||
|
|
||||||
|
const MyCustom = model.define("my_custom", {
|
||||||
|
id: model.id().primaryKey(),
|
||||||
|
name: model.text(),
|
||||||
|
age: model.number()
|
||||||
|
}).indexes([
|
||||||
|
{
|
||||||
|
on: ["name", "age"],
|
||||||
|
where: {
|
||||||
|
age: 30
|
||||||
|
}
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
export default MyCustom
|
||||||
|
```
|
||||||
|
|
||||||
|
The index object passed to `indexes` accepts a `where` property that is an object of conditions. The object's key is a property's name, and its value is the condition on that property.
|
||||||
|
|
||||||
|
In the example above, the composite index is created on the `name` and `age` properties when the `age`'s value is `30`.
|
||||||
|
|
||||||
|
A property's condition can be a negation. For example:
|
||||||
|
|
||||||
|
export const negationHighlights = [
|
||||||
|
["12", "", "Create the index when `age` is not `null`."]
|
||||||
|
]
|
||||||
|
|
||||||
|
```ts highlights={negationHighlights}
|
||||||
|
import { model } from "@medusajs/utils"
|
||||||
|
|
||||||
|
const MyCustom = model.define("my_custom", {
|
||||||
|
id: model.id().primaryKey(),
|
||||||
|
name: model.text(),
|
||||||
|
age: model.number().nullable()
|
||||||
|
}).indexes([
|
||||||
|
{
|
||||||
|
on: ["name", "age"],
|
||||||
|
where: {
|
||||||
|
age: {
|
||||||
|
$ne: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
export default MyCustom
|
||||||
|
```
|
||||||
|
|
||||||
|
A property's value in `where` can be an object having a `$ne` property. `$ne`'s value indicates what the specified property's value shouldn't be.
|
||||||
|
|
||||||
|
In the example above, the composite index is created on the `name` and `age` properties when `age`'s value is not `null`.
|
||||||
|
|
||||||
|
### Unique Data Model Index
|
||||||
|
|
||||||
|
The object passed to `indexes` accepts a `unique` property indicating that the created index must be a unique index.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
export const uniqueHighlights = [
|
||||||
|
["10", "unique", "Specify if the index is a unique index."]
|
||||||
|
]
|
||||||
|
|
||||||
|
```ts highlights={uniqueHighlights}
|
||||||
|
import { model } from "@medusajs/utils"
|
||||||
|
|
||||||
|
const MyCustom = model.define("my_custom", {
|
||||||
|
id: model.id().primaryKey(),
|
||||||
|
name: model.text(),
|
||||||
|
age: model.number()
|
||||||
|
}).indexes([
|
||||||
|
{
|
||||||
|
on: ["name", "age"],
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
export default MyCustom
|
||||||
|
```
|
||||||
|
|
||||||
|
This creates a unique composite index on the `name` and `age` properties.
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
export const metadata = {
|
|
||||||
title: `${pageNumber} Data Model Indexes`,
|
|
||||||
}
|
|
||||||
|
|
||||||
# {metadata.title}
|
|
||||||
|
|
||||||
In this chapter, you’ll learn how to define indexes on a data model.
|
|
||||||
|
|
||||||
## Define Index
|
|
||||||
|
|
||||||
The `index` method defines a custom index on a property.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
export const highlights = [
|
|
||||||
["5", "index", "Define an index on the `name` property."]
|
|
||||||
]
|
|
||||||
|
|
||||||
```ts highlights={highlights}
|
|
||||||
import { model } from "@medusajs/utils"
|
|
||||||
|
|
||||||
const MyCustom = model.define("my_custom", {
|
|
||||||
id: model.id(),
|
|
||||||
name: model.text().index(
|
|
||||||
"IDX_MY_CUSTOM_NAME"
|
|
||||||
),
|
|
||||||
})
|
|
||||||
|
|
||||||
export default MyCustom
|
|
||||||
```
|
|
||||||
|
|
||||||
In this example, you define an index on the `name` property. The `index` method optionally accepts the name of the index as a parameter.
|
|
||||||
@@ -6,35 +6,25 @@ export const metadata = {
|
|||||||
|
|
||||||
In this chapter, you’ll learn how to configure the primary key of a data model.
|
In this chapter, you’ll learn how to configure the primary key of a data model.
|
||||||
|
|
||||||
## id Property
|
|
||||||
|
|
||||||
A property defined with the `id` method is, by default, considered the data model’s primary key.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## primaryKey Method
|
## primaryKey Method
|
||||||
|
|
||||||
To set any `text` or `number` property as a primary key, use the `primaryKey` method.
|
To set any `id`, `text`, or `number` property as a primary key, use the `primaryKey` method.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
export const highlights = [
|
export const highlights = [
|
||||||
["4", "primaryKey", "Define the `code` property to be the data model's primary key."]
|
["4", "primaryKey", "Define the `id` property to be the data model's primary key."]
|
||||||
]
|
]
|
||||||
|
|
||||||
```ts highlights={highlights}
|
```ts highlights={highlights}
|
||||||
import { model } from "@medusajs/utils"
|
import { model } from "@medusajs/utils"
|
||||||
|
|
||||||
const MyCustom = model.define("my_custom", {
|
const MyCustom = model.define("my_custom", {
|
||||||
code: model.text().primaryKey(),
|
id: model.id().primaryKey(),
|
||||||
// ...
|
// ...
|
||||||
})
|
})
|
||||||
|
|
||||||
export default MyCustom
|
export default MyCustom
|
||||||
```
|
```
|
||||||
|
|
||||||
<Note>
|
In the example above, the `id` property is defined as the data model's primary key.
|
||||||
|
|
||||||
A property that’s defined with the `primaryKey` method takes precedence over an `id` property.
|
|
||||||
|
|
||||||
</Note>
|
|
||||||
@@ -31,12 +31,12 @@ export const oneToOneHighlights = [
|
|||||||
import { model } from "@medusajs/utils"
|
import { model } from "@medusajs/utils"
|
||||||
|
|
||||||
const User = model.define("user", {
|
const User = model.define("user", {
|
||||||
id: model.id(),
|
id: model.id().primaryKey(),
|
||||||
email: model.hasOne(() => Email),
|
email: model.hasOne(() => Email),
|
||||||
})
|
})
|
||||||
|
|
||||||
const Email = model.define("email", {
|
const Email = model.define("email", {
|
||||||
id: model.id(),
|
id: model.id().primaryKey(),
|
||||||
user: model.belongsTo(() => User, {
|
user: model.belongsTo(() => User, {
|
||||||
mappedBy: "email",
|
mappedBy: "email",
|
||||||
}),
|
}),
|
||||||
@@ -70,12 +70,12 @@ export const oneToManyHighlights = [
|
|||||||
import { model } from "@medusajs/utils"
|
import { model } from "@medusajs/utils"
|
||||||
|
|
||||||
const Store = model.define("store", {
|
const Store = model.define("store", {
|
||||||
id: model.id(),
|
id: model.id().primaryKey(),
|
||||||
products: model.hasMany(() => Product),
|
products: model.hasMany(() => Product),
|
||||||
})
|
})
|
||||||
|
|
||||||
const Product = model.define("product", {
|
const Product = model.define("product", {
|
||||||
id: model.id(),
|
id: model.id().primaryKey(),
|
||||||
store: model.belongsTo(() => Store, {
|
store: model.belongsTo(() => Store, {
|
||||||
mappedBy: "products",
|
mappedBy: "products",
|
||||||
}),
|
}),
|
||||||
@@ -101,12 +101,12 @@ export const manyToManyHighlights = [
|
|||||||
import { model } from "@medusajs/utils"
|
import { model } from "@medusajs/utils"
|
||||||
|
|
||||||
const Order = model.define("order", {
|
const Order = model.define("order", {
|
||||||
id: model.id(),
|
id: model.id().primaryKey(),
|
||||||
products: model.manyToMany(() => Product),
|
products: model.manyToMany(() => Product),
|
||||||
})
|
})
|
||||||
|
|
||||||
const Product = model.define("product", {
|
const Product = model.define("product", {
|
||||||
id: model.id(),
|
id: model.id().primaryKey(),
|
||||||
order: model.manyToMany(() => Order),
|
order: model.manyToMany(() => Order),
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
@@ -132,14 +132,14 @@ export const relationNameHighlights = [
|
|||||||
import { model } from "@medusajs/utils"
|
import { model } from "@medusajs/utils"
|
||||||
|
|
||||||
const User = model.define("user", {
|
const User = model.define("user", {
|
||||||
id: model.id(),
|
id: model.id().primaryKey(),
|
||||||
email: model.hasOne(() => Email, {
|
email: model.hasOne(() => Email, {
|
||||||
mappedBy: "owner",
|
mappedBy: "owner",
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
const Email = model.define("email", {
|
const Email = model.define("email", {
|
||||||
id: model.id(),
|
id: model.id().primaryKey(),
|
||||||
owner: model.belongsTo(() => User, {
|
owner: model.belongsTo(() => User, {
|
||||||
mappedBy: "email",
|
mappedBy: "email",
|
||||||
}),
|
}),
|
||||||
@@ -170,7 +170,7 @@ export const highlights = [
|
|||||||
import { model } from "@medusajs/utils"
|
import { model } from "@medusajs/utils"
|
||||||
|
|
||||||
const Store = model.define("store", {
|
const Store = model.define("store", {
|
||||||
id: model.id(),
|
id: model.id().primaryKey(),
|
||||||
products: model.hasMany(() => Product),
|
products: model.hasMany(() => Product),
|
||||||
})
|
})
|
||||||
.cascades({
|
.cascades({
|
||||||
@@ -178,7 +178,7 @@ const Store = model.define("store", {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const Product = model.define("product", {
|
const Product = model.define("product", {
|
||||||
id: model.id(),
|
id: model.id().primaryKey(),
|
||||||
store: model.belongsTo(() => Store, {
|
store: model.belongsTo(() => Store, {
|
||||||
mappedBy: "products",
|
mappedBy: "products",
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
export const metadata = {
|
|
||||||
title: `${pageNumber} Soft-Deletable Data Models`,
|
|
||||||
}
|
|
||||||
|
|
||||||
# {metadata.title}
|
|
||||||
|
|
||||||
In this chapter, you’ll learn about soft-deletable data models.
|
|
||||||
|
|
||||||
## What is a Soft-Deletable Data Model?
|
|
||||||
|
|
||||||
A soft-deletable data model is a model that has a `deleted_at` `dateTime` property.
|
|
||||||
|
|
||||||
When a record of the data model is deleted, this field is set to the current date, marking it as deleted.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Configure Data Model Soft-Deletion
|
|
||||||
|
|
||||||
By default, all data models have a `deleted_at` property and are considered soft-deletable.
|
|
||||||
@@ -30,7 +30,7 @@ For example, create the file `src/modules/hello/models/my-custom.ts` with the fo
|
|||||||
import { model } from "@medusajs/utils"
|
import { model } from "@medusajs/utils"
|
||||||
|
|
||||||
const MyCustom = model.define("my_custom", {
|
const MyCustom = model.define("my_custom", {
|
||||||
id: model.id(),
|
id: model.id().primaryKey(),
|
||||||
name: model.text(),
|
name: model.text(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -135,25 +135,25 @@ export const sidebar = sidebarAttachHrefCommonOptions(
|
|||||||
path: "/advanced-development/data-models/property-types",
|
path: "/advanced-development/data-models/property-types",
|
||||||
title: "Property Types",
|
title: "Property Types",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: "/advanced-development/data-models/configure-properties",
|
|
||||||
title: "Configure Properties",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: "/advanced-development/data-models/primary-key",
|
path: "/advanced-development/data-models/primary-key",
|
||||||
title: "Primary Key",
|
title: "Primary Key",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/advanced-development/data-models/default-properties",
|
||||||
|
title: "Default Properties",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/advanced-development/data-models/configure-properties",
|
||||||
|
title: "Configure Properties",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/advanced-development/data-models/relationships",
|
path: "/advanced-development/data-models/relationships",
|
||||||
title: "Relationships",
|
title: "Relationships",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/advanced-development/data-models/indexes",
|
path: "/advanced-development/data-models/index",
|
||||||
title: "Data Model Index",
|
title: "Index",
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/advanced-development/data-models/soft-deletable",
|
|
||||||
title: "Soft-Deletable Models",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/advanced-development/data-models/searchable-property",
|
path: "/advanced-development/data-models/searchable-property",
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ The rest of this guide uses this `Manager` data model as an example:
|
|||||||
import { model } from "@medusajs/utils"
|
import { model } from "@medusajs/utils"
|
||||||
|
|
||||||
const Manager = model.define("manager", {
|
const Manager = model.define("manager", {
|
||||||
id: model.id(),
|
id: model.id().primaryKey(),
|
||||||
firstName: model.text(),
|
firstName: model.text(),
|
||||||
lastName: model.text(),
|
lastName: model.text(),
|
||||||
email: model.text(),
|
email: model.text(),
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ Module Relationships is coming soon.
|
|||||||
import { model } from "@medusajs/utils"
|
import { model } from "@medusajs/utils"
|
||||||
|
|
||||||
const Company = model.define("company", {
|
const Company = model.define("company", {
|
||||||
id: model.id(),
|
id: model.id().primaryKey(),
|
||||||
name: model.text(),
|
name: model.text(),
|
||||||
city: model.text(),
|
city: model.text(),
|
||||||
country_code: model.text(),
|
country_code: model.text(),
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ export const restockModelHighlights = [
|
|||||||
import { model } from "@medusajs/utils"
|
import { model } from "@medusajs/utils"
|
||||||
|
|
||||||
const RestockNotification = model.define("restock_notification", {
|
const RestockNotification = model.define("restock_notification", {
|
||||||
id: model.id(),
|
id: model.id().primaryKey(),
|
||||||
email: model.text(),
|
email: model.text(),
|
||||||
variant_id: model.text(),
|
variant_id: model.text(),
|
||||||
sales_channel_id: model.text(),
|
sales_channel_id: model.text(),
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ Module Relationships is coming soon.
|
|||||||
import { MediaType } from "../../../types/digital-product/product-media"
|
import { MediaType } from "../../../types/digital-product/product-media"
|
||||||
|
|
||||||
const ProductMedia = model.define("product_media", {
|
const ProductMedia = model.define("product_media", {
|
||||||
id: model.id(),
|
id: model.id().primaryKey(),
|
||||||
name: model.text(),
|
name: model.text(),
|
||||||
type: model.enum(Object.values(MediaType)),
|
type: model.enum(Object.values(MediaType)),
|
||||||
fileKey: model.text(),
|
fileKey: model.text(),
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ Module Relationships is coming soon.
|
|||||||
import { model } from "@medusajs/utils"
|
import { model } from "@medusajs/utils"
|
||||||
|
|
||||||
const StoreUser = model.define("store_user", {
|
const StoreUser = model.define("store_user", {
|
||||||
id: model.id(),
|
id: model.id().primaryKey(),
|
||||||
store_id: model.text(),
|
store_id: model.text(),
|
||||||
user_id: model.text(),
|
user_id: model.text(),
|
||||||
})
|
})
|
||||||
@@ -87,7 +87,7 @@ Module Relationships is coming soon.
|
|||||||
import { model } from "@medusajs/utils"
|
import { model } from "@medusajs/utils"
|
||||||
|
|
||||||
const StoreProduct = model.define("store_user", {
|
const StoreProduct = model.define("store_user", {
|
||||||
id: model.id(),
|
id: model.id().primaryKey(),
|
||||||
store_id: model.text(),
|
store_id: model.text(),
|
||||||
product_id: model.text(),
|
product_id: model.text(),
|
||||||
})
|
})
|
||||||
@@ -105,7 +105,7 @@ Module Relationships is coming soon.
|
|||||||
import { model } from "@medusajs/utils"
|
import { model } from "@medusajs/utils"
|
||||||
|
|
||||||
const StoreOrder = model.define("store_user", {
|
const StoreOrder = model.define("store_user", {
|
||||||
id: model.id(),
|
id: model.id().primaryKey(),
|
||||||
store_id: model.text(),
|
store_id: model.text(),
|
||||||
order_id: model.text(),
|
order_id: model.text(),
|
||||||
parent_order_id: model.text(),
|
parent_order_id: model.text(),
|
||||||
|
|||||||
Reference in new issue
Block a user