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
@@ -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>
|
||||
|
||||
Reference in new issue
Block a user