Skip to content

v0.9.0

Choose a tag to compare

@cwt cwt released this 08 Sep 07:49
· 727 commits to main since this release

NeoSQLite v0.9.0 Release Notes

Overview

This release focuses on continued enhancements to NeoSQLite's aggregation pipeline processing and query engine capabilities. Key improvements include expanded SQL-based optimization for complex aggregation pipelines, enhanced text search functionality, comprehensive implementation of missing PyMongo-compatible APIs and operators, and significant improvements to binary data handling. The release also includes a major reorganization of test files for better maintainability and code coverage.

Highlights

Enhanced Aggregation Pipeline Processing

  • Expanded SQL Optimization Coverage: Increased SQL optimization coverage from ~85% to over 95% of common aggregation pipelines through temporary table processing
  • Three-Tier Processing Model: Implemented sophisticated three-tier approach for aggregation processing: 1) Single SQL Query optimization (fastest), 2) Temporary Table Aggregation (intermediate), 3) Python Fallback (slowest but most flexible)
  • Granular Pipeline Processing: Individual unsupported stages can now fall back to Python processing while keeping others in SQL for hybrid pipeline operations
  • Improved Resource Management: Intermediate results now stored in temporary tables rather than Python memory, enabling processing of larger datasets
  • Position Independence: Operations like $lookup can now be used in any pipeline position, not just at the end
  • Enhanced $unwind Support: Fully implemented $unwind with all advanced options including includeArrayIndex and preserveNullAndEmptyArrays

Hybrid Text Search Processing

  • Performance Enhancement: Instead of falling back the entire pipeline to Python processing when a $text operator is encountered without FTS indexes, the system now processes compatible stages with SQL optimization and only falls back to Python for the specific text search operation
  • Three-Tier Processing for Text Search: Pipelines are now processed as follows:
    1. Stages 1 to N-1: Process using SQL with temporary tables
    2. Stage N (with $text): Process with Python-based text search
    3. Stages N+1 to M: Continue processing with SQL using temporary tables
  • Resource Efficiency: Only matching documents are loaded for text search, significantly reducing memory usage
  • Enhanced Text Search Capabilities: Improved international character support with diacritic-insensitive matching and Unicode normalization
  • Selective Fallback: Only text search operations fall back to Python processing while other pipeline stages continue to benefit from SQL optimization

Comprehensive API Implementation

  • Missing API Coverage: Implemented approximately 95%+ of the core PyMongo Collection APIs that were previously missing
  • Logical Operators: Fully implemented $and, $or, $not, and $nor logical operators
  • Element Operators: Implemented $type element operator for type-based document selection
  • Array Operators: Implemented $all array operator for matching arrays that contain all specified elements
  • Collection Management: Added drop(), create_collection(), list_collection_names(), and list_collections() methods
  • Advanced Aggregation: Implemented aggregate_raw_batches() for efficient batch processing of large aggregation results
  • Search Index APIs: Added comprehensive FTS5-based search index functionality with create_search_index(), create_search_indexes(), drop_search_index(), list_search_indexes(), and update_search_index() methods

Enhanced Binary Data Handling

  • Automatic Conversion: Raw bytes are now automatically converted to Binary objects with proper JSON serialization during insert and update operations
  • Subtype Preservation: Binary objects preserve their subtypes (FUNCTION, UUID, MD5, etc.) during database operations
  • Nested Structure Support: Binary data handling now works correctly in nested documents and arrays
  • SQL Update Support: Binary data can now be used in SQL-based update operations with proper serialization

Package Structure Reorganization

  • Modular Organization: Cursor classes have been moved from the root package to the collection module for better code organization
  • Improved Maintainability: Related functionality is now grouped more logically within the package structure
  • Backward Compatibility: All public APIs remain accessible through the same import paths
  • Test Suite Reorganization: Consolidated test files for better maintainability and code coverage

