docs: improve database operations docs + added data model repository reference (#12273)
* some changes * docs: improve database operations docs + add data model repository reference * regenerate
This commit is contained in:
1 parent
876a14eb98
commit
54bae210b8
21 files changed
+20651
-17089
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import { CodeTabs, CodeTab } from "docs-ui"
|
||||
import { CodeTabs, CodeTab, TypeList } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Perform Database Operations in a Service`,
|
||||
@@ -78,7 +78,18 @@ Refer to [MikroORM's reference](https://mikro-orm.io/api/knex/class/EntityManage
|
||||
|
||||
---
|
||||
|
||||
## Execute Operations in Transactions
|
||||
## Perform Database Operations
|
||||
|
||||
There are two ways to perform database operations in transactional methods:
|
||||
|
||||
1. Using the [data model repositories](#perform-database-operations-with-data-model-repositories) in your module.
|
||||
2. Using the [transactional entity manager](#perform-database-operations-with-the-transactional-entity-manager) injected into the method's shared context.
|
||||
|
||||
For both approaches, you must wrap the method performing the database operations in a transaction.
|
||||
|
||||
### Wrap Database Operations in Transactions
|
||||
|
||||
When performing database operations without using the [Service Factory](../service-factory/page.mdx), you must wrap the method performing the database operations in a transaction.
|
||||
|
||||
To wrap database operations in a transaction, you create two methods:
|
||||
|
||||
@@ -92,9 +103,7 @@ For example:
|
||||
export const opHighlights = [
|
||||
["11", "InjectTransactionManager", "A decorator that injects the a transactional entity manager into the `sharedContext` parameter."],
|
||||
["17", "MedusaContext", "A decorator to use Medusa's shared context."],
|
||||
["20", "nativeUpdate", "Update a record."],
|
||||
["31", "execute", "Retrieve the updated record."],
|
||||
["38", "InjectManager", "A decorator that injects a forked entity manager into the context."],
|
||||
["24", "InjectManager", "A decorator that injects a forked entity manager into the context."],
|
||||
]
|
||||
|
||||
```ts highlights={opHighlights}
|
||||
@@ -106,6 +115,273 @@ import {
|
||||
import { Context } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
|
||||
class BlogModuleService {
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async update_(
|
||||
input: {
|
||||
id: string,
|
||||
name: string
|
||||
},
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const transactionManager = sharedContext?.transactionManager
|
||||
|
||||
// TODO: update the record
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async update(
|
||||
input: {
|
||||
id: string,
|
||||
name: string
|
||||
},
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
) {
|
||||
return await this.update_(input, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `BlogModuleService` has two methods:
|
||||
|
||||
- A protected `update_` that performs the database operations inside a transaction.
|
||||
- A public `update` that executes the transactional protected method.
|
||||
|
||||
You can then perform in the transactional method the database operations either using the [data model repository](#perform-database-operations-with-data-model-repositories) or the [transactional entity manager](#perform-database-operations-with-the-transactional-entity-manager).
|
||||
|
||||
#### Why Wrap a Transactional Method
|
||||
|
||||
The variables in the transactional method (such as `update_`) hold values that are uncommitted to the database. They're only committed once the method finishes execution.
|
||||
|
||||
So, if in your method you perform database operations, then use their result to perform other actions, such as connecting to a third-party service, you'll be working with uncommitted data.
|
||||
|
||||
By placing only the database operations in a method that has the `InjectTransactionManager` and using it in a wrapper method, the wrapper method receives the committed result of the transactional method.
|
||||
|
||||
<Note title="Optimization Tip">
|
||||
|
||||
This is also useful if you perform heavy data normalization outside of the database operations. In that case, you don't hold the transaction for a longer time than needed.
|
||||
|
||||
</Note>
|
||||
|
||||
For example, the `update` method may call other methods than `update_` to perform other actions:
|
||||
|
||||
```ts
|
||||
// other imports...
|
||||
import {
|
||||
InjectManager,
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
|
||||
class BlogModuleService {
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async update_(
|
||||
// ...
|
||||
): Promise<any> {
|
||||
// ...
|
||||
}
|
||||
@InjectManager()
|
||||
async update(
|
||||
input: {
|
||||
id: string,
|
||||
name: string
|
||||
},
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
) {
|
||||
const newData = await this.update_(input, sharedContext)
|
||||
|
||||
// example method that sends data to another system
|
||||
await this.sendNewDataToSystem(newData)
|
||||
|
||||
return newData
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In this case, only the `update_` method is wrapped in a transaction. The returned value `newData` holds the committed result, which can be used for other operations, such as passed to a `sendNewDataToSystem` method.
|
||||
|
||||
#### Using Methods in Transactional Methods
|
||||
|
||||
If your protected transactional method uses other methods that accept a Medusa context, pass the shared context to those methods.
|
||||
|
||||
For example:
|
||||
|
||||
export const anotherMethodHighlights = [
|
||||
["26", "sharedContext", "Pass the context to the other transactional method."]
|
||||
]
|
||||
|
||||
```ts highlights={anotherMethodHighlights}
|
||||
// other imports...
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
|
||||
class BlogModuleService {
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async anotherMethod(
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
) {
|
||||
// ...
|
||||
}
|
||||
|
||||
@InjectTransactionManager()
|
||||
protected async update_(
|
||||
input: {
|
||||
id: string,
|
||||
name: string
|
||||
},
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
this.anotherMethod(sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You use the `anotherMethod` transactional method in the `update_` transactional method, so you pass it the shared context.
|
||||
|
||||
The `anotherMethod` now runs in the same transaction as the `update_` method.
|
||||
|
||||
### Perform Database Operations with Data Model Repositories
|
||||
|
||||
For every data model in your module, Medusa generates a data model repository that has methods to perform database operations.
|
||||
|
||||
For example, if your module has a `Post` model, it has a `postRepository` in the container.
|
||||
|
||||
The data model repository is a wrapper around the [entity manager](https://mikro-orm.io/api/knex/class/EntityManager) that provides a higher-level API for performing database operations.
|
||||
|
||||
<Note>
|
||||
|
||||
To use the low-level entity manager, use the [transactional entity manager](#perform-database-operations-with-the-transactional-entity-manager) instead.
|
||||
|
||||
</Note>
|
||||
|
||||
#### Resolve Data Model Repository
|
||||
|
||||
When the Medusa application injects a data model repository into a module's container, it formats the registration name by:
|
||||
|
||||
- Taking the data model's name that's passed as the first parameter of `model.define`
|
||||
- Lower-casing the first character
|
||||
- Suffixing the result with `Repository`.
|
||||
|
||||
For example:
|
||||
|
||||
- `Post` model: `postRepository`
|
||||
- `My_Custom` model: `my_CustomRepository`
|
||||
|
||||
So, to resolve a data model repository from a module's container, pass the expected registration name of the repository in the first parameter of the module's constructor (the container).
|
||||
|
||||
For example:
|
||||
|
||||
<CodeTabs group="service-type">
|
||||
<CodeTab label="Extending Service Factory" value="service-factory">
|
||||
|
||||
export const serviceFactoryRepoHighlights = [
|
||||
["20", "postRepository", "Resolve the data model repository of the `Post` model."],
|
||||
]
|
||||
|
||||
```ts highlights={serviceFactoryRepoHighlights}
|
||||
import { MedusaService } from "@medusajs/framework/utils"
|
||||
import { InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import Post from "./models/post"
|
||||
|
||||
type Post = InferTypeOf<typeof Post>
|
||||
|
||||
type InjectedDependencies = {
|
||||
postRepository: DAL.RepositoryService<Post>
|
||||
}
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
protected postRepository_: DAL.RepositoryService<Post>
|
||||
|
||||
constructor({
|
||||
postRepository
|
||||
}: InjectedDependencies) {
|
||||
super(...arguments)
|
||||
this.postRepository_ = postRepository
|
||||
}
|
||||
}
|
||||
|
||||
export default BlogModuleService
|
||||
```
|
||||
</CodeTab>
|
||||
<CodeTab label="Without Service Factory" value="no-service-factory">
|
||||
|
||||
export const noServiceFactoryRepoHighlights = [
|
||||
["17", "postRepository", "Resolve the data model repository of the `Post` model."],
|
||||
]
|
||||
|
||||
```ts highlights={noServiceFactoryRepoHighlights}
|
||||
import { InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import Post from "./models/post"
|
||||
|
||||
type Post = InferTypeOf<typeof Post>
|
||||
|
||||
type InjectedDependencies = {
|
||||
postRepository: DAL.RepositoryService<Post>
|
||||
}
|
||||
|
||||
class BlogModuleService {
|
||||
protected postRepository_: DAL.RepositoryService<Post>
|
||||
|
||||
constructor({
|
||||
postRepository
|
||||
}: InjectedDependencies) {
|
||||
super(...arguments)
|
||||
this.postRepository_ = postRepository
|
||||
}
|
||||
}
|
||||
|
||||
export default BlogModuleService
|
||||
```
|
||||
|
||||
</CodeTab>
|
||||
</CodeTabs>
|
||||
|
||||
You can then use the data model repository in your service to perform database operations.
|
||||
|
||||
#### Data Model Repository Methods
|
||||
|
||||
A data model repository has methods that allows you to create, update, and delete records, among other operations.
|
||||
|
||||
To learn about the methods available in a data model repository, refer to the [Data Model Repository](!resources!/data-model-repository-reference) reference.
|
||||
|
||||
### Perform Database Operations with the Transactional Entity Manager
|
||||
|
||||
Your transactional method can use the transactional entity manager injected into the method's shared context to perform database operations. It's an instance of the [MikroORM EntityManager](https://mikro-orm.io/api/knex/class/EntityManager) class.
|
||||
|
||||
<Note>
|
||||
|
||||
To use an easier higher-level API focused on each data model, use the [data model repository](#perform-database-operations-with-data-model-repositories) instead.
|
||||
|
||||
</Note>
|
||||
|
||||
For example:
|
||||
|
||||
export const transactionalEntityManagerHighlights = [
|
||||
["19", "transactionManager", "Use the transactional entity manager injected\ninto the `sharedContext` parameter."],
|
||||
["20", "nativeUpdate", "Perform a native update operation."],
|
||||
["31", "execute", "Perform a native query operation."],
|
||||
]
|
||||
|
||||
```ts highlights={transactionalEntityManagerHighlights}
|
||||
import {
|
||||
InjectManager,
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
|
||||
class BlogModuleService {
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
@@ -148,119 +424,15 @@ class BlogModuleService {
|
||||
}
|
||||
```
|
||||
|
||||
The `BlogModuleService` has two methods:
|
||||
The `update_` method uses the transactional entity manager injected into the `sharedContext.transactionManager` property to perform the database operations.
|
||||
|
||||
- A protected `update_` that performs the database operations inside a transaction.
|
||||
- A public `update` that executes the transactional protected method.
|
||||
|
||||
The shared context's `transactionManager` property holds the transactional entity manager (injected by `InjectTransactionManager`) that you use to perform database operations.
|
||||
|
||||
<Note>
|
||||
|
||||
Refer to [MikroORM's reference](https://mikro-orm.io/api/knex/class/EntityManager) for a full list of the entity manager's methods.
|
||||
|
||||
</Note>
|
||||
|
||||
### Why Wrap a Transactional Method
|
||||
|
||||
The variables in the transactional method (for example, `update_`) hold values that are uncommitted to the database. They're only committed once the method finishes execution.
|
||||
|
||||
So, if in your method you perform database operations, then use their result to perform other actions, such as connecting to a third-party service, you'll be working with uncommitted data.
|
||||
|
||||
By placing only the database operations in a method that has the `InjectTransactionManager` and using it in a wrapper method, the wrapper method receives the committed result of the transactional method.
|
||||
|
||||
<Note title="Optimization Tip">
|
||||
|
||||
This is also useful if you perform heavy data normalization outside of the database operations. In that case, you don't hold the transaction for a longer time than needed.
|
||||
|
||||
</Note>
|
||||
|
||||
For example, the `update` method could be changed to the following:
|
||||
|
||||
```ts
|
||||
// other imports...
|
||||
import {
|
||||
InjectManager,
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
|
||||
class BlogModuleService {
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async update_(
|
||||
// ...
|
||||
): Promise<any> {
|
||||
// ...
|
||||
}
|
||||
@InjectManager()
|
||||
async update(
|
||||
input: {
|
||||
id: string,
|
||||
name: string
|
||||
},
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
) {
|
||||
const newData = await this.update_(input, sharedContext)
|
||||
|
||||
// example method that sends data to another system
|
||||
await this.sendNewDataToSystem(newData)
|
||||
|
||||
return newData
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In this case, only the `update_` method is wrapped in a transaction. The returned value `newData` holds the committed result, which can be used for other operations, such as passed to a `sendNewDataToSystem` method.
|
||||
|
||||
### Using Methods in Transactional Methods
|
||||
|
||||
If your transactional method uses other methods that accept a Medusa context, pass the shared context to those methods.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
// other imports...
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
|
||||
class BlogModuleService {
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async anotherMethod(
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
) {
|
||||
// ...
|
||||
}
|
||||
|
||||
@InjectTransactionManager()
|
||||
protected async update_(
|
||||
input: {
|
||||
id: string,
|
||||
name: string
|
||||
},
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
this.anotherMethod(sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You use the `anotherMethod` transactional method in the `update_` transactional method, so you pass it the shared context.
|
||||
|
||||
The `anotherMethod` now runs in the same transaction as the `update_` method.
|
||||
Find all available methods in the [MikroORM EntityManager](https://mikro-orm.io/api/knex/class/EntityManager) reference.
|
||||
|
||||
---
|
||||
|
||||
## Configure Transactions
|
||||
## Configure Transactions with the Base Repository
|
||||
|
||||
To configure the transaction, such as its [isolation level](https://www.postgresql.org/docs/current/transaction-iso.html), use the `baseRepository` dependency registered in your module's container.
|
||||
To configure the transaction, such as its [isolation level](https://www.postgresql.org/docs/current/transaction-iso.html), use the `baseRepository` class registered in your module's container.
|
||||
|
||||
The `baseRepository` is an instance of a repository class that provides methods to create transactions, run database operations, and more.
|
||||
|
||||
@@ -271,7 +443,11 @@ For example, resolve the `baseRepository` in your service's constructor:
|
||||
<CodeTabs group="service-type">
|
||||
<CodeTab label="Extending Service Factory" value="service-factory">
|
||||
|
||||
```ts highlights={[["14"]]}
|
||||
export const baseRepoHighlights = [
|
||||
["16", "baseRepository", "Resolve the base repository."],
|
||||
]
|
||||
|
||||
```ts highlights={baseRepoHighlights}
|
||||
import { MedusaService } from "@medusajs/framework/utils"
|
||||
import Post from "./models/post"
|
||||
import { DAL } from "@medusajs/framework/types"
|
||||
@@ -293,10 +469,15 @@ class BlogModuleService extends MedusaService({
|
||||
|
||||
export default BlogModuleService
|
||||
```
|
||||
|
||||
</CodeTab>
|
||||
<CodeTab label="Without Service Factory" value="no-service-factory">
|
||||
|
||||
```ts highlights={[["10"]]}
|
||||
export const noServiceFactoryBaseRepoHighlights = [
|
||||
["11", "baseRepository", "Resolve the base repository."],
|
||||
]
|
||||
|
||||
```ts highlights={noServiceFactoryBaseRepoHighlights}
|
||||
import { DAL } from "@medusajs/framework/types"
|
||||
|
||||
type InjectedDependencies = {
|
||||
@@ -317,7 +498,7 @@ export default BlogModuleService
|
||||
</CodeTab>
|
||||
</CodeTabs>
|
||||
|
||||
Then, add the following method that uses it:
|
||||
Then, use it in the service's transactional methods:
|
||||
|
||||
export const repoHighlights = [
|
||||
["20", "transaction", "Wrap the function parameter in a transaction."]
|
||||
@@ -399,7 +580,7 @@ The second parameter of the `baseRepository_.transaction` method is an object of
|
||||
|
||||
1. `transaction`: Set the transactional entity manager passed to the function. You must provide this option as explained in the previous section.
|
||||
|
||||
```ts highlights={[["16"]]}
|
||||
```ts highlights={[["24"]]}
|
||||
// other imports...
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import {
|
||||
@@ -407,7 +588,6 @@ import {
|
||||
MedusaContext,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
|
||||
class BlogModuleService {
|
||||
// ...
|
||||
@@ -438,7 +618,7 @@ class BlogModuleService {
|
||||
- `repeatable read`
|
||||
- `serializable`
|
||||
|
||||
```ts highlights={[["19"]]}
|
||||
```ts highlights={[["25"]]}
|
||||
// other imports...
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
@@ -473,7 +653,7 @@ class BlogModuleService {
|
||||
3. `enableNestedTransactions`: (default: `false`) whether to allow using nested transactions.
|
||||
- If `transaction` is provided and this is disabled, the manager in `transaction` is re-used.
|
||||
|
||||
```ts highlights={[["16"]]}
|
||||
```ts highlights={[["24"]]}
|
||||
// other imports...
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
|
||||
@@ -68,7 +68,7 @@ export const generatedEditDates = {
|
||||
"app/learn/fundamentals/module-links/directions/page.mdx": "2025-03-17T12:52:06.161Z",
|
||||
"app/learn/fundamentals/module-links/page.mdx": "2025-04-17T08:50:17.036Z",
|
||||
"app/learn/fundamentals/module-links/query/page.mdx": "2025-04-18T11:13:02.240Z",
|
||||
"app/learn/fundamentals/modules/db-operations/page.mdx": "2025-03-21T09:21:46.901Z",
|
||||
"app/learn/fundamentals/modules/db-operations/page.mdx": "2025-04-23T14:24:37.910Z",
|
||||
"app/learn/fundamentals/modules/multiple-services/page.mdx": "2025-03-18T15:11:44.632Z",
|
||||
"app/learn/fundamentals/modules/page.mdx": "2025-03-18T07:51:09.049Z",
|
||||
"app/learn/debugging-and-testing/instrumentation/page.mdx": "2025-02-24T08:12:53.132Z",
|
||||
|
||||
+17143
-16966
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,85 @@
|
||||
---
|
||||
sidebar_label: "create"
|
||||
---
|
||||
|
||||
import { TypeList } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `create Method - Data Model Repository Reference`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
The `create` method of a data model repository creates one or more records of the data model.
|
||||
|
||||
<Note>
|
||||
|
||||
This reference assumes you've already resolved the data model repository, as explained in the [Data Model Repository Reference](../../page.mdx) documentation.
|
||||
|
||||
</Note>
|
||||
|
||||
## `create` Parameters
|
||||
|
||||
<TypeList
|
||||
types={[
|
||||
{
|
||||
type: "`array`",
|
||||
name: "data",
|
||||
description: "An array of objects to create. The shape of the objects is the same as the shape of the data model.",
|
||||
required: true,
|
||||
}
|
||||
]}
|
||||
sectionTitle="create Parameters"
|
||||
/>
|
||||
|
||||
---
|
||||
|
||||
## Create Records
|
||||
|
||||
```ts
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const posts = await this.postRepository_.create([
|
||||
{
|
||||
title: "My Post",
|
||||
content: "This is a post",
|
||||
author_id: "01JSGRGQ8S61SR0Y7VCRV8FH66",
|
||||
}
|
||||
])
|
||||
|
||||
return posts
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
The `create` method accepts an array of objects, each representing a record to create. The shape of the objects is the same as the shape of the data model.
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns an array of the created records.
|
||||
@@ -0,0 +1,138 @@
|
||||
---
|
||||
sidebar_label: "delete"
|
||||
---
|
||||
|
||||
import { TypeList } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `delete Method - Data Model Repository Reference`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
The `delete` method of a data model repository deletes one or more records of the data model.
|
||||
|
||||
<Note>
|
||||
|
||||
This reference assumes you've already resolved the data model repository, as explained in the [Data Model Repository Reference](../../page.mdx) documentation.
|
||||
|
||||
</Note>
|
||||
|
||||
## `delete` Parameters
|
||||
|
||||
<TypeList
|
||||
types={[
|
||||
{
|
||||
type: "`object`",
|
||||
name: "filters",
|
||||
description: "The filters to select the records to delete. The keys are the property names of the data model, and the values are the values to filter by.",
|
||||
required: true,
|
||||
}
|
||||
]}
|
||||
sectionTitle="delete Parameters"
|
||||
/>
|
||||
---
|
||||
|
||||
## Delete Record by ID
|
||||
|
||||
```ts
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const deletedIds = await this.postRepository_.delete({
|
||||
id
|
||||
})
|
||||
|
||||
return deletedIds
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
The `delete` method accepts an object of filters to select the records to delete.
|
||||
|
||||
In the example above, you pass an object with the `id` property to delete a record by its ID.
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns an array of strings, each representing the ID of a deleted record.
|
||||
|
||||
---
|
||||
|
||||
## Delete Records by Filters
|
||||
|
||||
```ts
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const deletedIds = await this.postRepository_.delete({
|
||||
title: "My Post"
|
||||
})
|
||||
|
||||
return deletedIds
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
Since the `delete` method accepts an object of filters, you can pass any property of the data model as a filter.
|
||||
|
||||
In the example above, you pass an object with the `title` property to delete all records with that title.
|
||||
|
||||
<Note>
|
||||
|
||||
Find examples of different filters in the [Filter Records](../../tips/filtering/page.mdx) documentation.
|
||||
|
||||
</Note>
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns an array of strings, each representing the ID of a deleted record.
|
||||
@@ -0,0 +1,460 @@
|
||||
---
|
||||
sidebar_label: "find"
|
||||
---
|
||||
|
||||
import { TypeList } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `find Method - Data Model Repository Reference`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
The `find` method of a data model repository retrieves a list of records.
|
||||
|
||||
<Note>
|
||||
|
||||
This reference assumes you've already resolved the data model repository, as explained in the [Data Model Repository Reference](../../page.mdx) documentation.
|
||||
|
||||
</Note>
|
||||
|
||||
## `find` Parameters
|
||||
|
||||
<TypeList
|
||||
types={[
|
||||
{
|
||||
type: "`object`",
|
||||
name: "data",
|
||||
description: "Options to filter and configure the query to retrieve the records.",
|
||||
required: false,
|
||||
children: [
|
||||
{
|
||||
type: "`object`",
|
||||
name: "where",
|
||||
description: "Filters to apply to the query. The keys are the property names of the data model, and the values are the values to filter by.",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
type: "`object`",
|
||||
name: "options",
|
||||
description: "Options to configure the query.",
|
||||
required: false,
|
||||
children: [
|
||||
{
|
||||
type: "`string[]`",
|
||||
name: "populate",
|
||||
description: "An array of relation names to retrieve.",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
type: "`string[]`",
|
||||
name: "fields",
|
||||
description: "An array of property names to retrieve.",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
type: "`number`",
|
||||
name: "limit",
|
||||
description: "The number of records to retrieve.",
|
||||
required: false,
|
||||
defaultValue: "`15`",
|
||||
},
|
||||
{
|
||||
type: "`number`",
|
||||
name: "offset",
|
||||
description: "The number of records to skip before the retrieved records.",
|
||||
required: false,
|
||||
defaultValue: "`0`",
|
||||
},
|
||||
{
|
||||
type: "`object`",
|
||||
name: "orderBy",
|
||||
description: "An object whose keys are the property names of the data model, and values are the sorting order.",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
type: "`string | string[]`",
|
||||
name: "groupBy",
|
||||
description: "Group the records by one or more properties.",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
type: "`select-in` \\| `joined`",
|
||||
name: "strategy",
|
||||
description: "The strategy to use to retrieve the records. Learn more in the [MikroORM documentation](https://mikro-orm.io/docs/loading-strategies). If you don't specify a strategy and you specify the `limit` or `offset` options, the default strategy is `select-in`. Otherwise, the default strategy is `joined`.",
|
||||
required: false,
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]}
|
||||
sectionTitle="find Parameters"
|
||||
openedLevel={1}
|
||||
/>
|
||||
|
||||
---
|
||||
|
||||
## Retrieve List of Records
|
||||
|
||||
To retrieve a list of records matching a set of filters, use the `find` method of the data model repository:
|
||||
|
||||
```ts title="src/modules/blog/service.ts"
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const posts = await this.postRepository_.find()
|
||||
|
||||
return posts
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Returns
|
||||
|
||||
By default, the method returns an array of the first `15` records of the data model.
|
||||
|
||||
---
|
||||
|
||||
## Filter Records
|
||||
|
||||
You can filter the retrieved records by passing filters as a first parameter of the `find` method:
|
||||
|
||||
```ts title="src/modules/blog/service.ts"
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string[],
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const posts = await this.postRepository_.find({
|
||||
where: {
|
||||
id,
|
||||
},
|
||||
})
|
||||
|
||||
return posts
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
The first object parameter is an object that has a `where` property used to apply filters. `where`'s value is an object whose keys are the property names of the data model, and values are the values to filter by.
|
||||
|
||||
In the example above, you filter the retrieved posts by their `id` property.
|
||||
|
||||
<Note>
|
||||
|
||||
Refer to the [Filtering](../../tips/filtering/page.mdx) reference for more information on how to filter records.
|
||||
|
||||
</Note>
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns an array of the first `15` records matching the filters.
|
||||
|
||||
---
|
||||
|
||||
## Retrieve Relations
|
||||
|
||||
<Note>
|
||||
|
||||
This applies to relations between data models of the same module. To retrieve linked records of different modules, use [Query](!docs!/learn/fundamentals/module-links/query).
|
||||
|
||||
</Note>
|
||||
|
||||
```ts title="src/modules/blog/service.ts"
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string[],
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const posts = await this.postRepository_.find({
|
||||
where: {
|
||||
id
|
||||
},
|
||||
options: {
|
||||
populate: ["author"]
|
||||
}
|
||||
})
|
||||
|
||||
return posts
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
The first object parameter of `find` accepts an `option` property, whose value is an object of retrieval options.
|
||||
|
||||
It accepts a `populate` property, whose value is an array of relation names to retrieve.
|
||||
|
||||
In the example above, you retrieve the `author` relation of the posts.
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns an array of the first `15` records. Each record will have the specified relations populated:
|
||||
|
||||
```json title="Example"
|
||||
[
|
||||
{
|
||||
"id": "1",
|
||||
"author": {
|
||||
"id": "1",
|
||||
"name": "John Doe",
|
||||
// ...
|
||||
},
|
||||
// ...
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Select Properties
|
||||
|
||||
```ts title="src/modules/blog/service.ts"
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const posts = await this.postRepository_.find({
|
||||
where: {
|
||||
id
|
||||
},
|
||||
options: {
|
||||
fields: ["title"]
|
||||
}
|
||||
})
|
||||
|
||||
return posts
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
By default, retrieved records have all their properties. The first object parameter of `find` accepts in its `options` property a `fields` property, whose value is an array of property names to retrieve.
|
||||
|
||||
In the example above, you retrieve only the `title` property of the posts.
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns an array of the first `15` records. Each record will have only the specified properties:
|
||||
|
||||
```json title="Example"
|
||||
[
|
||||
{
|
||||
"id": "1",
|
||||
"title": "My first post"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Paginate Relations
|
||||
|
||||
```ts title="src/modules/blog/service.ts"
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const posts = await this.postRepository_.find({
|
||||
where: {
|
||||
id
|
||||
},
|
||||
options: {
|
||||
limit: 10,
|
||||
offset: 10,
|
||||
}
|
||||
})
|
||||
|
||||
return posts
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
By default, the `find` method retrieves the first `15` records.
|
||||
|
||||
To change pagination configurations, you can pass to the first object parameter the `options` property, whose value is an object that accepts the following properties for pagination:
|
||||
|
||||
- `limit`: a number indicating how many records to retrieve. By default, it's `15`.
|
||||
- `offset`: a number indicating how many records to skip before the retrieved records. By default, it's `0`.
|
||||
|
||||
In the example above, you retrieve `10` records, skipping the first `10` records.
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns an array of records. The number of records is less than or equal to `limit`'s value.
|
||||
|
||||
---
|
||||
|
||||
## Sort Records
|
||||
|
||||
```ts title="src/modules/blog/service.ts"
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const posts = await this.postRepository_.find({
|
||||
where: {
|
||||
id
|
||||
},
|
||||
options: {
|
||||
orderBy: {
|
||||
title: "ASC"
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return posts
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
To sort records by one or more properties, the first object parameter of `find` accepts in its `options` property an `orderBy` property. Its value is an object whose keys are the property names of the data model, and values are the sorting order.
|
||||
|
||||
The sorting order can be one of the following:
|
||||
|
||||
- `ASC` to sort by this property in the ascending order.
|
||||
- `DESC` to sort by this property in the descending order.
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns an array of the first `15` records sorted by the specified properties.
|
||||
@@ -0,0 +1,495 @@
|
||||
---
|
||||
sidebar_label: "findAndCount"
|
||||
---
|
||||
|
||||
import { TypeList } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `findAndCount Method - Data Model Repository Reference`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
The `findAndCount` method of a data model repository retrieves a list of records and the total count of records that match the query.
|
||||
|
||||
<Note>
|
||||
|
||||
This reference assumes you've already resolved the data model repository, as explained in the [Data Model Repository Reference](../../page.mdx) documentation.
|
||||
|
||||
</Note>
|
||||
|
||||
## `findAndCount` Parameters
|
||||
|
||||
<TypeList
|
||||
types={[
|
||||
{
|
||||
type: "`object`",
|
||||
name: "data",
|
||||
description: "Options to filter and configure the query to retrieve the records.",
|
||||
required: false,
|
||||
children: [
|
||||
{
|
||||
type: "`object`",
|
||||
name: "where",
|
||||
description: "Filters to apply to the query. The keys are the property names of the data model, and the values are the values to filter by.",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
type: "`object`",
|
||||
name: "options",
|
||||
description: "Options to configure the query.",
|
||||
required: false,
|
||||
children: [
|
||||
{
|
||||
type: "`string[]`",
|
||||
name: "populate",
|
||||
description: "An array of relation names to retrieve.",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
type: "`string[]`",
|
||||
name: "fields",
|
||||
description: "An array of property names to retrieve.",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
type: "`number`",
|
||||
name: "limit",
|
||||
description: "The number of records to retrieve.",
|
||||
required: false,
|
||||
defaultValue: "`15`",
|
||||
},
|
||||
{
|
||||
type: "`number`",
|
||||
name: "offset",
|
||||
description: "The number of records to skip before the retrieved records.",
|
||||
required: false,
|
||||
defaultValue: "`0`",
|
||||
},
|
||||
{
|
||||
type: "`object`",
|
||||
name: "orderBy",
|
||||
description: "An object whose keys are the property names of the data model, and values are the sorting order.",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
type: "`string | string[]`",
|
||||
name: "groupBy",
|
||||
description: "Group the records by one or more properties.",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
type: "`select-in` \\| `joined`",
|
||||
name: "strategy",
|
||||
description: "The strategy to use to retrieve the records. Learn more in the [MikroORM documentation](https://mikro-orm.io/docs/loading-strategies). If you don't specify a strategy and you specify the `limit` or `offset` options, the default strategy is `select-in`. Otherwise, the default strategy is `joined`.",
|
||||
required: false,
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]}
|
||||
sectionTitle="findAndCount Parameters"
|
||||
openedLevel={1}
|
||||
/>
|
||||
|
||||
---
|
||||
|
||||
## Retrieve List of Records
|
||||
|
||||
To retrieve a list of records matching a set of filters, use the `findAndCount` method of the data model repository:
|
||||
|
||||
```ts title="src/modules/blog/service.ts"
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const [posts, count] = await this.postRepository_.findAndCount()
|
||||
|
||||
return {
|
||||
posts,
|
||||
count
|
||||
}
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns a tuple of two elements:
|
||||
|
||||
- An array of the first `15` records of the data model.
|
||||
- The total count of records that match the query.
|
||||
|
||||
---
|
||||
|
||||
## Filter Records
|
||||
|
||||
You can filter the retrieved records by passing filters as a first parameter of the `findAndCount` method:
|
||||
|
||||
```ts title="src/modules/blog/service.ts"
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string[],
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const [posts, count] = await this.postRepository_.findAndCount({
|
||||
where: {
|
||||
id,
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
posts,
|
||||
count
|
||||
}
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
The first object parameter is an object that has a `where` property used to apply filters. `where`'s value is an object whose keys are the property names of the data model, and values are the values to filter by.
|
||||
|
||||
In the example above, you filter the retrieved posts by their `id` property.
|
||||
|
||||
<Note>
|
||||
|
||||
Refer to the [Filtering](../../tips/filtering/page.mdx) reference for more information on how to filter records.
|
||||
|
||||
</Note>
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns a tuple of two elements:
|
||||
|
||||
- An array of the first `15` records matching the filters.
|
||||
- The total count of records that match the query.
|
||||
|
||||
---
|
||||
|
||||
## Retrieve Relations
|
||||
|
||||
<Note>
|
||||
|
||||
This applies to relations between data models of the same module. To retrieve linked records of different modules, use [Query](!docs!/learn/fundamentals/module-links/query).
|
||||
|
||||
</Note>
|
||||
|
||||
```ts title="src/modules/blog/service.ts"
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string[],
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const [posts, count] = await this.postRepository_.findAndCount({
|
||||
where: {
|
||||
id
|
||||
},
|
||||
options: {
|
||||
populate: ["author"]
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
posts,
|
||||
count
|
||||
}
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
The first object parameter of `findAndCount` accepts an `options` property, whose value is an object of retrieval options.
|
||||
|
||||
It accepts a `populate` property, whose value is an array of relation names to retrieve.
|
||||
|
||||
In the example above, you retrieve the `author` relation of the posts.
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns a tuple of two elements:
|
||||
|
||||
- An array of the first `15` records.
|
||||
- The total count of records that match the query.
|
||||
|
||||
Each record in the array will have the specified relations populated:
|
||||
|
||||
```json title="Example"
|
||||
[
|
||||
{
|
||||
"id": "1",
|
||||
"author": {
|
||||
"id": "1",
|
||||
"name": "John Doe",
|
||||
// ...
|
||||
},
|
||||
// ...
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Select Properties
|
||||
|
||||
```ts title="src/modules/blog/service.ts"
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const [posts, count] = await this.postRepository_.findAndCount({
|
||||
where: {
|
||||
id
|
||||
},
|
||||
options: {
|
||||
fields: ["title"]
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
posts,
|
||||
count
|
||||
}
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
By default, retrieved records have all their properties. The first object parameter of `findAndCount` accepts in its `options` property a `fields` property, whose value is an array of property names to retrieve.
|
||||
|
||||
In the example above, you retrieve only the `title` property of the posts.
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns a tuple of two elements:
|
||||
|
||||
- An array of the first `15` records.
|
||||
- The total count of records that match the query.
|
||||
|
||||
Each record in the array will have only the specified properties:
|
||||
|
||||
```json title="Example"
|
||||
[
|
||||
{
|
||||
"id": "1",
|
||||
"title": "My first post"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Paginate Relations
|
||||
|
||||
```ts title="src/modules/blog/service.ts"
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const [posts, count] = await this.postRepository_.findAndCount({
|
||||
where: {
|
||||
id
|
||||
},
|
||||
options: {
|
||||
limit: 10,
|
||||
offset: 10,
|
||||
}
|
||||
})
|
||||
|
||||
return posts
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
By default, the `find` method retrieves the first `15` records.
|
||||
|
||||
To change pagination configurations, you can pass to the first object parameter the `options` property, whose value is an object that accepts the following properties for pagination:
|
||||
|
||||
- `limit`: a number indicating how many records to retrieve. By default, it's `15`.
|
||||
- `offset`: a number indicating how many records to skip before the retrieved records. By default, it's `0`.
|
||||
|
||||
In the example above, you retrieve `10` records, skipping the first `10` records.
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns an array of records. The number of records is less than or equal to `limit`'s value.
|
||||
|
||||
---
|
||||
|
||||
## Sort Records
|
||||
|
||||
```ts title="src/modules/blog/service.ts"
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const [posts, count] = await this.postRepository_.findAndCount({
|
||||
where: {
|
||||
id
|
||||
},
|
||||
options: {
|
||||
orderBy: {
|
||||
title: "ASC"
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
posts,
|
||||
count
|
||||
}
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
To sort records by one or more properties, the first object parameter of `findAndCount` accepts in its `options` property an `orderBy` property. Its value is an object whose keys are the property names of the data model, and values are the sorting order.
|
||||
|
||||
The sorting order can be one of the following:
|
||||
|
||||
- `ASC` to sort by this property in the ascending order.
|
||||
- `DESC` to sort by this property in the descending order.
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns a tuple of two elements:
|
||||
|
||||
- An array of the first `15` records.
|
||||
- The total count of records that match the query.
|
||||
@@ -0,0 +1,332 @@
|
||||
---
|
||||
sidebar_label: "restore"
|
||||
---
|
||||
|
||||
import { TypeList } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `restore Method - Data Model Repository Reference`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
The `restore` method of a data model repository restores one or more records of the data model that were previously soft-deleted.
|
||||
|
||||
This means that the `deleted_at` property of the records is set to `null`.
|
||||
|
||||
<Note>
|
||||
|
||||
This reference assumes you've already resolved the data model repository, as explained in the [Data Model Repository Reference](../../page.mdx) documentation.
|
||||
|
||||
</Note>
|
||||
|
||||
## `restore` Parameters
|
||||
|
||||
<TypeList
|
||||
types={[
|
||||
{
|
||||
type: "`string` \\| `string[]` \\| `object`",
|
||||
name: "filters",
|
||||
description: "Can be either the ID of a record to restore, an array of records IDs to restore, or an object of filters to select the records to restore.",
|
||||
required: true,
|
||||
}
|
||||
]}
|
||||
sectionTitle="restore Parameters"
|
||||
/>
|
||||
---
|
||||
|
||||
## Restore Record by ID
|
||||
|
||||
```ts
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const [
|
||||
restoredPosts,
|
||||
restoredEntities
|
||||
] = await this.postRepository_.restore(id)
|
||||
|
||||
return restoredPosts
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
The `restore` method can accept the ID of a record to restore as a string.
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns a tuple with two elements:
|
||||
|
||||
- The first element is an array of the restored records.
|
||||
- The second element is an object whose keys are the names of restored data models, and values an array of restored record objects.
|
||||
- This is useful if records from other data models were previously soft-deleted due to cascading soft-deletes, and are now restored.
|
||||
|
||||
For example:
|
||||
|
||||
```json title="Example"
|
||||
[
|
||||
[
|
||||
{
|
||||
"id": "01JSHAW6Z7KW4X6E8MFPGNEKHC",
|
||||
"title": "My first post",
|
||||
"content": "This is my first post",
|
||||
"metadata": null,
|
||||
"product_id": null,
|
||||
"product_ids": [
|
||||
"prod_01JP4M5T5K55P2JN1F17EY7B2T"
|
||||
],
|
||||
"author_id": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"author": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"created_at": "2025-04-23T12:44:59.751Z",
|
||||
"updated_at": "2025-04-23T12:44:59.751Z",
|
||||
"deleted_at": "2025-04-23T12:45:08.750Z"
|
||||
}
|
||||
],
|
||||
{
|
||||
"Post": [
|
||||
{
|
||||
"id": "01JSHAW6Z7KW4X6E8MFPGNEKHC",
|
||||
"title": "My first post",
|
||||
"content": "This is my first post",
|
||||
"metadata": null,
|
||||
"product_id": null,
|
||||
"product_ids": [
|
||||
"prod_01JP4M5T5K55P2JN1F17EY7B2T"
|
||||
],
|
||||
"author_id": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"author": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"created_at": "2025-04-23T12:44:59.751Z",
|
||||
"updated_at": "2025-04-23T12:44:59.751Z",
|
||||
"deleted_at": "2025-04-23T12:45:08.750Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Restore Multiple Records By IDs
|
||||
|
||||
```ts
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
ids: string[],
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const [
|
||||
restoredPosts,
|
||||
restoredEntities
|
||||
] = await this.postRepository_.restore(ids)
|
||||
|
||||
return restoredPosts
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
ids: string[],
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(ids, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
The `restore` method can accept an array of record IDs to restore.
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns a tuple with two elements:
|
||||
|
||||
- The first element is an array of the restored records.
|
||||
- The second element is an object whose keys are the names of restored data models, and values an array of restored record objects.
|
||||
- This is useful if records from other data models were previously soft-deleted due to cascading soft-deletes, and are now restored.
|
||||
|
||||
For example:
|
||||
|
||||
```json title="Example"
|
||||
[
|
||||
[
|
||||
{
|
||||
"id": "01JSHAW6Z7KW4X6E8MFPGNEKHC",
|
||||
"title": "My first post",
|
||||
"content": "This is my first post",
|
||||
"metadata": null,
|
||||
"product_id": null,
|
||||
"product_ids": [
|
||||
"prod_01JP4M5T5K55P2JN1F17EY7B2T"
|
||||
],
|
||||
"author_id": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"author": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"created_at": "2025-04-23T12:44:59.751Z",
|
||||
"updated_at": "2025-04-23T12:44:59.751Z",
|
||||
"deleted_at": "2025-04-23T12:45:08.750Z"
|
||||
}
|
||||
],
|
||||
{
|
||||
"Post": [
|
||||
{
|
||||
"id": "01JSHAW6Z7KW4X6E8MFPGNEKHC",
|
||||
"title": "My first post",
|
||||
"content": "This is my first post",
|
||||
"metadata": null,
|
||||
"product_id": null,
|
||||
"product_ids": [
|
||||
"prod_01JP4M5T5K55P2JN1F17EY7B2T"
|
||||
],
|
||||
"author_id": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"author": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"created_at": "2025-04-23T12:44:59.751Z",
|
||||
"updated_at": "2025-04-23T12:44:59.751Z",
|
||||
"deleted_at": "2025-04-23T12:45:08.750Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Restore Records by Filters
|
||||
|
||||
```ts
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const [
|
||||
restoredPosts,
|
||||
restoredEntities
|
||||
] = await this.postRepository_.restore({
|
||||
title: "My Post"
|
||||
})
|
||||
|
||||
return restoredPosts
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
ids: string[],
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(ids, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
The `restore` method can accept an object of filters to select the records to restore.
|
||||
|
||||
In the example above, you pass an object with the `title` property to restore all records with that title.
|
||||
|
||||
<Note>
|
||||
|
||||
Find examples of different filters in the [Filter Records](../../tips/filtering/page.mdx) documentation.
|
||||
|
||||
</Note>
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns a tuple with two elements:
|
||||
|
||||
- The first element is an array of the restored records.
|
||||
- The second element is an object whose keys are the names of restored data models, and values an array of restored record objects.
|
||||
- This is useful if records from other data models were previously soft-deleted due to cascading soft-deletes, and are now restored.
|
||||
|
||||
For example:
|
||||
|
||||
```json title="Example"
|
||||
[
|
||||
[
|
||||
{
|
||||
"id": "01JSHAW6Z7KW4X6E8MFPGNEKHC",
|
||||
"title": "My first post",
|
||||
"content": "This is my first post",
|
||||
"metadata": null,
|
||||
"product_id": null,
|
||||
"product_ids": [
|
||||
"prod_01JP4M5T5K55P2JN1F17EY7B2T"
|
||||
],
|
||||
"author_id": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"author": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"created_at": "2025-04-23T12:44:59.751Z",
|
||||
"updated_at": "2025-04-23T12:44:59.751Z",
|
||||
"deleted_at": "2025-04-23T12:45:08.750Z"
|
||||
}
|
||||
],
|
||||
{
|
||||
"Post": [
|
||||
{
|
||||
"id": "01JSHAW6Z7KW4X6E8MFPGNEKHC",
|
||||
"title": "My first post",
|
||||
"content": "This is my first post",
|
||||
"metadata": null,
|
||||
"product_id": null,
|
||||
"product_ids": [
|
||||
"prod_01JP4M5T5K55P2JN1F17EY7B2T"
|
||||
],
|
||||
"author_id": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"author": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"created_at": "2025-04-23T12:44:59.751Z",
|
||||
"updated_at": "2025-04-23T12:44:59.751Z",
|
||||
"deleted_at": "2025-04-23T12:45:08.750Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
@@ -0,0 +1,334 @@
|
||||
---
|
||||
sidebar_label: "softDelete"
|
||||
---
|
||||
|
||||
import { TypeList } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `softDelete Method - Data Model Repository Reference`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
The `softDelete` method of a data model repository soft-deletes one or more records of the data model.
|
||||
|
||||
This means that the records are still available in the database, but they are marked as deleted by setting their `deleted_at` property to the deletion date.
|
||||
|
||||
You can later restore the records using the [restore](../restore/page.mdx) method.
|
||||
|
||||
<Note>
|
||||
|
||||
This reference assumes you've already resolved the data model repository, as explained in the [Data Model Repository Reference](../../page.mdx) documentation.
|
||||
|
||||
</Note>
|
||||
|
||||
## `softDelete` Parameters
|
||||
|
||||
<TypeList
|
||||
types={[
|
||||
{
|
||||
type: "`string` \\| `string[]` \\| `object`",
|
||||
name: "filters",
|
||||
description: "Can be either the ID of a record to soft-delete, an array of records IDs to soft-delete, or an object of filters to select the records to soft-delete.",
|
||||
required: true,
|
||||
}
|
||||
]}
|
||||
sectionTitle="softDelete Parameters"
|
||||
/>
|
||||
---
|
||||
|
||||
## Soft-Delete Record by ID
|
||||
|
||||
```ts
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const [
|
||||
deletedPosts,
|
||||
deletedEntities
|
||||
] = await this.postRepository_.softDelete(id)
|
||||
|
||||
return deletedPosts
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
The `softDelete` method can accept the ID of a record to soft-delete as a string.
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns a tuple with two elements:
|
||||
|
||||
- The first element is an array of the soft-deleted records.
|
||||
- The second element is an object whose keys are the names of deleted data models, and values an array of deleted record objects.
|
||||
- This is useful if records from other data models are soft-deleted due to cascading soft-deletes.
|
||||
|
||||
For example:
|
||||
|
||||
```json title="Example"
|
||||
[
|
||||
[
|
||||
{
|
||||
"id": "01JSHAW6Z7KW4X6E8MFPGNEKHC",
|
||||
"title": "My first post",
|
||||
"content": "This is my first post",
|
||||
"metadata": null,
|
||||
"product_id": null,
|
||||
"product_ids": [
|
||||
"prod_01JP4M5T5K55P2JN1F17EY7B2T"
|
||||
],
|
||||
"author_id": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"author": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"created_at": "2025-04-23T12:44:59.751Z",
|
||||
"updated_at": "2025-04-23T12:44:59.751Z",
|
||||
"deleted_at": "2025-04-23T12:45:08.750Z"
|
||||
}
|
||||
],
|
||||
{
|
||||
"Post": [
|
||||
{
|
||||
"id": "01JSHAW6Z7KW4X6E8MFPGNEKHC",
|
||||
"title": "My first post",
|
||||
"content": "This is my first post",
|
||||
"metadata": null,
|
||||
"product_id": null,
|
||||
"product_ids": [
|
||||
"prod_01JP4M5T5K55P2JN1F17EY7B2T"
|
||||
],
|
||||
"author_id": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"author": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"created_at": "2025-04-23T12:44:59.751Z",
|
||||
"updated_at": "2025-04-23T12:44:59.751Z",
|
||||
"deleted_at": "2025-04-23T12:45:08.750Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Soft-Delete Multiple Records By IDs
|
||||
|
||||
```ts
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
ids: string[],
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const [
|
||||
deletedPosts,
|
||||
deletedEntities
|
||||
] = await this.postRepository_.softDelete(ids)
|
||||
|
||||
return deletedPosts
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
ids: string[],
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(ids, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
The `softDelete` method can accept an array of record IDs to soft-delete.
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns a tuple with two elements:
|
||||
|
||||
- The first element is an array of the soft-deleted records.
|
||||
- The second element is an object whose keys are the names of deleted data models, and values an array of deleted record objects.
|
||||
- This is useful if records from other data models are soft-deleted due to cascading soft-deletes.
|
||||
|
||||
For example:
|
||||
|
||||
```json title="Example"
|
||||
[
|
||||
[
|
||||
{
|
||||
"id": "01JSHAW6Z7KW4X6E8MFPGNEKHC",
|
||||
"title": "My first post",
|
||||
"content": "This is my first post",
|
||||
"metadata": null,
|
||||
"product_id": null,
|
||||
"product_ids": [
|
||||
"prod_01JP4M5T5K55P2JN1F17EY7B2T"
|
||||
],
|
||||
"author_id": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"author": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"created_at": "2025-04-23T12:44:59.751Z",
|
||||
"updated_at": "2025-04-23T12:44:59.751Z",
|
||||
"deleted_at": "2025-04-23T12:45:08.750Z"
|
||||
}
|
||||
],
|
||||
{
|
||||
"Post": [
|
||||
{
|
||||
"id": "01JSHAW6Z7KW4X6E8MFPGNEKHC",
|
||||
"title": "My first post",
|
||||
"content": "This is my first post",
|
||||
"metadata": null,
|
||||
"product_id": null,
|
||||
"product_ids": [
|
||||
"prod_01JP4M5T5K55P2JN1F17EY7B2T"
|
||||
],
|
||||
"author_id": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"author": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"created_at": "2025-04-23T12:44:59.751Z",
|
||||
"updated_at": "2025-04-23T12:44:59.751Z",
|
||||
"deleted_at": "2025-04-23T12:45:08.750Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Soft-Delete Records by Filters
|
||||
|
||||
```ts
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const [
|
||||
deletedPosts,
|
||||
deletedEntities
|
||||
] = await this.postRepository_.softDelete({
|
||||
title: "My Post"
|
||||
})
|
||||
|
||||
return deletedPosts
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
ids: string[],
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(ids, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
The `softDelete` method can accept an object of filters to select the records to soft-delete.
|
||||
|
||||
In the example above, you pass an object with the `title` property to soft-delete all records with that title.
|
||||
|
||||
<Note>
|
||||
|
||||
Find examples of different filters in the [Filter Records](../../tips/filtering/page.mdx) documentation.
|
||||
|
||||
</Note>
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns a tuple with two elements:
|
||||
|
||||
- The first element is an array of the soft-deleted records.
|
||||
- The second element is an object whose keys are the names of deleted data models, and values an array of deleted record objects.
|
||||
- This is useful if records from other data models are soft-deleted due to cascading soft-deletes.
|
||||
|
||||
For example:
|
||||
|
||||
```json title="Example"
|
||||
[
|
||||
[
|
||||
{
|
||||
"id": "01JSHAW6Z7KW4X6E8MFPGNEKHC",
|
||||
"title": "My first post",
|
||||
"content": "This is my first post",
|
||||
"metadata": null,
|
||||
"product_id": null,
|
||||
"product_ids": [
|
||||
"prod_01JP4M5T5K55P2JN1F17EY7B2T"
|
||||
],
|
||||
"author_id": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"author": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"created_at": "2025-04-23T12:44:59.751Z",
|
||||
"updated_at": "2025-04-23T12:44:59.751Z",
|
||||
"deleted_at": "2025-04-23T12:45:08.750Z"
|
||||
}
|
||||
],
|
||||
{
|
||||
"Post": [
|
||||
{
|
||||
"id": "01JSHAW6Z7KW4X6E8MFPGNEKHC",
|
||||
"title": "My first post",
|
||||
"content": "This is my first post",
|
||||
"metadata": null,
|
||||
"product_id": null,
|
||||
"product_ids": [
|
||||
"prod_01JP4M5T5K55P2JN1F17EY7B2T"
|
||||
],
|
||||
"author_id": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"author": "01JSHAW6YZNKR65TJ242GCMD2S",
|
||||
"created_at": "2025-04-23T12:44:59.751Z",
|
||||
"updated_at": "2025-04-23T12:44:59.751Z",
|
||||
"deleted_at": "2025-04-23T12:45:08.750Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
@@ -0,0 +1,113 @@
|
||||
---
|
||||
sidebar_label: "update"
|
||||
---
|
||||
|
||||
import { TypeList } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `update Method - Data Model Repository Reference`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
The `update` method of a data model repository updates one or more records of the data model.
|
||||
|
||||
<Note>
|
||||
|
||||
This reference assumes you've already resolved the data model repository, as explained in the [Data Model Repository Reference](../../page.mdx) documentation.
|
||||
|
||||
</Note>
|
||||
|
||||
## `update` Parameters
|
||||
|
||||
<TypeList
|
||||
types={[
|
||||
{
|
||||
type: "`array`",
|
||||
name: "data",
|
||||
description: "An array of update details.",
|
||||
required: true,
|
||||
children: [
|
||||
{
|
||||
type: "`object`",
|
||||
name: "entity",
|
||||
description: "The entity to update. It must be the entire entity, which can be retrieved using the `find` method.",
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
type: "`object`",
|
||||
name: "update",
|
||||
description: "The properties to update. The keys are the property names of the data model, and the values are the values to update.",
|
||||
required: true,
|
||||
}
|
||||
]
|
||||
}
|
||||
]}
|
||||
openedLevel={1}
|
||||
sectionTitle="update Parameters"
|
||||
/>
|
||||
---
|
||||
|
||||
## Update Records
|
||||
|
||||
```ts
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const existingPost = await this.postRepository_.find({
|
||||
where: {
|
||||
id
|
||||
}
|
||||
})
|
||||
|
||||
const posts = await this.postRepository_.update([
|
||||
{
|
||||
entity: existingPost[0],
|
||||
update: {
|
||||
title: "My Post Updated"
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
return posts
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
The `update` method accepts an array of objects, each representing a record to update.
|
||||
|
||||
Each object has two properties:
|
||||
|
||||
- `entity`: The entity or record to update. It must be the entire record, which can be retrieved using the [find](../find/page.mdx) or [findAndCount](../findAndCount/page.mdx) methods.
|
||||
- `update`: The properties to update. The keys are the property names of the data model, and the values are the values to update.
|
||||
|
||||
In the example above, you retrieve the record to update using the `find` method. Then, you pass the entire record and the properties to update to the `update` method.
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns an array of the updated records.
|
||||
@@ -0,0 +1,92 @@
|
||||
---
|
||||
sidebar_label: "upsert"
|
||||
---
|
||||
|
||||
import { TypeList } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `upsert Method - Data Model Repository Reference`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
The `upsert` method of a data model repository creates or updates one or more records of the data model.
|
||||
|
||||
<Note>
|
||||
|
||||
This reference assumes you've already resolved the data model repository, as explained in the [Data Model Repository Reference](../../page.mdx) documentation.
|
||||
|
||||
</Note>
|
||||
|
||||
## `upsert` Parameters
|
||||
|
||||
<TypeList
|
||||
types={[
|
||||
{
|
||||
type: "`array`",
|
||||
name: "data",
|
||||
description: "An array of records to create or update. If a record object has an `id` property, the method will try to update the record. Otherwise, the method will create a new record.",
|
||||
required: true,
|
||||
}
|
||||
]}
|
||||
sectionTitle="upsert Parameters"
|
||||
/>
|
||||
---
|
||||
|
||||
## Upsert Records
|
||||
|
||||
```ts
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const posts = await this.postRepository_.upsert([
|
||||
{
|
||||
id: "01JSHAW6Z7KW4X6E8MFPGNEKHC",
|
||||
title: "My Old Post",
|
||||
},
|
||||
{
|
||||
title: "My New Post",
|
||||
}
|
||||
])
|
||||
|
||||
return posts
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
The `upsert` method accepts an array of objects, each representing a record to create or update.
|
||||
|
||||
If a record object has an `id` property, the method will try to update a record with that `id`. Otherwise, the method will create a new record.
|
||||
|
||||
If the `id` property is specified but no record with that `id` exists, the created record will have the specified `id`.
|
||||
|
||||
Each object has the same shape as the data model.
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns an array of the created or updated records.
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
---
|
||||
sidebar_label: "upsertWithReplace"
|
||||
---
|
||||
|
||||
import { TypeList } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `upsertWithReplace Method - Data Model Repository Reference`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
The `upsertWithReplace` method of a data model repository can do three things:
|
||||
|
||||
- Create a new record.
|
||||
- Update an existing record.
|
||||
- Delete a record related to the record being upserted. If a one-to-many or many-to-many relation is omitted in the new data of a record, the method will delete the related records if they belong to the record being upserted.
|
||||
|
||||
This method is useful when you're doing complex upserts with relations, or you want details of the operations performed. Otherwise, use the [upsert](../upsert/page.mdx) method.
|
||||
|
||||
<Note>
|
||||
|
||||
This reference assumes you've already resolved the data model repository, as explained in the [Data Model Repository Reference](../../page.mdx) documentation.
|
||||
|
||||
</Note>
|
||||
|
||||
## `upsertWithReplace` Parameters
|
||||
|
||||
<TypeList
|
||||
types={[
|
||||
{
|
||||
type: "`array`",
|
||||
name: "data",
|
||||
description: "An array of records to create or update. If a record object has an `id` property, the method will try to update the record. Otherwise, the method will create a new record.",
|
||||
required: true,
|
||||
}
|
||||
]}
|
||||
sectionTitle="upsertWithReplace Parameters"
|
||||
/>
|
||||
---
|
||||
|
||||
## Upsert Records
|
||||
|
||||
```ts
|
||||
import {
|
||||
InjectTransactionManager,
|
||||
MedusaContext,
|
||||
MedusaService,
|
||||
} from "@medusajs/framework/utils"
|
||||
import { Context, InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import { EntityManager } from "@mikro-orm/knex"
|
||||
import Post from "./models/post"
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
// ...
|
||||
@InjectTransactionManager()
|
||||
protected async doSomething_(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
const {
|
||||
entities,
|
||||
performedActions
|
||||
} = await this.postRepository_.upsertWithReplace([
|
||||
{
|
||||
id: "01JSHAW6Z7KW4X6E8MFPGNEKHC",
|
||||
title: "My Old Post",
|
||||
author_id: null
|
||||
},
|
||||
{
|
||||
id: "123",
|
||||
title: "My New Post",
|
||||
}
|
||||
])
|
||||
|
||||
return {
|
||||
entities,
|
||||
performedActions
|
||||
}
|
||||
}
|
||||
|
||||
@InjectManager()
|
||||
async doSomething(
|
||||
id: string,
|
||||
@MedusaContext() sharedContext?: Context<EntityManager>
|
||||
): Promise<any> {
|
||||
return await this.doSomething_(id, sharedContext)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
The `upsertWithReplace` method accepts an array of objects, each representing a record to create or update.
|
||||
|
||||
If a record object has an `id` property, the method will try to update a record with that `id`. Otherwise, the method will create a new record.
|
||||
|
||||
If the `id` property is specified but no record with that `id` exists, the created record will have the specified `id`.
|
||||
|
||||
Each object has the same shape as the data model.
|
||||
|
||||
### Returns
|
||||
|
||||
The method returns an object with two properties:
|
||||
|
||||
- `entities`: An array of the created or updated records.
|
||||
- `performedActions`: An object with three properties:
|
||||
- `created`: An object whose keys are the names of data models, and values are arrays of the records that were created.
|
||||
- `updated`: An object whose keys are the names of data models, and values are arrays of the records that were updated.
|
||||
- `deleted`: An object whose keys are the names of data models, and values are arrays of the records that were deleted.
|
||||
|
||||
For example:
|
||||
|
||||
```json title="Example"
|
||||
{
|
||||
"entities": [
|
||||
{
|
||||
"id": "01JSHAW6Z7KW4X6E8MFPGNEKHC",
|
||||
"title": "My Old Post",
|
||||
"author_id": null
|
||||
},
|
||||
{
|
||||
"id": "123",
|
||||
"title": "My New Post"
|
||||
}
|
||||
],
|
||||
"performedActions": {
|
||||
"created": {
|
||||
"Post": [
|
||||
{
|
||||
"id": "123"
|
||||
}
|
||||
]
|
||||
},
|
||||
"updated": {
|
||||
"Post": [
|
||||
{
|
||||
"id": "01JSHAW6Z7KW4X6E8MFPGNEKHC"
|
||||
}
|
||||
]
|
||||
},
|
||||
"deleted": {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,87 @@
|
||||
import { ChildDocs } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `Data Model Repository Reference`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
This section of the documentation provides a reference of the methods generated for data model repositories that are injected into a module's container.
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
Learn more about the data model repository in the [Database Operations](!docs!/learn/fundamentals/modules/db-operations) documentation.
|
||||
|
||||
</Note>
|
||||
|
||||
## When to Use the Data Model Repository?
|
||||
|
||||
If your module has data models, then you should always extend the [service factory](!docs!/learn/fundamentals/modules/service-factory). It generates basic data-mangement operations for your module's data models.
|
||||
|
||||
However, there are some cases where you might need to perform more complex database operations and need more control over the parameters you're passing.
|
||||
|
||||
In those cases, you can use the data model repository.
|
||||
|
||||
---
|
||||
|
||||
## Data Model Repository Registration Name
|
||||
|
||||
When the Medusa application injects a data model repository into a module's container, it formats the registration name by:
|
||||
|
||||
- Taking the data model's name that's passed as the first parameter of `model.define`
|
||||
- Lower-casing the first character
|
||||
- Suffixing the result with `Repository`.
|
||||
|
||||
For example:
|
||||
|
||||
- `Post` model: `postRepository`
|
||||
- `My_Custom` model: `my_CustomRepository`
|
||||
|
||||
---
|
||||
|
||||
## Resolve Data Model Repository
|
||||
|
||||
To resolve a data model repository from a module's container, pass the data model's name in the first parameter of the module's constructor.
|
||||
|
||||
For example:
|
||||
|
||||
export const resolveRepoHighlights = [
|
||||
["17", "postRepository", "Resolve the data model repository for the `Post` model."],
|
||||
]
|
||||
|
||||
```ts highlights={resolveRepoHighlights}
|
||||
import { MedusaService } from "@medusajs/framework/utils"
|
||||
import { InferTypeOf, DAL } from "@medusajs/framework/types"
|
||||
import Post from "./models/post"
|
||||
|
||||
type Post = InferTypeOf<typeof Post>
|
||||
|
||||
type InjectedDependencies = {
|
||||
postRepository: DAL.RepositoryService<Post>
|
||||
}
|
||||
|
||||
class BlogModuleService extends MedusaService({
|
||||
Post,
|
||||
}){
|
||||
protected postRepository_: DAL.RepositoryService<Post>
|
||||
|
||||
constructor({
|
||||
postRepository
|
||||
}: InjectedDependencies) {
|
||||
super(...arguments)
|
||||
this.postRepository_ = postRepository
|
||||
}
|
||||
}
|
||||
|
||||
export default BlogModuleService
|
||||
```
|
||||
|
||||
In this example, the `BlogModuleService` class resolves the `postRepository` from its container.
|
||||
|
||||
---
|
||||
|
||||
## Methods Reference
|
||||
|
||||
Learn how to use the data model repository's methods to perform database operations on the data model.
|
||||
|
||||
<ChildDocs showItems={["Methods"]} hideTitle />
|
||||
@@ -0,0 +1,531 @@
|
||||
---
|
||||
sidebar_label: "Filtering"
|
||||
---
|
||||
|
||||
import { Table } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `Filter Records - Data Model Repository Reference`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
This reference provides examples to different filtering mechanisms and scenarios.
|
||||
|
||||
## Methods that Accept Filters
|
||||
|
||||
Some of the data model repository's methods allow you to pass filters, including:
|
||||
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>
|
||||
Method
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell>
|
||||
Filter Parameter
|
||||
</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
[find](../../methods/find/page.mdx)
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Accepts a `where` property in its first parameter to pass filters.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
[findAndCount](../../methods/findAndCount/page.mdx)
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Accepts a `where` property in its first parameter to pass filters.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
[delete](../../methods/delete/page.mdx)
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Accepts an object as a first parameter to pass filters.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
[softDelete](../../methods/softDelete/page.mdx)
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Accepts an object as a first parameter to pass filters.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
[restore](../../methods/restore/page.mdx)
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Accepts an object as a first parameter to pass filters.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
|
||||
While the examples in this reference are based on the `find` method, the same filtering mechanisms apply to the other methods.
|
||||
|
||||
---
|
||||
|
||||
## Match Exact Value
|
||||
|
||||
```ts
|
||||
const posts = await this.postRepository_.find({
|
||||
where: {
|
||||
title: "My Post"
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
If you pass a property with its value, only records whose properties exactly match the value are selected.
|
||||
|
||||
In the example above, only posts having the title `My Post` are retrieved.
|
||||
|
||||
---
|
||||
|
||||
## Doesn't Match Exact Value
|
||||
|
||||
```ts
|
||||
const posts = await this.postRepository_.find({
|
||||
where: {
|
||||
title: {
|
||||
$ne: "My Post",
|
||||
}
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
To find records with a property that doesn't match a value, pass an object with a `$ne` property. Its value is the value that a record's property shouldn't match.
|
||||
|
||||
In the example above, only posts that don't have the title `My Post` are retrieved.
|
||||
|
||||
---
|
||||
|
||||
## Match Multiple Values
|
||||
|
||||
```ts
|
||||
const posts = await this.postRepository_.find({
|
||||
where: {
|
||||
views: [
|
||||
50,
|
||||
100,
|
||||
],
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
To find records with a property matching multiple values, pass an array of those values as the property's value in the filter.
|
||||
|
||||
In the example above, only posts having either `50` or `100` views are retrieved.
|
||||
|
||||
---
|
||||
|
||||
## Don't Match Multiple Values
|
||||
|
||||
```ts
|
||||
const posts = await this.postRepository_.find({
|
||||
where: {
|
||||
title: {
|
||||
$nin: ["My Post", "My Post 2"]
|
||||
}
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
To find records with a property that doesn't match one or more values, pass an object with a `$nin` property. Its value is an array of multiple values that a record's property shouldn't match.
|
||||
|
||||
In the example above, only posts that don't have the title `My Post` are retrieved.
|
||||
|
||||
---
|
||||
|
||||
## Match Text Like Value
|
||||
|
||||
<Note>
|
||||
|
||||
This filter only applies to text-like properties, including `text`, `id`, and `enum` properties.
|
||||
|
||||
</Note>
|
||||
|
||||
```ts
|
||||
const posts = await this.postRepository_.find({
|
||||
where: {
|
||||
title: {
|
||||
$like: "My%"
|
||||
}
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
To perform a `like` filter on a record's property, set the property's value to an object with a `$like` property. Its value is the string to use when applying the `like` filter.
|
||||
|
||||
The example above matches all posts whose title starts with `My`.
|
||||
|
||||
---
|
||||
|
||||
## Filter by Null or Not Null
|
||||
|
||||
To retrieve records with a property that is `null`, set the property's value to `null`.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
const posts = await this.postRepository_.find({
|
||||
where: {
|
||||
published_at: null,
|
||||
},
|
||||
})
|
||||
```
|
||||
In the example above, only posts that have a `null` publish date are retrieved.
|
||||
|
||||
On the other hand, to retrieve records with a property that isn't `null`, set the property's value to an object with a `$ne` property.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
const posts = await this.postRepository_.find({
|
||||
where: {
|
||||
published_at: {
|
||||
$ne: null,
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
In the example above, only posts that have a publish date are retrieved.
|
||||
|
||||
---
|
||||
|
||||
## Apply Range Filters
|
||||
|
||||
<Note>
|
||||
|
||||
This filter only applies to the `number` and `dateTime` properties.
|
||||
|
||||
</Note>
|
||||
|
||||
```ts
|
||||
const posts = await this.postRepository_.find({
|
||||
where: {
|
||||
published_at: {
|
||||
$lt: new Date(),
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
To filter a record's property to be within a range, set the property's value to an object with any of the following properties:
|
||||
|
||||
1. `$lt`: The property's value must be less than the supplied value.
|
||||
2. `$lte`: The property's value must be less than or equal to the supplied value.
|
||||
3. `$gt`: The property's value must be greater than the supplied value.
|
||||
4. `$gte`: The property's value must be greater than or equal the supplied value.
|
||||
|
||||
In the example above, only posts whose `published_at` property is before the current date and time are retrieved.
|
||||
|
||||
### Example: Retrieve Posts Published Today
|
||||
|
||||
```ts
|
||||
const startToday = new Date()
|
||||
startToday.setHours(0, 0, 0, 0)
|
||||
|
||||
const endToday = new Date()
|
||||
endToday.setHours(23, 59, 59, 59)
|
||||
|
||||
const posts = await this.postRepository_.find({
|
||||
where: {
|
||||
published_at: {
|
||||
$gte: startToday,
|
||||
$lte: endToday,
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
The `dateTime` property also stores the time. So, when matching for an exact day, you must set a range filter to be between the beginning and end of the day.
|
||||
|
||||
In this example, you retrieve the current date twice: once to set its time to `00:00:00`, and another to set its time `23:59:59`. Then, you retrieve posts whose `published_at` property is between `00:00:00` and `23:59:59` of today.
|
||||
|
||||
### Example: Range Filter on Number Property
|
||||
|
||||
```ts
|
||||
const posts = await this.postRepository_.find({
|
||||
where: {
|
||||
views: {
|
||||
$gte: 50,
|
||||
$lte: 100,
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
In the example above, only posts with `views` between `50` and `100` are retrieved.
|
||||
|
||||
---
|
||||
|
||||
## Apply Or Condition
|
||||
|
||||
```ts
|
||||
const posts = await this.postRepository_.find({
|
||||
where: {
|
||||
$or: [
|
||||
{
|
||||
title: "My Post",
|
||||
},
|
||||
{
|
||||
published_at: {
|
||||
$lt: new Date(),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
To use an `or` condition, pass to the filter object the `$or` property, whose value is an array of filters.
|
||||
|
||||
In the example above, posts whose title is `My Post` or their `published_at` date is less than the current date and time are retrieved.
|
||||
|
||||
---
|
||||
|
||||
## Apply And Condition
|
||||
|
||||
```ts
|
||||
const posts = await this.postRepository_.find({
|
||||
where: {
|
||||
$and: [
|
||||
{
|
||||
title: "My Post",
|
||||
},
|
||||
{
|
||||
published_at: {
|
||||
$lt: new Date(),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
To use an `and` condition, pass to the filter object the `$and` property, whose value is an array of filters.
|
||||
|
||||
In the example above, only posts whose title is `My Post` and their `published_at` date is less than the current date and time are retrieved.
|
||||
|
||||
---
|
||||
|
||||
## Complex Filters Example
|
||||
|
||||
```ts
|
||||
const posts = await this.postRepository_.find({
|
||||
where: {
|
||||
$or: [
|
||||
{
|
||||
$and: [
|
||||
{ views: { $gte: 50 } },
|
||||
{
|
||||
published_at: {
|
||||
$gte: new Date(new Date().getFullYear(), 0, 1),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: {
|
||||
$like: "%Featured%",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
In the example above, posts are retrieved if they meet either of the following conditions:
|
||||
|
||||
1. The post has at least `50` views and was published after the beginning of the current year.
|
||||
2. The post's title contains the word `Featured`.
|
||||
|
||||
By combining `and` and `or` conditions, you can create complex filters to retrieve records that meet specific criteria.
|
||||
|
||||
---
|
||||
|
||||
## Supported Filter Operators List
|
||||
|
||||
The following operators are supported by the data model repository filtering mechanism:
|
||||
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>
|
||||
Operator
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell>
|
||||
Description
|
||||
</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
|
||||
<Table.Body>
|
||||
<Table.Row className="bg-medusa-bg-component">
|
||||
<Table.Cell colSpan={2}>
|
||||
Comparison Operators
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$eq`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values that are equal to a specified value.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$ne`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values that are not equal to a specified value.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$in`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches any of the values specified in an array.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$nin`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches none of the values specified in an array.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$like`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values containing a specified substring.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$lt`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values that are less than a specified value.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$lte`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values that are less than or equal to a specified value.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$gt`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values that are greater than a specified value.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$gte`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values that are greater than or equal to a specified value.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$re`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values that match a specified regular expression.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$ilike`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values containing a specified substring, case-insensitive.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$fulltext`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Performs a full-text search on a text property.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$overlap`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values that have overlapping elements with the specified array.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$contains`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Performs an `@> value` comparison. Learn more in the [PostgreSQL documentation](https://www.postgresql.org/docs/9.6/functions-array.html).
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$contained`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Performs an `value @>` comparison. Learn more in the [PostgreSQL documentation](https://www.postgresql.org/docs/9.6/functions-array.html).
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row className="bg-medusa-bg-component">
|
||||
<Table.Cell colSpan={2}>
|
||||
Logical Operators
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$and`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Joins two or more conditions with a logical AND.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$or`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Joins two or more conditions with a logical OR.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$not`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Inverts the logic of a condition. For example, `$not: { $eq: value }` matches any value that is not equal to the specified value.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
sidebar_label: "Filtering"
|
||||
---
|
||||
|
||||
import { Table } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `Filter Records - Service Factory Reference`,
|
||||
}
|
||||
@@ -273,4 +275,181 @@ In the example above, posts are retrieved if they meet either of the following c
|
||||
1. The post has at least `50` views and was published after the beginning of the current year.
|
||||
2. The post's title contains the word `Featured`.
|
||||
|
||||
By combining `and` and `or` conditions, you can create complex filters to retrieve records that meet specific criteria.
|
||||
By combining `and` and `or` conditions, you can create complex filters to retrieve records that meet specific criteria.
|
||||
|
||||
---
|
||||
|
||||
## Supported Filter Operators List
|
||||
|
||||
The following operators are supported by the service factory filtering mechanism:
|
||||
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>
|
||||
Operator
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell>
|
||||
Description
|
||||
</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
|
||||
<Table.Body>
|
||||
<Table.Row className="bg-medusa-bg-component">
|
||||
<Table.Cell colSpan={2}>
|
||||
Comparison Operators
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$eq`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values that are equal to a specified value.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$ne`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values that are not equal to a specified value.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$in`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches any of the values specified in an array.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$nin`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches none of the values specified in an array.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$like`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values containing a specified substring.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$lt`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values that are less than a specified value.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$lte`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values that are less than or equal to a specified value.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$gt`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values that are greater than a specified value.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$gte`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values that are greater than or equal to a specified value.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$re`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values that match a specified regular expression.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$ilike`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values containing a specified substring, case-insensitive.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$fulltext`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Performs a full-text search on a text property.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$overlap`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Matches values that have overlapping elements with the specified array.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$contains`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Performs an `@> value` comparison. Learn more in the [PostgreSQL documentation](https://www.postgresql.org/docs/9.6/functions-array.html).
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$contained`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Performs an `value @>` comparison. Learn more in the [PostgreSQL documentation](https://www.postgresql.org/docs/9.6/functions-array.html).
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row className="bg-medusa-bg-component">
|
||||
<Table.Cell colSpan={2}>
|
||||
Logical Operators
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$and`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Joins two or more conditions with a logical AND.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$or`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Joins two or more conditions with a logical OR.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`$not`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Inverts the logic of a condition. For example, `$not: { $eq: value }` matches any value that is not equal to the specified value.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
|
||||
@@ -132,7 +132,7 @@ export const generatedEditDates = {
|
||||
"app/service-factory-reference/methods/retrieve/page.mdx": "2024-07-31T17:01:33+03:00",
|
||||
"app/service-factory-reference/methods/soft-delete/page.mdx": "2024-07-31T17:01:33+03:00",
|
||||
"app/service-factory-reference/methods/update/page.mdx": "2024-07-31T17:01:33+03:00",
|
||||
"app/service-factory-reference/tips/filtering/page.mdx": "2025-03-21T08:32:39.125Z",
|
||||
"app/service-factory-reference/tips/filtering/page.mdx": "2025-04-23T14:38:29.068Z",
|
||||
"app/service-factory-reference/page.mdx": "2024-07-26T14:40:56+00:00",
|
||||
"app/storefront-development/cart/context/page.mdx": "2025-03-27T14:47:14.258Z",
|
||||
"app/storefront-development/cart/create/page.mdx": "2025-03-27T14:46:51.473Z",
|
||||
|
||||
@@ -691,6 +691,50 @@ export const filesMap = [
|
||||
"filePath": "/www/apps/resources/app/create-medusa-app/page.mdx",
|
||||
"pathname": "/create-medusa-app"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/app/data-model-repository-reference/methods/create/page.mdx",
|
||||
"pathname": "/data-model-repository-reference/methods/create"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/app/data-model-repository-reference/methods/delete/page.mdx",
|
||||
"pathname": "/data-model-repository-reference/methods/delete"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/app/data-model-repository-reference/methods/find/page.mdx",
|
||||
"pathname": "/data-model-repository-reference/methods/find"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/app/data-model-repository-reference/methods/findAndCount/page.mdx",
|
||||
"pathname": "/data-model-repository-reference/methods/findAndCount"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/app/data-model-repository-reference/methods/restore/page.mdx",
|
||||
"pathname": "/data-model-repository-reference/methods/restore"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/app/data-model-repository-reference/methods/softDelete/page.mdx",
|
||||
"pathname": "/data-model-repository-reference/methods/softDelete"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/app/data-model-repository-reference/methods/update/page.mdx",
|
||||
"pathname": "/data-model-repository-reference/methods/update"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/app/data-model-repository-reference/methods/upsert/page.mdx",
|
||||
"pathname": "/data-model-repository-reference/methods/upsert"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/app/data-model-repository-reference/methods/upsertWithReplace/page.mdx",
|
||||
"pathname": "/data-model-repository-reference/methods/upsertWithReplace"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/app/data-model-repository-reference/page.mdx",
|
||||
"pathname": "/data-model-repository-reference"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/app/data-model-repository-reference/tips/filtering/page.mdx",
|
||||
"pathname": "/data-model-repository-reference/tips/filtering"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/app/deployment/medusa-application/railway/page.mdx",
|
||||
"pathname": "/deployment/medusa-application/railway"
|
||||
|
||||
@@ -6367,6 +6367,137 @@ const generatedgeneratedReferencesSidebarSidebar = {
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "sidebar",
|
||||
"sidebar_id": "data-model-repository-reference",
|
||||
"title": "Data Model Repository",
|
||||
"description": "List of methods in your service extending the data model repository.",
|
||||
"children": [
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/data-model-repository-reference",
|
||||
"title": "Overview",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "category",
|
||||
"title": "Methods",
|
||||
"initialOpen": true,
|
||||
"autogenerate_path": "/data-model-repository-reference/methods",
|
||||
"children": [
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/data-model-repository-reference/methods/create",
|
||||
"title": "create",
|
||||
"description": "",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/data-model-repository-reference/methods/delete",
|
||||
"title": "delete",
|
||||
"description": "",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/data-model-repository-reference/methods/find",
|
||||
"title": "find",
|
||||
"description": "",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/data-model-repository-reference/methods/findAndCount",
|
||||
"title": "findAndCount",
|
||||
"description": "",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/data-model-repository-reference/methods/restore",
|
||||
"title": "restore",
|
||||
"description": "",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/data-model-repository-reference/methods/softDelete",
|
||||
"title": "softDelete",
|
||||
"description": "",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/data-model-repository-reference/methods/update",
|
||||
"title": "update",
|
||||
"description": "",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/data-model-repository-reference/methods/upsert",
|
||||
"title": "upsert",
|
||||
"description": "",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/data-model-repository-reference/methods/upsertWithReplace",
|
||||
"title": "upsertWithReplace",
|
||||
"description": "",
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "category",
|
||||
"title": "Tips",
|
||||
"initialOpen": true,
|
||||
"autogenerate_path": "/data-model-repository-reference/tips",
|
||||
"children": [
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/data-model-repository-reference/tips/filtering",
|
||||
"title": "Filtering",
|
||||
"description": "",
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
|
||||
@@ -75,6 +75,35 @@ export const referencesSidebar = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "sidebar",
|
||||
sidebar_id: "data-model-repository-reference",
|
||||
title: "Data Model Repository",
|
||||
description:
|
||||
"List of methods in your service extending the data model repository.",
|
||||
children: [
|
||||
{
|
||||
type: "link",
|
||||
path: "/data-model-repository-reference",
|
||||
title: "Overview",
|
||||
},
|
||||
{
|
||||
type: "separator",
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
title: "Methods",
|
||||
initialOpen: true,
|
||||
autogenerate_path: "/data-model-repository-reference/methods",
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
title: "Tips",
|
||||
initialOpen: true,
|
||||
autogenerate_path: "/data-model-repository-reference/tips",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
path: "/events-reference",
|
||||
|
||||
@@ -123,6 +123,7 @@ const sidebarMappings: {
|
||||
"/references/workflows",
|
||||
"/references-overview",
|
||||
"/references/medusa-workflows",
|
||||
"/data-model-repository-reference",
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -313,6 +313,11 @@ export const navDropdownItems: NavigationItem[] = [
|
||||
title: "Data Model Language",
|
||||
link: "/resources/references/data-model",
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
title: "Data Model Repository",
|
||||
link: "/resources/data-model-repository-reference",
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
title: "Events Reference",
|
||||
|
||||
Reference in new issue
Block a user