Retrieving and Filtering Notes
This guide shows you how to retrieve and filter notes from private storage using NoteGetterOptions.
Prerequisites
- Aztec contract with note storage
- Understanding of note structure and properties
- Familiarity with PropertySelector and Comparator
Set up basic note retrieval
Step 1: Create default options
let mut options = NoteGetterOptions::new();
This returns up to MAX_NOTE_HASH_READ_REQUESTS_PER_CALL notes without filtering.
Step 2: Retrieve notes from storage
let notes = storage.my_notes.at(owner).get_notes(options);
Filter notes by properties
Step 1: Select notes with specific field values
// Assuming MyNote has an 'owner' field
let mut options = NoteGetterOptions::new();
options = options.select(
MyNote::properties().owner,
Comparator.EQ,
owner
);
Step 2: Apply multiple selection criteria
let mut options = NoteGetterOptions::new();
options = options
.select(MyNote::properties().value, Comparator.EQ, value)
.select(MyNote::properties().owner, Comparator.EQ, owner);
tip
Chain multiple select calls to filter by multiple fields. Remember to call get_notes(options) after applying all your selection criteria to retrieve the filtered notes.
Sort retrieved notes
Sort and paginate results
let mut options = NoteGetterOptions::new();
options = options
.select(MyNote::properties().owner, Comparator.EQ, owner)
.sort(MyNote::properties().value, SortOrder.DESC)
.set_limit(10) // Max 10 notes
.set_offset(20); // Skip first 20
Apply custom filters
Filter Performance
Database select is more efficient than custom filters. Use custom filters only for complex logic.
Create and use a custom filter
fn filter_above_threshold(
notes: [Option<RetrievedNote<Note>>; MAX_NOTES],
min: Field,
) -> [Option<RetrievedNote<Note>>; MAX_NOTES] {
let mut result = [Option::none(); MAX_NOTES];
let mut count = 0;
for note in notes {
if note.is_some() & (note.unwrap().note.value >= min) {
result[count] = note;
count += 1;
}
}
result
}
// Use the filter
let options = NoteGetterOptions::with_filter(filter_above_threshold, min_value);
Note Limits
Maximum notes per call: MAX_NOTE_HASH_READ_REQUESTS_PER_CALL (currently 128)
Available Comparators
EQ: Equal toNEQ: Not equal toLT: Less thanLTE: Less than or equalGT: Greater thanGTE: Greater than or equal
Use comparators effectively
Available comparators
// Equal to
options.select(MyNote::properties().value, Comparator.EQ, target_value)
// Greater than or equal
options.select(MyNote::properties().value, Comparator.GTE, min_value)
// Less than
options.select(MyNote::properties().value, Comparator.LT, max_value)
Call from TypeScript with comparator
// Pass comparator from client
contract.methods.read_notes(Comparator.GTE, 5).simulate({ from: defaultAddress })
View notes without constraints
use dep::aztec::note::note_viewer_options::NoteViewerOptions;
#[external("utility")]
unconstrained fn view_notes(comparator: u8, value: Field) -> auto {
let mut options = NoteViewerOptions::new();
options = options.select(MyNote::properties().value, comparator, value);
storage.my_notes.view_notes(options)
}
Viewer vs Getter
NoteGetterOptions: For constrained functions (private/public)NoteViewerOptions: For unconstrained viewing (utilities)
Query notes with different status
Set status to include nullified notes
let mut options = NoteGetterOptions::new();
options.set_status(NoteStatus.ACTIVE_OR_NULLIFIED);
Note Status Options
NoteStatus.ACTIVE: Only active (non-nullified) notes (default)NoteStatus.ACTIVE_OR_NULLIFIED: Both active and nullified notes
Optimize note retrieval
Best Practices
- Use select over filter - Database-level filtering is more efficient
- Set limits early - Reduce unnecessary note processing
- Sort before limiting - Get the most relevant notes first
- Batch operations - Retrieve all needed notes in one call
Example: Optimized retrieval
// Get highest value note for owner
let mut options = NoteGetterOptions::new();
options = options
.select(MyNote::properties().owner, Comparator.EQ, owner)
.sort(MyNote::properties().value, SortOrder.DESC)
.set_limit(1);
let notes = storage.my_notes.at(owner).get_notes(options);
assert(notes.len() > 0, "No notes found");
let highest_note = notes.get(0);
Next steps
- Learn about custom note implementations
- Explore note discovery mechanisms
- Understand note lifecycle