# Polymorphic Relationship Filters

| AVAILABLE API VERSION                                  |
| ------------------------------------------------------ |
| API v56.0 and later                                    |
| Event and Task (Beta) available in API v59.0 and later |

A polymorphic relationship is one where an object can be one of several object types. For example, an event can have a polymorphic relationship to an account, campaign, or opportunity via the Related To field. Conversely, a contact has a non-polymorphic relationship to an account via the Account Name field.

[Common polymorphic fields](https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_relationships_and_polymorph_keys.htm#common-polymorphic-fields) include the Owner, Who, and What fields.

To query using a polymorphic relationship, use [inline fragments](https://graphql.org/learn/queries/#inline-fragments) with the `... on Object` syntax.

## Owner Polymorphic Field

The Owner field represents the parent of the record. For example, a case owner can be a Group or User object.

When the parent relationship is polymorphic, an input object following the naming convention `<ObjectName>_<RelationshipName>_Filters` is constructed and used as the filter type for that parent relationship.

The Owner field follows the naming convention `<ObjectName>_Owner`, which is used as the filter type for that parent relationship.

For example, the Case object’s Owner filter has a type of `Case_Owner_Filters`.

```sfdocs-code {"lang":"graphql", "title": "Case Owner field", "src": "" }
type Case {
  Owner: Case_Owner
}
```

The union has one possible type for each concrete type that participates in the polymorphic relationship.

```sfdocs-code {"lang":"graphql", "title": "Case_Owner subtypes", "src": "" }
union Case_Owner = Group | User
```

The input object type has one input object field of the filter type for each object that participates in the polymorphic relationship.

```sfdocs-code {"lang":"graphql", "title": "Case_Owner_Filters fields", "src": "" }
input Case_Owner_Filters {
  Group: Group_Filter
  Name: Name_Filter
  User: User_Filter
}
```

Let’s say you query cases that match a specified Owner.Name value. Case records correspond to owners that are either groups or users. This example queries cases where the owner’s username starts with "D" and the Owner.Type is a User object.

```sfdocs-code {"lang":"graphql", "title": "Query cases using the Owner field", "src": "" }
query  {
  uiapi {
    query {
      Case ( where: { Owner: { User: { Name: {like: "D%"} }}} ) {
        edges {
          node {
            Id
            Owner {
              ... on User {
                  Name { value }
              }
            }
          }
        }
      }
    }
  }
}
```

The previous query is similar to this SOQL statement.

```sfdocs-code {"lang":"sql", "title": "SOQL statement with the Owner polymorphic field", "src": "" }
SELECT Id, Owner.Name
FROM Case
WHERE Owner.Name like 'D%'
```

In the next example, the Name field is available only when the node is of type User.

```sfdocs-code {"lang":"graphql", "title": "Query ", "src": "" }
query AccountCasesDetail {
  uiapi {
      query {
        Contact ( where: { Name: { like: "Rose%" } } ) {
            edges {
                node {
                    Id
                    Name {
                        value
                        displayValue
                    }
                    Cases {
                        edges {
                            node {
                                Subject {
                                    value
                                }
                                Owner {
                                    ... on User {
                                        Name {
                                            value
                                        }
                                    }
                                }
                                CreatedDate {
                                    displayValue
                                }
                                IsEscalated  {
                                    value
                                }
                            }
                        }
                    }
                }
            }
          }
      }
  }
}
```

## Who Polymorphic Field

The Who field represents the person associated with the record. Some objects, like Event, Task, ContactRequest, and SocialPost, have a Who field. For more information, see the [Object Reference for the Salesforce Platform](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/field_types.htm).

:::note
Not all objects that have a Who field are available in [GraphQL API via UI API](https://developer.salesforce.com/docs/atlas.en-us.uiapi.meta/uiapi/ui_api_all_supported_objects.htm).
:::

For example, the `ContactRequest` object's `Who` filter has a type of `ContactRequest_Who_Filters`. This input object has one input object field for each concrete type that participates in the polymorphic relationship.

```sfdocs-code {"lang":"graphql", "title": "ContactRequest with who field", "src": "" }
type ContactRequest {
  who: ContactRequest_Who
}
```

The union has one possible type for each concrete type that participates in the polymorphic relationship.

```sfdocs-code {"lang":"graphql", "title": "ContactRequest_Who union", "src": "" }
union ContactRequest_Who = Contact | Lead | User
```

```sfdocs-code {"lang":"graphql", "title": "ContactRequest_Filter input", "src": "" }
input ContactRequest_Filter {
  who: ContactRequest_Who_Filters # the filter object contains another filter object constructed for the polymorphic type
}
```

The input object type has one input object field of the filter type for each object that participates in the polymorphic relationship.

```sfdocs-code {"lang":"graphql", "title": "ContactRequest_Who_Filters input", "src": "" }
input ContactRequest_Who_Filters {
  Contact: Contact_Filter
  Lead:    Lead_Filter
  Name:    Name_Filter
  User:    User_Filter
}
```

ContactRequest records have a Who field that can reference a contact, lead, name, or user. This example query applies to ContactRequest records whose owners can be either a Group or User object. It filters the records based on the User object and select records where the Who.Type is a Contact object.

```sfdocs-code {"lang":"graphql", "title": "Query ContactRequest using the Who field", "src": "" }
query  {
  uiapi {
    query {
      ContactRequest ( where: { Owner: { User: { FirstName: {like: "D%"} }}} ) {
        edges {
          node {
            Id
            Who {
              ... on Contact {
                  Name { value }
              }
            }
          }
        }
      }
    }
  }
}
```

The previous query is similar to this SOQL statement.

```sfdocs-code {"lang":"sql", "title": "SOQL statement with polymorphic Who and Owner fields", "src": "" }
SELECT Id, Who.FirstName, Who.LastName
FROM ContactRequest
WHERE Owner.FirstName LIKE 'D%'
```

## What Polymorphic Field

The What field represents non-person objects that are associated with the record. Some objects, like Event and ContactRequest, have a What field. For more information, see the [Object Reference for the Salesforce Platform](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/field_types.htm).

:::note
Not all objects that have a Who field are available in [GraphQL API via UI API](https://developer.salesforce.com/docs/atlas.en-us.uiapi.meta/uiapi/ui_api_all_supported_objects.htm).
:::

For example, the `ContactRequest` object's `What` filter has a type of `ContactRequest_What_Filters`. This input object has one input object field for each concrete type that participates in the polymorphic relationship.

```sfdocs-code {"lang":"graphql", "title": "ContactRequest type", "src": "" }
type ContactRequest {
  who: ContactRequest_What
}
```

The union has one possible type for each concrete type that participates in the polymorphic relationship.

```sfdocs-code {"lang":"graphql", "title": "ContactRequest_What union", "src": "" }
union ContactRequest_What = Account | Case | Opportunity
```

```sfdocs-code {"lang":"graphql", "title": "ContactRequest_Filter input", "src": "" }
input ContactRequest_Filter {
  What: ContactRequest_What_Filters # the filter object contains another filter object constructed for the polymorphic type
}
```

The input object type has one input object field of the filter type for each object that participates in the polymorphic relationship.

```sfdocs-code {"lang":"graphql", "title": "ContactRequest_What_Filters input", "src": "" }
input ContactRequest_What_Filters {
  Account:     Account_Filter
  Case:        Case_Filter
  Name:        Name_Filter
  Opportunity: Opportunity_Filter
}
```

ContactRequest records have a What field that can reference an account, case, name, or opportunity. This example query applies to ContactRequest records whose What field is Account. It returns ContactRequest records with the Name field, the What.Name field where the What.Type is Account.

```sfdocs-code {"lang":"graphql", "title": "Query ContactRequest using the What field", "src": "" }
query  {
  uiapi {
    query {
      ContactRequest {
        edges {
          node {
            Id
            Name { value }
            What {
              ... on Account {
                Name { value }
              }
            }
          }
        }
      }
    }
  }
}
```

The previous query is similar to this SOQL statement.

```sfdocs-code {"lang":"sql", "title": "SOQL statement with polymorphic What field", "src": "" }
SELECT Id, Name, What.Name
FROM ContactRequest
```

## Filter Polymorphic Fields with Boolean Operators

You can filter the result set by the value of the underlying polymorphic types data. Each filter is combined with an [`and` operator](/docs/platform/graphql/guide/filter-boolean.md) to assert the polymorphic relationship is of the filter type.

```sfdocs-code {"lang":"graphql", "title": "Filter using a polymorphic relationship", "src": "" }
query  {
  uiapi {
    query {
      ContactRequest ( where: {
        and: [{
          Who: { Contact: { FirstName: {
            like: "R%" } } },
          Who: {Contact: { LastName: {
            like: "G%" } } }
        }]
       }) {
        edges {
          node {
            Id
            Name { value }
          }
        }
      }
    }
  }
}
```

The query is similar to this SOQL statement.

```sfdocs-code {"lang":"sql", "title": "SOQL statement with polymorphic relationship", "src": "" }
SELECT Id, Name
FROM ContactRequest
WHERE Who.FirstName LIKE 'R%' AND Who.LastName LIKE 'G%'
```

You can work with multiple fields on a polymorphic filter with an [`or` operator](/docs/platform/graphql/guide/filter-boolean.md). This example returns ContactRequest records with the Id, Name, and What.Name fields where the What.Type is Account. It filters the records where the What.Name is "Salesforce" or the Who.FirstName contact names start with "R".

```sfdocs-code {"lang":"graphql", "title": "Query ContactRequest records with the or operator", "src": "" }
query  {
  uiapi {
    query {
      ContactRequest ( where: {
        or: [{
          What: { Account: { Name: {
            eq: "Salesforce" } } },
          Who: { Contact: { FirstName: {
            like: "R%" } } }
        }]
       }) {
        edges {
          node {
            Id
            Name { value }
            What {
              ... on Account {
                Name { value }
              }
            }
          }
        }
      }
    }
  }
}
```

The previous query is similar to this SOQL statement where the individual clauses are joined with `OR`, allowing selective filtering based on the underlying type of the polymorphic relationship.

```sfdocs-code {"lang":"sql", "title": "SOQL statement with selective filtering", "src": "" }
SELECT Id, Name, What.Name
FROM ContactRequest
WHERE What.Name = 'Salesforce' OR Who.FirstName LIKE 'R%'
```

:::note
Although objects with an `OwnerId`, `WhatId`, or `WhoId` field have polymorphic parent relationships, GraphQL API includes as possible types only [those objects that are available via the User Interface API](https://developer.salesforce.com/docs/atlas.en-us.uiapi.meta/uiapi/ui_api_all_supported_objects.htm).
:::

If the parent relationship is non-polymorphic, then the corresponding filter type for that object is used.

## Non-Polymorphic Relationships

Consider an account that as a parent relationship `CreatedBy` points to the User object.

```sfdocs-code {"lang":"graphql", "title": "An account with a parent relationship", "src": "" }
type Account {
  CreatedBy: User
}
```

As the relationship is non-polymorphic, the filter has a field with the same name of the parent relationship with the corresponding filter type.

```sfdocs-code {"lang":"graphql", "title": "Account filter", "src": "" }
input Account_Filter {
  CreatedBy: User_Filter
}
```

To find all accounts created by a particular user, we can construct a `where` argument as follows.

```sfdocs-code {"lang":"graphql", "title": "Find accounts created by Misato", "src": "" }
query  {
  uiapi {
    query {
      Account ( where: { CreatedBy: { FirstName: { like: "Misato" } } } ) {
        edges {
          node {
            Id
            Name { value }
          }
        }
      }
    }
  }
}
```

This query is similar to this SOQL statement.

```sfdocs-code {"lang":"graphql", "title": "SOQL statement with a parent relationship", "src": "" }
SELECT Id, Name
FROM Account
WHERE CreatedBy.FirstName='Misato'
```
