StashEntityStore provides advanced filtering methods that combine local caching with smart field-level population. These methods enable high-performance queries by minimizing network traffic while ensuring data completeness.
Overview
The advanced filtering system builds on the UNSET Pattern and Identity Map to provide:- Field-level granularity: Track which fields are loaded vs unqueried
- Smart population: Automatically fetch only missing fields
- Local filtering: Query cached data without network calls
- Fail-fast validation: Ensure required fields are present before filtering
Method Comparison
filter_strict() - Fail-Fast Filtering
Filters cached objects, raising an error if any required fields are missing. Useful when you MUST have complete data.
Signature
Example
When to Use
- Data validation: Ensure cache is complete before processing
- Debugging: Identify incomplete cache population
- Critical operations: Operations that require guaranteed field presence
filter_and_populate() - Smart Hybrid Filtering
The main workhorse method. Filters cached objects, automatically fetching missing fields as needed. Much faster than find() when most data is cached.
Signature
Example
Performance Benefits
Scenario: Cache has 1000 performers with basic info, need to filter byrating100
Batch Size Parameter
Controls how many entities are populated concurrently:filter_and_populate_with_stats() - Debug Variant
Same as filter_and_populate() but returns detailed statistics. Useful for performance optimization.
Signature
Example
Statistics Dictionary
When to Use
- Performance analysis: Identify cache inefficiencies
- Optimization: Determine if cache warming is needed
- Debugging: Understand why queries are slow
populated_filter_iter() - Lazy Async Iterator
Lazy version of filter_and_populate() that yields results incrementally. Great for large datasets where you want to start processing immediately or can short-circuit early.
Signature
Example: Early Exit
Example: Incremental Processing
Batch Parameters
populate_batch: How many to populate concurrently (default: 50)yield_batch: How many to process before yielding (default: 10)
When to Use
- Large datasets: Process 10,000+ entities incrementally
- Early exit: Stop processing when you find enough matches
- Memory efficiency: Don’t load all results into memory
- Progress reporting: Update UI as results stream in
Real-World Workflow Example
Best Practices
1. Choose the Right Method
2. Cache Warming Strategy
3. Performance Monitoring
4. Field Dependencies
Nested Field Filtering
All advanced filter methods support Django-style nested field specifications using double-underscore (__) syntax. This allows you to filter on properties of related objects without manual joins.
Syntax
- Simple field:
'rating100','favorite' - Nested field:
'files__path','studio__parent__name' - Deep nesting:
'studio__parent__parent__name'(arbitrary depth) - Mixed:
['rating100', 'files__path', 'studio__name']
Example: Filter Images by File Properties
Example: Filter by Studio Hierarchy
How It Works
When you specify a nested field like'files__path', the filter method:
- Parses the specification:
'files__path'→['files', 'path'] - Checks root field: Ensures
filesrelationship is populated - Recursively checks nested fields: Ensures
pathis populated on eachFileobject - Auto-populates missing data: Fetches only what’s needed from the server
Benefits
- No manual joins: Express complex queries naturally
- Selective fetching: Only fetch fields actually needed
- Type-safe: Compile-time checking with IDE autocomplete
- Efficient: Uses identity map to avoid duplicate fetches
Nested Field Examples
With filter_strict()
Performance Tip
Nested field filtering is most efficient when:- Root relationships are already cached
- Only leaf fields need population
- Batch sizes are tuned for your dataset
Integration with UNSET Pattern
The advanced filter methods work seamlessly with the UNSET Pattern:Preloading Files with find_iter(BaseFile, ...)
find_iter(BaseFile, ...) bulk-loads files and warms the identity map. Each file is deserialized as its concrete polymorphic subtype (VideoFile, ImageFile, GalleryFile, or the fieldless BasicFile) based on its __typename. On servers that expose the file reverse-relationship resolvers (stashapp/stash #6938), the reverse relationships (scenes, images, galleries) are populated in the same query; on older servers they are left UNSET (there is no per-file fallback in the bulk path — use populate() on an individual file for the path-filter fallback).
Supported FileFilterType filters
Django-style kwargs translate directly for the scalar FileFilterType fields:
Known limitation: list-membership and complex file filters
The kwargs shorthand does not auto-translate everyFileFilterType field. These must be passed as raw filter dicts (matching the GraphQL input shape), and list-membership values must be given as explicit lists:
zip_file(MultiCriterionInput) andparent_folder(HierarchicalMultiCriterionInput) — the shorthand will not wrap a single value into a list; pass{"value": [ids], "modifier": "INCLUDES"}.hashes([FingerprintFilterInput!]) andduplicated(FileDuplicationCriterionInput) — no shorthand; pass the raw dict.
See Also
- UNSET Pattern: Understanding unqueried vs null fields
- Identity Map: Object caching and identity
- Entity Store API: Full API reference
- Usage Patterns: Common usage scenarios