Overview
This guide covers migrating from Ditto’s legacy query builder API to DQL (Ditto Query Language) in Java. DQL provides a SQL-like syntax that’s more powerful and intuitive for querying and manipulating data. Note: This migration is required alongside the V4→V5 API Migration for a complete upgrade.AI Agent Prompt
Use this prompt when working with an AI coding assistant to migrate your Ditto Java app to DQL.Copy AI Migration Prompt (Click to Expand)
Copy AI Migration Prompt (Click to Expand)
Document Query Syntax
Query All Documents
Query Document by ID
Query with Predicate
Query with Parameterized Arguments
Insert, Update, Delete, Eviction
Insert Document
Update Document
Delete Document
Evict All Documents Matching Condition
Query Response Handling
Working with Query Results
Observer Migration
Observing Query Results
- DQL observers use
registerObserver(query, args, callback)instead of.observe() - Results are
List<Map<String, Object>>instead ofList<DittoDocument> - Same cleanup pattern with
.stop()
Sync Subscriptions Migration
Creating Sync Subscriptions
- DQL subscriptions use
registerSubscription(query, args)instead of.subscribe() - Cleanup now uses
.cancel()instead of.close()
Counter Type Migration
Updating Counter Values
PN_COUNTER is the DQL equivalent of the legacy
DittoCounter type. When migrating counter operations from the legacy query builder’s counter methods, use PN_INCREMENT BY in the APPLY clause. This maintains full compatibility with existing counter data created by DittoCounter.- Never initialize counter fields in INSERT statements - they start at 0 automatically when incremented
- Use
PN_INCREMENT BYin theAPPLYclause for counter operations - Positive values increment, negative values decrement
- Counter values are read as integers in SELECT queries
Attachment Operations
Fetching Attachments
Performance Enhancements
Indexes for Improved Query Performance
DQL observers and queries benefit significantly from proper indexing. When migrating from the legacy query builder to DQL, creating indexes on frequently queried fields is essential for maintaining optimal performance. Why Indexes Matter for DQL:- DQL observers support advanced features like aggregates and projections
- These advanced features require full database scans to ensure consistent results
- Indexes dramatically reduce query execution time by avoiding full scans
- Combining indexes with observers provides better performance than legacy query builder
- Create indexes on fields used in
WHEREclauses - Create indexes before registering observers for those queries
- Use compound indexes for queries with multiple filter conditions
- Monitor query performance and add indexes as needed
Common Pitfalls to Avoid
1. DQL Syntax Errors
Use:paramName for parameters, not string literals or concatenation.
2. Missing Parameter Binding
NEVER use string concatenation in queries. Always use parameterized queries withMap<String, Object>.
3. Counter Type Errors
UseCOUNTER annotation in collection definitions. Do NOT use SET with COUNTER fields. Use APPLY with PN_INCREMENT BY. Pass negative values for decrements.
4. Memory Management with Observers
Callitem.close() after extracting data from QueryResultItems. Always close observers when done. Use indexes for improved memory and performance.
5. Attachment Handling
UseATTACHMENT annotation in collection definitions. Create attachments with ditto.getStore().newAttachment().
Migration Checklist
- Replace all
.collection().find()with DQL SELECT queries - Replace all
.collection().findById()with DQL SELECT with_idfilter - Replace all
.collection().upsert()with DQL INSERT statements - Replace all
.update()callbacks with DQL UPDATE statements - Replace all
.remove()with DQL EVICT statements - Update all observers to use
registerObserver(query, args, callback) - Update all subscriptions to use
registerSubscription(query, args) - Convert counter operations to use
PN_INCREMENT BYin APPLY clause - Remove counter field initialization from INSERT statements
- Add
nullas second argument for queries without parameters - Update result handling from
DittoDocumenttoMap<String, Object> - Verify attachment fetching uses tokens from query results