# Filter Parameters for Search Results in Neko Image Gallery: Complete API Reference

> Explore Neko Image Gallery API filter parameters to refine vector search results. Discover eight filters including aspect ratio, dimensions, starred status, and categories.

- Repository: [EdgeNeko/nekoimagegallery](https://github.com/hv0905/nekoimagegallery)
- Tags: api-reference
- Published: 2026-03-03

---

**The Neko Image Gallery API supports eight distinct filter parameters—including aspect ratio ranges, minimum dimensions, starred status, and category whitelists—to refine vector search results against the Qdrant backend.**

Neko Image Gallery is an open-source AI-powered image management system that stores embeddings and metadata in Qdrant. When querying the `/search/text/{prompt}` or `/search/similar` endpoints, clients can narrow results by passing filter parameters defined in the `FilterParams` Pydantic model located in [`app/Models/query_params.py`](https://github.com/hv0905/nekoimagegallery/blob/main/app/Models/query_params.py). These parameters are automatically translated into Qdrant filter objects by the `vector_db_context` service.

## Available Filter Parameters

The complete set of user-controllable filter parameters is defined in [`app/Models/query_params.py`](https://github.com/hv0905/nekoimagegallery/blob/main/app/Models/query_params.py) (lines 16-44). Each parameter maps to a specific field condition in the vector database.

### Aspect Ratio Constraints

**`preferred_ratio`** (`float`): Specifies the target aspect ratio (width ÷ height) for returned images. For example, `1.6` targets 16:10 images.

**`ratio_tolerance`** (`float`): Defines the acceptable fractional deviation from `preferred_ratio`. The system calculates the valid range as `preferred_ratio × (1 ± ratio_tolerance)`, then constructs a Qdrant `Range` filter with `gte` and `lte` bounds.

### Minimum Dimension Thresholds

**`min_width`** (`int`): Enforces a lower bound on image width in pixels. Implemented as a `FieldCondition` with `Range(gte=min_width)` in [`app/Services/vector_db_context.py`](https://github.com/hv0905/nekoimagegallery/blob/main/app/Services/vector_db_context.py).

**`min_height`** (`int`): Enforces a lower bound on image height in pixels. Uses the same range filter pattern as `min_width`.

### Metadata and Category Filters

**`starred`** (`bool`): When `true`, restricts results to images where the `starred` field equals `true`; when `false`, excludes starred images. Implemented via Qdrant's `MatchValue` condition.

**`categories`** (`str`): A comma-separated whitelist of category tags (e.g., `"stickers,cg"`). The system splits the string and applies a `MatchAny` condition, returning images that contain **any** of the listed tags.

**`categories_negative`** (`str`): A comma-separated blacklist of category tags. These are added to the filter's `must_not` clause, excluding images that match **any** of the specified tags.

### Internal OCR Text Filter

**`ocr_text`** (`str`): An internal parameter automatically populated when performing exact OCR text searches with `exact=true`. The system converts the query to lowercase and applies a `MatchText` condition against the `ocr_text_lower` field in Qdrant. Users typically do not set this manually; it is derived from the search prompt.

## How Filters Are Translated to Qdrant

The `vector_db_context._get_filters_by_filter_param` method (lines 295-355 in [`app/Services/vector_db_context.py`](https://github.com/hv0905/nekoimagegallery/blob/main/app/Services/vector_db_context.py)) handles the conversion from `FilterParams` to Qdrant `Filter` objects:

- **Range filters**: Applied to numerical fields (`width`, `height`, `ratio`) using `FieldCondition` with `Range` objects.
- **Exact matches**: Used for boolean `starred` fields via `MatchValue`.
- **Text matches**: Applied to `ocr_text_lower` using `MatchText` for exact OCR searches.
- **Tag lists**: Whitelisted categories use `MatchAny` in the `must` clause; blacklisted categories use `MatchAny` in the `must_not` clause.

If all filter parameters are omitted, the method returns `None` and the search executes without additional constraints.

## Practical Usage Examples

### HTTP API Query

To search for wide images that are starred and belong to specific categories:

```http
GET /search/text/cute%20cat?preferred_ratio=1.78&ratio_tolerance=0.05&min_width=800&categories=anime,cg&starred=true

```

This request constructs a `FilterParams` instance with:
- `preferred_ratio`: 1.78 (targeting 16:9)
- `ratio_tolerance`: 0.05 (accepting ratios between ~1.69 and ~1.87)
- `min_width`: 800 pixels
- `categories`: Whitelist including "anime" and "cg"
- `starred`: true

### Python Model Instantiation

For programmatic access within the application stack:

```python
from app.Models.query_params import FilterParams

# Configure filters for high-resolution landscape images

filters = FilterParams(
    preferred_ratio=1.6,      # 16:10 aspect ratio

    ratio_tolerance=0.1,      # ±10% tolerance

    min_width=1920,
    min_height=1080,
    categories="wallpaper,landscape",
    categories_negative="nsfw,lowres",
    starred=False
)

# Execute search with filters

results = await db_context.query_search(
    query=embedding_vector,
    top_k=50,
    filter_param=filters
)

```

### Exact OCR Text Search

When the `exact=true` query parameter is provided, the system automatically sets the `ocr_text` filter:

```http
GET /search/text/Hello%20World?exact=true

```

This internally adds a text match filter against the `ocr_text_lower` field, ensuring only images containing the exact phrase "Hello World" in their OCR data are returned.

## Summary

- **Eight filter parameters** control search granularity: `preferred_ratio`, `ratio_tolerance`, `min_width`, `min_height`, `starred`, `categories`, `categories_negative`, and `ocr_text`.
- **Source definitions** reside in [`app/Models/query_params.py`](https://github.com/hv0905/nekoimagegallery/blob/main/app/Models/query_params.py), while translation logic lives in [`app/Services/vector_db_context.py`](https://github.com/hv0905/nekoimagegallery/blob/main/app/Services/vector_db_context.py) within the `_get_filters_by_filter_param` method.
- **Qdrant integration** uses `Range` for numerical bounds, `MatchValue` for booleans, `MatchAny` for category whitelists, and `must_not` for blacklists.
- **OCR text filtering** operates automatically when `exact=true` is specified, matching against the normalized `ocr_text_lower` field.

## Frequently Asked Questions

### How do I filter for images with a specific aspect ratio?

Use the `preferred_ratio` parameter combined with `ratio_tolerance`. For 16:9 images (ratio 1.78) with a 5% tolerance, set `preferred_ratio=1.78&ratio_tolerance=0.05`. The system calculates the valid range (1.69 to 1.87) and applies a Qdrant range filter on the aspect ratio field.

### Can I exclude specific categories from search results?

Yes. Pass a comma-separated list to the `categories_negative` parameter. For example, `categories_negative=nsfw,screenshots` adds a `must_not` condition to the Qdrant filter, ensuring no images tagged with "nsfw" or "screenshots" appear in the results.

### What happens if I provide no filter parameters?

If all filter fields are omitted, the `_get_filters_by_filter_param` method returns `None`, and the search executes against the entire collection without additional constraints. This retrieves the top-k nearest neighbors purely based on vector similarity.

### Is the `ocr_text` filter available for manual use?

The `ocr_text` parameter is intended for internal use by the exact-match search pipeline. When you set `exact=true` on a text search endpoint, the system automatically populates this field and applies a `MatchText` condition against the `ocr_text_lower` field. Manual specification is possible but not required for standard API usage.