> For the complete documentation index, see [llms.txt](https://navixy.com/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://navixy.com/docs/navixy-graphql-api/filtering-and-sorting/custom-field-filtering.md).

# Custom field filtering and sorting

Filter and sort assets and geo objects by their custom field values in Business Data Repository.

[Business Data Repository's](/docs/navixy-graphql-api/business-data-repository/overview.md) assets and geo objects are the entities that support custom fields, and both can be filtered and sorted by their custom field values. This is in addition to the standard `filter` and `orderBy` arguments described in [Filtering and sorting](/docs/navixy-graphql-api/filtering-and-sorting.md).

For an overview of custom fields themselves, see [Custom fields](/docs/navixy-graphql-api/business-data-repository/api-reference/custom-fields.md).

## Filtering by custom fields

Add conditions to the `customFields` array inside the `filter` argument:

```graphql
query {
  bdr {
    assets(
      workspaceId: "019d48ea-0752-8000-801f-444556437ab1"
      filter: {
        customFields: [
          { code: "cf_fuel_type", operator: EQ, value: { string: "diesel" } }
        ]
      }
    ) {
      nodes {
        id
        title
      }
    }
  }
}
```

Each condition in the `customFields` array has three parts:

<table><thead><tr><th width="200.39996337890625">Field</th><th>Description</th></tr></thead><tbody><tr><td>code</td><td>The custom field's code, as defined in its CustomFieldDefinition</td></tr><tr><td>operator</td><td>How to compare the value</td></tr><tr><td>value</td><td>The value to compare against. Provide exactly one option, the one matching the <a href="#value-formats">field's type</a></td></tr></tbody></table>

### Operators

<table data-search="false"><thead><tr><th>Operator</th><th>Description</th></tr></thead><tbody><tr><td>EQ</td><td>Equals</td></tr><tr><td>NE</td><td>Not equals</td></tr><tr><td>GT</td><td>Greater than</td></tr><tr><td>GTE</td><td>Greater than or equal</td></tr><tr><td>LT</td><td>Less than</td></tr><tr><td>LTE</td><td>Less than or equal</td></tr><tr><td>CONTAINS</td><td>String contains (case-insensitive)</td></tr><tr><td>IN</td><td>Matches any value in the provided array</td></tr><tr><td>IS_NULL</td><td>Field has no value</td></tr><tr><td>IS_NOT_NULL</td><td>Field has a value</td></tr></tbody></table>

### How CONTAINS matches

On `STRING` and `TEXT` fields, `CONTAINS` ignores letter case and matches everything else literally:

* Case differences never prevent a match, in any alphabet: `diesel` finds `Diesel Truck`, and `дизель` finds `Дизельный грузовик`.
* Accents count: `cafe` does not find `café`.
* Digits match literally: `part 7` does not find `part 0007`, and a Western digit does not find its equivalent from another script.
* Invisible characters count: a soft hyphen or a zero-width space inside the stored value breaks the match.

Search for the substring exactly as it is stored; only letter case can differ.

The whole-value operators `EQ`, `NE`, and `IN` compare strings with the natural-language rules that [sorting](/docs/navixy-graphql-api/filtering-and-sorting.md#sort-behavior) uses, and those rules treat some visibly different strings as equal: for them, `1` equals `01`. A value that `EQ` matches is therefore not always found by `CONTAINS` with the same search string.

### Value formats

The `value` field is a `@oneOf` input: provide exactly one of its options, the one matching your field's type:

<table data-search="false"><thead><tr><th>Option</th><th>Field types</th><th>Example</th></tr></thead><tbody><tr><td><code>string</code></td><td>STRING, TEXT, OPTIONS</td><td><code>{ string: "diesel" }</code></td></tr><tr><td><code>decimal</code></td><td>DECIMAL</td><td><code>{ decimal: 42.50 }</code></td></tr><tr><td><code>integer</code></td><td>INTEGER</td><td><code>{ integer: 42 }</code></td></tr><tr><td><code>boolean</code></td><td>BOOLEAN</td><td><code>{ boolean: true }</code></td></tr><tr><td><code>date</code></td><td>DATE</td><td><code>{ date: "2024-01-15" }</code></td></tr><tr><td><code>datetime</code></td><td>DATETIME</td><td><code>{ datetime: "2024-01-15T10:30:00Z" }</code></td></tr><tr><td><code>id</code></td><td>DEVICE, REFERENCE</td><td><code>{ id: "019a6a3f-..." }</code></td></tr><tr><td><code>stringList</code></td><td>IN operator on string-based fields</td><td><code>{ stringList: ["option_a", "option_b"] }</code></td></tr><tr><td><code>idList</code></td><td>IN operator on DEVICE and REFERENCE fields</td><td><code>{ idList: ["uuid1", "uuid2"] }</code></td></tr></tbody></table>

For `IS_NULL` and `IS_NOT_NULL` operators, omit `value` or set it to `null`.

### Multiple conditions

Multiple custom field conditions are combined with AND logic:

```graphql
filter: {
  customFields: [
    { code: "cf_fuel_type", operator: EQ, value: { string: "diesel" } },
    { code: "cf_year", operator: GTE, value: { integer: 2020 } }
  ]
}
```

This returns assets where fuel type is diesel AND year is 2020 or later.

### Multi-value fields

For custom fields configured to hold multiple values (`isMulti: true`), the filter matches if any stored value satisfies the condition:

```graphql
# Asset has colors: ["red", "blue", "white"]
filter: {
  customFields: [
    { code: "cf_colors", operator: EQ, value: { string: "red" } }
  ]
}
# Matches — "red" is one of the values
```

### Combining standard and custom filters

You can use standard filter fields and custom field conditions together:

```graphql
query {
  bdr {
    assets(
      workspaceId: "019d48ea-0752-8000-801f-444556437ab1"
      filter: {
        typeIds: ["type-truck-uuid"]
        titleContains: "north"
        customFields: [
          { code: "cf_region", operator: EQ, value: { string: "northwest" } }
        ]
      }
    ) {
      nodes {
        id
        title
      }
    }
  }
}
```

This returns trucks with "north" in their title that are assigned to the northwest region.

## Sorting by custom fields

Assets and geo objects support sorting by custom field values. The sortable field types are `STRING`, `DECIMAL`, `INTEGER`, `DATE`, `DATETIME`, plus the reference types `DEVICE` and single-value `REFERENCE`, which sort by the title of the entity they point at rather than by the stored ID. `TEXT`, `OPTIONS`, `BOOLEAN`, and `GEOJSON` fields are not sortable, and neither is a multi-value `REFERENCE` or a `REFERENCE` pointing at an entity with no title.

```graphql
query {
  bdr {
    assets(
      workspaceId: "019d48ea-0752-8000-801f-444556437ab1"
      orderBy: { customFieldCode: "cf_priority", direction: DESC }
    ) {
      nodes {
        id
        title
      }
    }
  }
}
```

Use either `field` or `customFieldCode` in your `orderBy` input, not both — they are mutually exclusive.

## See also

* [Filtering and sorting](/docs/navixy-graphql-api/filtering-and-sorting.md): Narrow list queries and control result order
* [Defining and using custom fields](/docs/navixy-graphql-api/business-data-repository/guides/defining-and-using-custom-fields.md): Define custom fields and store your own data on entities


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://navixy.com/docs/navixy-graphql-api/filtering-and-sorting/custom-field-filtering.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