Enhanced Documentation

  • Comprehensive Docstrings: Added detailed docstrings throughout the codebase explaining functionality, parameters, and return values
  • Implementation Documentation: Added complete specification documents for all major enhancements
  • Improved Code Clarity: Better comments and documentation make the codebase more approachable for new contributors

New Features

Aggregation Pipeline Enhancements

  • Temporary Table Aggregation: Introduced a new three-tier processing model that bridges SQL optimization and Python fallback
  • Enhanced $unwind Support: Fully implemented $unwind with all advanced options including includeArrayIndex and preserveNullAndEmptyArrays
  • $lookup Position Independence: $lookup operations can now be used in any pipeline position, not just at the end
  • Multi-Stage Pipeline Optimization: Complex pipelines with multiple $unwind, $lookup, $group, and $sort stages can now be processed efficiently
  • Database-Level Intermediate Processing: Intermediate results processed at database level rather than Python level
  • Automatic Resource Management: Robust transaction-based cleanup with guaranteed resource release using SQLite SAVEPOINTs

Query Operator Implementations

  • Logical Operators: Fully implemented $and, $or, $not, and $nor operators for complex query construction
  • Element Operators: Implemented $type operator for selecting documents based on field type
  • Array Operators: Implemented $all operator for matching arrays that contain all specified elements
  • Query Validation: Enhanced query validation with proper error handling for malformed queries

Collection Management APIs

  • drop() Method: Drop the entire collection (table in SQLite)
  • create_collection() Method: Create a new collection with specific options
  • list_collection_names() Method: List all collection names in the database
  • list_collections() Method: Get detailed information about collections

Advanced Aggregation Features

  • aggregate_raw_batches() Method: Perform aggregation and retrieve raw BSON batches for efficient processing of large results
  • Batch Processing: Efficient batch insertion of text search results into temporary tables for better performance
  • Pipeline Validation Updates: Modified can_process_with_temporary_tables() to allow pipelines containing $text operators

Search Index APIs

  • create_search_index() Method: Create a single search index using FTS5
  • create_search_indexes() Method: Create multiple search indexes at once
  • drop_search_index() Method: Drop a search index
  • list_search_indexes() Method: List search indexes
  • update_search_index() Method: Update a search index
  • Enhanced Text Search Implementation: New unified_text_search function in neosqlite.collection.text_search module provides enhanced text search capabilities

Binary Data Handling Improvements

  • Automatic Bytes Conversion: Raw bytes are automatically converted to Binary objects during insert and update operations
  • Subtype Preservation: Binary objects preserve their subtypes (FUNCTION, UUID, MD5, etc.) during database operations
  • Nested Structure Support: Binary data handling now works correctly in nested documents and arrays
  • SQL Update Support: Binary data can now be used in SQL-based update operations with proper serialization

Package Reorganization

  • Cursor Module Relocation: AggregationCursor, Cursor, and RawBatchCursor classes moved to neosqlite.collection submodules
  • Cleaner Import Structure: Related classes are now grouped more logically within the package structure
  • Maintained API Compatibility: All existing import paths continue to work without changes for end users
  • Test Suite Consolidation: Consolidated test files for better organization and maintainability

Performance Improvements

  • Significant Performance Gains: Pipelines with text search operations see 50%+ performance improvement over previous Python fallback approach
  • Reduced Memory Usage: Only relevant documents are loaded for text search operations, dramatically reducing memory footprint
  • Optimized Batch Operations: Batch insertion of text search results improves processing efficiency for large datasets
  • Maintained SQL Optimization: Non-text stages continue to benefit from SQL processing performance
  • Expanded SQL Coverage: Process 95%+ of common aggregation pipelines at SQL level vs. ~85% previously
  • Better Resource Management: Database-level processing for most operations with automatic temporary table management
  • Enhanced Maintainability: Improved code organization and comprehensive documentation

