The query module provides a powerful, fluent API for constructing complex queries over indexed text content using semantic descriptors.
-
query/predicates.py- Query predicates- Base
Predicateclass with logical operators - Field predicates:
FieldEquals,FieldIn,FieldStartsWith - Hierarchy predicates:
HierarchyMatches,HierarchyDepth - Text predicates:
TextContains,TextMatches - Metadata predicates:
MetadataEquals,MetadataExists - Timestamp predicates:
CreatedAfter,CreatedBefore,UpdatedAfter - Logical operators:
AndPredicate,OrPredicate,NotPredicate - Custom predicates:
CustomPredicate
- Base
-
query/filters.py- High-level filtersFilterclass - Fluent filter builder- Convenience functions:
find_research_posts,find_tutorials,find_by_author, etc. - Domain-specific helpers
-
query/query_builder.py- Query builderQueryBuilder- Main fluent query APIQueryResult- Result container with metadata- Chainable methods for all query types
- Sorting and pagination
- Query explanation
-
query/explain.py- Query explanationsexplain_query()- Human-readable query explanationsexplain_result()- Result analysisexplain_predicate_tree()- Predicate visualizationexplain_why_matched()/explain_why_not_matched()- Match explanationsQueryExplainer- Interactive explainer class- Result comparison and statistics
-
query/__init__.py- Public API -
examples/query_example.py- 12 comprehensive examples
- Type-safe predicate classes
- Composable with logical operators (
&,|,~) - Human-readable explanations
- Custom predicate support
- Lazy evaluation
- Fluent, chainable API
- Type-specific methods (domain, intent, tone, etc.)
- Hierarchy-aware querying
- Text search
- Metadata filtering
- Timestamp filtering
- Sorting (by any field)
- Pagination (limit/offset)
- Query cloning
- High-level
Filterclass - Convenience functions for common patterns
- Domain-specific helpers
- Method chaining
- Query explanations (natural language)
- Result statistics
- Predicate tree visualization
- Match/non-match explanations
- Query comparison
- Field distribution analysis
# Predicates are composable
bio = HierarchyMatches('domain', 'Science → Biology')
research = HierarchyMatches('intent', 'Research')
# Combine with operators
combined = bio & research # AND
either = bio | research # OR
not_bio = ~bio # NOTresult = (QueryBuilder(index)
.where_domain("Science → Biology", exact=False)
.where_intent("Research", exact=False)
.where_stability("Peer-reviewed")
.order_by_created(descending=True)
.limit(10)
.execute())# QueryBuilder - Full power
QueryBuilder(index).where_domain("Science").execute()
# Filter - Alternative fluent API
Filter().from_index(index).where_domain("Science").execute()
# Convenience functions - Quick common patterns
find_research_posts(items, domain="Science")from query import QueryBuilder
result = (QueryBuilder(index)
.where_domain("Science → Biology")
.execute())
print(f"Found {result.total} items")result = (QueryBuilder(index)
.where_domain("Science → Biology", exact=False)
.where_intent("Research", exact=False)
.where_stability("Peer-reviewed")
.where_audience("Researchers")
.execute())from query import FieldEquals, HierarchyMatches
tutorial = HierarchyMatches('intent', 'Documentation → Tutorial')
beginner = FieldEquals('audience', 'Beginners')
result = (QueryBuilder(index)
.or_where(tutorial, beginner)
.execute())result = (QueryBuilder(index)
.where_text_contains("machine learning", case_sensitive=False)
.where_domain("Science → Computer Science", exact=False)
.execute())# Get 10 most recent items
result = (QueryBuilder(index)
.order_by_created(descending=True)
.limit(10)
.execute())
# Page 2 (items 11-20)
result = (QueryBuilder(index)
.order_by_created(descending=True)
.offset(10)
.limit(10)
.execute())def long_text(item):
return len(item.text) > 1000
result = (QueryBuilder(index)
.where_custom(long_text, "text length > 1000")
.execute())from query import QueryExplainer
result = (QueryBuilder(index)
.where_domain("Science")
.where_intent("Research")
.execute())
explainer = QueryExplainer(result)
print(explainer.detailed()) # Full analysis
print(explainer.items()) # Item summaries# Manual composition
from query import AndPredicate, OrPredicate, NotPredicate
bio = HierarchyMatches('domain', 'Science → Biology')
physics = HierarchyMatches('domain', 'Science → Physics')
research = HierarchyMatches('intent', 'Research')
# (Bio OR Physics) AND Research
science = OrPredicate(bio, physics)
query = AndPredicate(science, research)
result = QueryBuilder(index).where(query).execute()from query import HierarchyDepth
# Find items with specific hierarchy depth
result = (QueryBuilder(index)
.where(HierarchyDepth('domain', min_depth=2, max_depth=3))
.execute())from datetime import datetime, timedelta
yesterday = datetime.now() - timedelta(days=1)
result = (QueryBuilder(index)
.where_created_after(yesterday)
.order_by_created(descending=True)
.execute())# Find by author
result = (QueryBuilder(index)
.where_metadata('author', 'Dr. Smith')
.execute())
# Check if metadata exists
result = (QueryBuilder(index)
.where_metadata_exists('doi')
.execute())# Create base query
base = (QueryBuilder(index)
.where_domain("Science")
.where_intent("Research"))
# Clone and specialize
biology = base.clone().where_domain("Science → Biology")
physics = base.clone().where_domain("Science → Physics")result = (QueryBuilder(index)
.where_domain("Science → Biology")
.where_stability("Peer-reviewed")
.execute())
print(result.query_explanation)
# "SELECT items WHERE (domain under 'Science → Biology'
# AND stability = 'Peer-reviewed')"from query import explain_why_matched
item = result.items[0]
predicate = builder.build_predicate()
explanation = explain_why_matched(item, predicate)
print(explanation)
# "Item abc123 matched because:
# All of the following were true:
# • domain = 'Science → Biology → Systems Biology'
# (matched hierarchy 'Science → Biology')
# • stability = 'Peer-reviewed'
# (matched 'Peer-reviewed')"from query import QueryExplainer
explainer = QueryExplainer(result)
stats = explainer.statistics()
print(stats)
# {
# 'total': 5,
# 'returned': 5,
# 'query': '...',
# 'field_distribution': {
# 'domain': Counter({'Science → Biology': 3, ...}),
# 'intent': Counter({'Research → Empirical': 2, ...})
# }
# }from query import explain_predicate_tree
combined = (bio_pred & research_pred) | tutorial_pred
print(explain_predicate_tree(combined))
# OR:
# AND:
# • domain under 'Science → Biology'
# • intent under 'Research'
# • intent = 'Documentation → Tutorial'from query import (
find_research_posts,
find_tutorials,
find_by_author,
find_recent,
search_text,
)
# Find research posts in biology
research = find_research_posts(
items,
domain="Science → Biology",
stability="Peer-reviewed"
)
# Find tutorials
tutorials = find_tutorials(items, domain="Engineering")
# Find by author
smith_posts = find_by_author(items, "Dr. Smith")
# Find recent items
recent = find_recent(items, since=yesterday)
# Search text
ai_posts = search_text(items, "artificial intelligence")- Uses semantic descriptors for querying
- Hierarchy-aware via core normalization
- Respects semantic field structure
- Queries TextIndex directly
- Works with IndexedText objects
- Leverages metadata system
- QueryBuilder serializable to JSON
- Query explanations suitable for HTTP responses
- Result pagination ready for REST APIs
- Linear scan: O(n) where n = number of items
- Predicate evaluation: O(1) per item
- Sorting: O(n log n) when ordering
- Filtering: No intermediate allocations
- Index-based lookups (future)
- Predicate short-circuiting (implemented)
- Lazy evaluation (implemented)
- Query result caching (future)
- Current: Optimized for 10K-100K items
- Predicates are lightweight and composable
- Explanation overhead is minimal
- Memory efficient (no duplication)
- Fluent, chainable API
- Type-safe predicates
- Composable with operators
- Human-readable explanations
- Multiple API styles
- Zero external dependencies
- Comprehensive docstrings
- 12 usage examples
- Explainability first
- Custom predicate support
This implementation embodies the project's core values:
- Explicit predicate classes
- Clear method names
- Obvious behavior
- Every query can be explained
- Match/non-match reasons provided
- Predicate tree visualization
- Queries based on semantic meaning
- No hidden scoring algorithms
- Transparent filtering
- Multiple API styles for different preferences
- Helpful error messages
- Educational explanations
# Find cautious, early-stage research
result = (QueryBuilder(index)
.where_domain("Science", exact=False)
.where_intent("Research → Conceptual → Early-stage")
.where_tone("Analytical / Cautious")
.where_stability("Hypothesis")
.execute())# Find answered questions
result = (QueryBuilder(index)
.where_intent("Discussion → Question")
.where_metadata_exists('accepted_answer')
.execute())# Find validated documentation
result = (QueryBuilder(index)
.where_intent("Documentation", exact=False)
.where_stability("Validated")
.order_by_updated(descending=True)
.execute())Status: Query module complete and production-ready
Dependencies: Core module, Indexer module
Ready for: API development, production use, advanced applications