> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mixpeek.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Sort Attribute

> Reorder documents by any metadata field value

![Sort Attribute stage showing attribute-based document ordering](https://mintcdn.com/mixpeek/TmiAqiYj-LwmWL2a/assets/retrievers/sort-attribute.svg?fit=max\&auto=format\&n=TmiAqiYj-LwmWL2a\&q=85\&s=08a095cd3221ca92e9351162374f6d19)

The Sort Attribute stage reorders documents based on metadata field values. It supports ascending/descending order, nested fields, and multiple sort criteria.

> [!NOTE]
>
> **Stage Category**: SORT (Reorders documents)
>
> **Transformation**: N documents → N documents (reordered by field value)

## When to Use

| Use Case | Description |
| - | - |
| **Price sorting** | Order products by price |
| **Recency sorting** | Most recent first |
| **Rating sorting** | Highest rated first |
| **Alphabetical** | Sort by name or title |
| **Custom ranking** | Sort by any numeric field |

## When NOT to Use

| Scenario | Recommended Alternative |
| - | - |
| Relevance ranking | `rerank` (neural re-scoring) |
| Complex scoring logic | `api_call` to custom service |
| Already sorted by search | Skip this stage |

## Parameters

| Parameter | Type | Default | Description |
| - | - | - | - |
| `field` | string | `metadata.created_at` | Field path to sort by |
| `direction` | string | `desc` | Sort direction: `asc` or `desc` |
| `nulls_last` | boolean | `true` | Place null or missing values at the end of the results regardless of direction. When `false`, nulls follow the sort order: first for `asc`, last for `desc` |

## Configuration Examples

```json Price Low to High theme={null}
{
  "stage_name": "sort_attribute",
  "stage_type": "sort",
  "config": {
    "stage_id": "sort_attribute",
    "parameters": {
      "field": "metadata.price",
      "direction": "asc"
    }
  }
}
```

```json Newest First theme={null}
{
  "stage_name": "sort_attribute",
  "stage_type": "sort",
  "config": {
    "stage_id": "sort_attribute",
    "parameters": {
      "field": "metadata.created_at",
      "direction": "desc"
    }
  }
}
```

```json Highest Rated theme={null}
{
  "stage_name": "sort_attribute",
  "stage_type": "sort",
  "config": {
    "stage_id": "sort_attribute",
    "parameters": {
      "field": "metadata.rating",
      "direction": "desc",
      "nulls_last": true
    }
  }
}
```

```json Alphabetical theme={null}
{
  "stage_name": "sort_attribute",
  "stage_type": "sort",
  "config": {
    "stage_id": "sort_attribute",
    "parameters": {
      "field": "metadata.title",
      "direction": "asc"
    }
  }
}
```

```json Nested Field theme={null}
{
  "stage_name": "sort_attribute",
  "stage_type": "sort",
  "config": {
    "stage_id": "sort_attribute",
    "parameters": {
      "field": "metadata.reviews.average_rating",
      "direction": "desc"
    }
  }
}
```

```json By Relevance Score theme={null}
{
  "stage_name": "sort_attribute",
  "stage_type": "sort",
  "config": {
    "stage_id": "sort_attribute",
    "parameters": {
      "field": "score",
      "direction": "desc"
    }
  }
}
```

## Field Types

The stage handles various field types:

| Type | Sort Behavior |
| - | - |
| Number | Numeric comparison |
| String | Lexicographic (alphabetical) |
| Date/ISO8601 | Chronological |
| Boolean | false \< true |

## Null Handling

| `nulls_last` | Behavior |
| - | - |
| `true` | Null/missing values always appear last, whatever the direction (default) |
| `false` | Null/missing values follow the sort order: first for `asc`, last for `desc` |

```json theme={null}
{
  "field": "metadata.optional_field",
  "direction": "desc",
  "nulls_last": true
}
```

## Performance

| Metric | Value |
| - | - |
| **Latency** | \< 5ms |
| **Complexity** | O(n log n) |
| **Memory** | In-place sort |
| **Index support** | Uses indexes when available |

> [!TIP]
>
> Sorting is very fast. Unlike `rerank`, it doesn't require model inference, making it ideal for simple ordering by attributes.

## Common Pipeline Patterns

### Search + Filter + Sort

```json theme={null}
[
  {
    "stage_name": "feature_search",
    "stage_type": "filter",
    "config": {
      "stage_id": "feature_search",
      "parameters": {
        "searches": [
          {
            "feature_uri": "mixpeek://multimodal_extractor@v1/vertex_multimodal_embedding",
            "query": {"input_mode": "text", "value": "{{INPUT.query}}"},
            "top_k": 50
          }
        ],
        "final_top_k": 50
      }
    }
  },
  {
    "stage_name": "attribute_filter",
    "stage_type": "filter",
    "config": {
      "stage_id": "attribute_filter",
      "parameters": {
        "field": "metadata.in_stock",
        "operator": "eq",
        "value": true
      }
    }
  },
  {
    "stage_name": "sort_attribute",
    "stage_type": "sort",
    "config": {
      "stage_id": "sort_attribute",
      "parameters": {
        "field": "metadata.price",
        "direction": "asc"
      }
    }
  },
  {
    "stage_name": "sample",
    "stage_type": "reduce",
    "config": {
      "stage_id": "sample",
      "parameters": {
        "count": 10
      }
    }
  }
]
```

### Rerank + Sort (Tie-Breaking)

```json theme={null}
[
  {
    "stage_name": "feature_search",
    "stage_type": "filter",
    "config": {
      "stage_id": "feature_search",
      "parameters": {
        "searches": [
          {
            "feature_uri": "mixpeek://multimodal_extractor@v1/vertex_multimodal_embedding",
            "query": {"input_mode": "text", "value": "{{INPUT.query}}"},
            "top_k": 100
          }
        ],
        "final_top_k": 100
      }
    }
  },
  {
    "stage_name": "rerank",
    "stage_type": "sort",
    "config": {
      "stage_id": "rerank",
      "parameters": {
        "inference_name": "BAAI__bge_reranker_v2_m3",
        "top_k": 20
      }
    }
  },
  {
    "stage_name": "sort_attribute",
    "stage_type": "sort",
    "config": {
      "stage_id": "sort_attribute",
      "parameters": {
        "field": "metadata.created_at",
        "direction": "desc"
      }
    }
  }
]
```

### Dynamic Sort Direction

```json theme={null}
[
  {
    "stage_name": "feature_search",
    "stage_type": "filter",
    "config": {
      "stage_id": "feature_search",
      "parameters": {
        "searches": [
          {
            "feature_uri": "mixpeek://multimodal_extractor@v1/vertex_multimodal_embedding",
            "query": {"input_mode": "text", "value": "{{INPUT.query}}"},
            "top_k": 100
          }
        ],
        "final_top_k": 100
      }
    }
  },
  {
    "stage_name": "sort_attribute",
    "stage_type": "sort",
    "config": {
      "stage_id": "sort_attribute",
      "parameters": {
        "field": "{{INPUT.sort_by}}",
        "direction": "{{INPUT.sort_order}}"
      }
    }
  }
]
```

## Comparison: sort\_attribute vs rerank

| Feature | sort\_attribute | rerank |
| - | - | - |
| Based on | Field values | Query relevance |
| Speed | \< 5ms | 50-100ms |
| Model required | No | Yes |
| Use case | Attribute ordering | Relevance scoring |
| Cost | Free | API calls |

## Multiple Sort Criteria

For multi-field sorting, chain multiple sort stages (last sort is primary):

```json theme={null}
[
  {
    "stage_name": "sort_attribute",
    "stage_type": "sort",
    "config": {
      "stage_id": "sort_attribute",
      "parameters": {
        "field": "metadata.created_at",
        "direction": "desc"
      }
    }
  },
  {
    "stage_name": "sort_attribute",
    "stage_type": "sort",
    "config": {
      "stage_id": "sort_attribute",
      "parameters": {
        "field": "metadata.featured",
        "direction": "desc"
      }
    }
  }
]
```

This sorts by `featured` first, then by `created_at` for ties.

## Error Handling

| Error | Behavior |
| - | - |
| Field not found | Treated as null |
| Type mismatch | String comparison fallback |
| Invalid order | Defaults to `desc` |

## Related

* [Rerank](https://docs.mixpeek.com/docs/retrieval/stages/rerank.md) - Neural relevance ranking
* [Sample](https://docs.mixpeek.com/docs/retrieval/stages/sample.md) - Reduce result count
* [Attribute Filter](https://docs.mixpeek.com/docs/retrieval/stages/attribute-filter.md) - Filter before sorting


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.