Technical Benefits

  • Better Resource Management: Database-level processing for most operations with automatic temporary table management
  • Enhanced Maintainability: Improved code organization and comprehensive documentation
  • Robust Error Handling: Comprehensive error handling for edge cases and invalid text search specifications
  • Extensibility: Modular design allows for future enhancements like parallel processing and caching
  • Automatic Cleanup: Guaranteed cleanup with transaction-based atomicity
  • Backward Compatibility: 100% backward compatibility with existing code
  • Enhanced Type Safety: Comprehensive type annotations throughout the codebase

Breaking Changes

There are no intentional breaking changes in this release. All existing APIs and functionality remain fully compatible with previous versions.

Installation

# Standard installation
pip install neosqlite

# For enhanced JSON/JSONB support
pip install neosqlite[jsonb]

# For memory-constrained processing of large result sets
pip install neosqlite[memory-constrained]

# Install multiple extras
pip install neosqlite[jsonb,memory-constrained]

Notable Features

Enhanced Aggregation Pipeline Example

# Complex pipeline now processed more efficiently
pipeline = [
    {"$match": {"status": "active"}},           # SQL - Filter to 1,000 docs
    {"$sort": {"created": -1}},                 # SQL - Sort 1,000 docs
    {"$match": {"$text": {"$search": "python"}}}, # Python - Filter to 50 docs
    {"$limit": 10}                              # SQL - Take first 10 docs
]

# NeoSQLite will automatically:
# 1. Process first match with SQL (10,000 → 1,000 docs)
# 2. Sort with SQL (1,000 docs)
# 3. Apply text search with Python (1,000 → 50 docs)
# 4. Apply limit with SQL (50 → 10 docs)
cursor = collection.aggregate(pipeline)

Full $unwind Support Example

# NeoSQLite now supports all $unwind options
pipeline = [
    {
        "$unwind": {
            "path": "$items",
            "includeArrayIndex": "itemIndex",
            "preserveNullAndEmptyArrays": True
        }
    }
]
result = collection.aggregate(pipeline)

Enhanced Text Search Example

# Text search now supports international characters with diacritic-insensitive matching
documents = [
    {"name": "José María", "location": "España"},
    {"name": "François Dubois", "location": "France"},
    {"name": "Björk Guðmundsdóttir", "location": "Ísland"}
]

collection.insert_many(documents)

# These searches will all match the appropriate documents:
result1 = list(collection.find({"$text": {"$search": "Jose"}}))  # Matches José María
result2 = list(collection.find({"$text": {"$search": "espana"}}))  # Matches España
result3 = list(collection.find({"$text": {"$search": "Bjork"}}))  # Matches Björk

Binary Data Handling Example

# NeoSQLite now automatically handles binary data
raw_bytes = b"\x00\x01\x02\x03"

# Insert raw bytes (automatically converted to Binary)
result = collection.insert_one({"data": raw_bytes})

# Retrieve (returns as Binary object)
doc = collection.find_one({"_id": result.inserted_id})
print(type(doc["data"]))  # <class 'neosqlite.Binary'>
print(doc["data"].subtype)  # 0 (default binary subtype)

Search Index APIs Example

# Create FTS search indexes for text search
users.create_search_index('bio')
users.create_search_indexes(['title', 'content', 'description'])

# List search indexes
indexes = users.list_search_indexes()

# Drop a search index
users.drop_search_index('bio')

# Update a search index (drops and recreates)
users.update_search_index('content')

Package Reorganization Example

# All existing import patterns continue to work unchanged:
from neosqlite import AggregationCursor, Cursor, RawBatchCursor

# But internally, these classes are now organized in the collection module:
# from neosqlite.collection.aggregation_cursor import AggregationCursor
# from neosqlite.collection.cursor import Cursor
# from neosqlite.collection.raw_batch_cursor import RawBatchCursor

This release represents a significant advancement in NeoSQLite's aggregation pipeline capabilities while improving the overall maintainability of the codebase through better organization, comprehensive API implementation, and enhanced documentation. The expanded SQL optimization coverage provides substantial performance benefits for aggregation pipelines while maintaining full backward compatibility.