> ## Documentation Index
> Fetch the complete documentation index at: https://nestjs-query.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Relations

Relations work a little differently in `mongoose` when compared to other relational ORMs such as `sequelize` or `typescript`. You can read more about relations (references) in `mongoose` [here](https://mongoosejs.com/docs/populate.html)

<Note>There are multiple ways to set of references in `mongoose` there are intended as starting point.</Note>

<Warning>Filtering on references is not supported by mongoose.</Warning>

## One to Many/Many To One Example

To set up a one to many/many to one relationship in mongoose you will store a reference in your document

For example lets add sub tasks to our todo items by storing a `todoItem` ref on our `subTask`

<Tabs>
  <Tab title="Todo Item">
    ```ts title="todo-item/todo-item.entity.ts" {32-36} theme={null}
    import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'
    import { SchemaTypes, Types, Document } from 'mongoose'

    @Schema({ timestamps: true })
    export class TodoItemEntity extends Document {

      @Prop({ required: true })
      title!: string

      @Prop()
      description?: string

      @Prop({ required: true })
      completed!: boolean

      @Prop({ default: Date.now })
      createdAt!: Date

      @Prop({ default: Date.now })
      updatedAt!: Date

      @Prop({ default: 0 })
      priority!: number

      @Prop()
      createdBy?: string

      @Prop()
      updatedBy?: string
    }

    export const TodoItemEntitySchema = SchemaFactory.createForClass(TodoItemEntity)
    TodoItemEntitySchema.virtual('subTasks', {
      ref: 'SubTaskEntity',
      localField: '_id',
      foreignField: 'todoItem'
    })
    ```
  </Tab>

  <Tab title="Subtask">
    ```ts title="sub-task/sub-task.entity.ts" {15-16} theme={null}
    import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'
    import { SchemaTypes, Types, Document } from 'mongoose'

    @Schema({ timestamps: true })
    export class SubTaskEntity extends Document {

      @Prop({ required: true })
      title!: string

      @Prop()
      description?: string

      @Prop({ required: true })
      completed!: boolean

      @Prop({ type: SchemaTypes.ObjectId, ref: 'TodoItemEntity', required: true })
      todoItem!: Types.ObjectId

      @Prop()
      createdAt!: Date

      @Prop()
      updatedAt!: Date

      @Prop()
      createdBy?: string

      @Prop()
      updatedBy?: string
    }

    export const SubTaskEntitySchema = SchemaFactory.createForClass(SubTaskEntity)
    ```
  </Tab>
</Tabs>

Now that we have the relationship defined we can add the `@Relation` and `@CursorConnection` to our DTOs

<Tabs>
  <Tab title="Todo Item">
    ```ts title="todo-item/todo-item.dto.ts" theme={null}
    import { FilterableField, IDField, KeySet, CursorConnection } from '@ptc-org/nestjs-query-graphql'
    import { ObjectType, ID, GraphQLISODateTime, Field } from '@nestjs/graphql'
    import { SubTaskDTO } from '../../sub-task/dto/sub-task.dto'

    @ObjectType('TodoItem')
    @KeySet(['id'])
    // disable the remove because mongoose does not support removing a virtual

    @CursorConnection('subTasks', () => SubTaskDTO, { update: { enabled: true } })
    export class TodoItemDTO {

      @IDField(() => ID)
      id!: string

      @FilterableField()
      title!: string

      @FilterableField({ nullable: true })
      description?: string

      @FilterableField()
      completed!: boolean

      @FilterableField(() => GraphQLISODateTime)
      createdAt!: Date

      @FilterableField(() => GraphQLISODateTime)
      updatedAt!: Date

      @Field()
      age!: number

      @FilterableField()
      priority!: number

      @FilterableField({ nullable: true })
      createdBy?: string

      @FilterableField({ nullable: true })
      updatedBy?: string
    }
    ```
  </Tab>

  <Tab title="Subtask">
    ```ts title="sub-task/sub-task.dto.ts" theme={null}
    import { FilterableField, IDField, KeySet, Relation } from '@ptc-org/nestjs-query-graphql'
    import { ObjectType, ID, GraphQLISODateTime } from '@nestjs/graphql'
    import { TodoItemDTO } from '../../todo-item/dto/todo-item.dto'

    @ObjectType('SubTask')
    @KeySet(['id'])
    // disable the remove because a sub task cannot exist without a todoitem

    @Relation('todoItem', () => TodoItemDTO, { update: { enabled: true } })
    export class SubTaskDTO {

      @IDField(() => ID)
      id!: string

      @FilterableField()
      title!: string

      @FilterableField({ nullable: true })
      description?: string

      @FilterableField()
      completed!: boolean

      @FilterableField(() => GraphQLISODateTime)
      createdAt!: Date

      @FilterableField(() => GraphQLISODateTime)
      updatedAt!: Date

      @FilterableField({ nullable: true })
      createdBy?: string

      @FilterableField({ nullable: true })
      updatedBy?: string
    }
    ```
  </Tab>
</Tabs>

## Many To Many Example

In this example we'll add `tags` to `todoItems` by storing an array of `tag` references on the `todoItems`.

<Tabs>
  <Tab title="Todo Item">
    ```ts title="todo-item/todo-item.entity.ts" {21-23} theme={null}
    import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'
    import { SchemaTypes, Types, Document } from 'mongoose'

    @Schema({ timestamps: true })
    export class TodoItemEntity extends Document {

      @Prop({ required: true })
      title!: string

      @Prop()
      description?: string

      @Prop({ required: true })
      completed!: boolean

      @Prop({ default: Date.now })
      createdAt!: Date

      @Prop({ default: Date.now })
      updatedAt!: Date

      // notice the brackets around the prop options

      @Prop([{ type: SchemaTypes.ObjectId, ref: 'TagEntity' }])
      tags!: Types.ObjectId[]

      @Prop({ default: 0 })
      priority!: number

      @Prop()
      createdBy?: string

      @Prop()
      updatedBy?: string
    }

    export const TodoItemEntitySchema = SchemaFactory.createForClass(TodoItemEntity)
    ```
  </Tab>

  <Tab title="Tag">
    ```ts title="tag/tag.entity.ts" {23-27} theme={null}
    import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'
    import { Document } from 'mongoose'

    @Schema({ timestamps: true })
    export class TagEntity extends Document {

      @Prop({ required: true })
      name!: string

      @Prop()
      createdAt!: Date

      @Prop()
      updatedAt!: Date

      @Prop()
      createdBy?: string

      @Prop()
      updatedBy?: string
    }

    export const TagEntitySchema = SchemaFactory.createForClass(TagEntity)
    TagEntitySchema.virtual('todoItems', {
      ref: 'TodoItemEntity',
      localField: '_id',
      foreignField: 'tags'
    })
    ```
  </Tab>
</Tabs>

Now that we have the relationship defined we can add the `@CursorConnection` to our DTOS

<Tabs>
  <Tab title="Todo Item">
    ```ts title="todo-item/todo-item.dto.ts" theme={null}
    import { FilterableField, IDField, KeySet, CursorConnection } from '@ptc-org/nestjs-query-graphql'
    import { ObjectType, ID, GraphQLISODateTime, Field } from '@nestjs/graphql'
    import { TagDTO } from '../../tag/dto/tag.dto'

    @ObjectType('TodoItem')
    @KeySet(['id'])
    @CursorConnection('tags', () => TagDTO)
    export class TodoItemDTO {

      @IDField(() => ID)
      id!: string

      @FilterableField()
      title!: string

      @FilterableField({ nullable: true })
      description?: string

      @FilterableField()
      completed!: boolean

      @FilterableField(() => GraphQLISODateTime)
      createdAt!: Date

      @FilterableField(() => GraphQLISODateTime)
      updatedAt!: Date

      @Field()
      age!: number

      @FilterableField()
      priority!: number

      @FilterableField({ nullable: true })
      createdBy?: string

      @FilterableField({ nullable: true })
      updatedBy?: string
    }
    ```
  </Tab>

  <Tab title="Tag">
    ```ts title="tag/tag.dto.ts" theme={null}
    import { FilterableField, IDField, KeySet, CursorConnection } from '@ptc-org/nestjs-query-graphql'
    import { ObjectType, ID, GraphQLISODateTime } from '@nestjs/graphql'
    import { TodoItemDTO } from '../../todo-item/dto/todo-item.dto'

    @ObjectType('Tag')
    @KeySet(['id'])
    // disable update and remove since it is a virtual in the entity

    @CursorConnection('todoItems', () => TodoItemDTO)
    export class TagDTO {

      @IDField(() => ID)
      id!: string

      @FilterableField()
      name!: string

      @FilterableField(() => GraphQLISODateTime)
      createdAt!: Date

      @FilterableField(() => GraphQLISODateTime)
      updatedAt!: Date

      @FilterableField({ nullable: true })
      createdBy?: string

      @FilterableField({ nullable: true })
      updatedBy?: string
    }
    ```
  </Tab>
</Tabs>
