Search Optimization Implementation
Overview​
This document describes the search optimization improvements made to reduce excessive API calls and improve the user experience in the OpenRegister search functionality.
Problem Statement​
The original search implementation had several performance issues:
- Excessive API Calls: Typing 'test' would fire 4 separate API calls (one for each letter: 't', 'te', 'tes', 'test')
- Poor User Experience: No visual feedback about search terms or performance
- Automatic Search: Search triggered automatically on every keystroke after 1 second delay
- Limited Search Capabilities: Only single search terms supported
Solution Implementation​
1. Explicit Search Action​
Before:
// Automatic search on every keystroke
searchQuery(value) {
if (this.searchTimeout) {
clearTimeout(this.searchTimeout)
}
this.searchTimeout = setTimeout(() => {
// API call triggered automatically
objectStore.refreshObjectList(...)
}, 1000)
}
After:
// Explicit search action
async performSearch() {
if (!this.canSearch) return;
this.searchLoading = true;
const startTime = performance.now();
// Only trigger API call when user explicitly searches
await objectStore.refreshObjectList({...});
// Show performance feedback
const endTime = performance.now();
this.lastSearchStats = {
total: this.totalItems,
time: (endTime - startTime).toFixed(0),
};
}
2. Multiple Search Terms Support​
Features:
- Support for comma and space-separated search terms
- Visual representation with chips
- Individual term removal capability
Implementation:
handleSearchInput() {
this.searchTerms = this.searchQuery.split(/[\s,]+/).filter(term => term.trim() !== '');
},
removeSearchTerm(index) {
this.searchTerms.splice(index, 1);
this.searchQuery = this.searchTerms.join(' ');
this.performSearch();
}
3. Enhanced User Interface​
Search Section Features:
- Moved to top of sidebar for better UX
- Search button with loading indicator
- Visual search term chips
- Performance statistics display
- Dynamic placeholder text
Template Structure:
<div class="searchSection">
<h3>{{ t('openregister', 'Search Objects') }}</h3>
<div class="searchGroup">
<NcTextField v-model="searchQuery" />
<NcButton @click="performSearch">
<template #icon>
<NcLoadingIcon v-if="searchLoading" />
<Magnify v-else />
</template>
{{ t('openregister', 'Search') }}
</NcButton>
</div>
<!-- Search term chips -->
<div v-if="searchTerms.length > 0" class="search-terms">
<NcChip v-for="(term, index) in searchTerms"
:key="index"
:text="term"
@delete="removeSearchTerm(index)" />
</div>
<!-- Performance stats -->
<div v-if="lastSearchStats" class="search-stats">
{{ t('openregister', 'Found {total} objects in {time}ms', lastSearchStats) }}
</div>
</div>
4. Performance Monitoring​
Search Statistics:
- Total results found
- Search execution time in milliseconds
- Real-time feedback to users
Implementation:
// Performance timing
const startTime = performance.now();
await objectStore.refreshObjectList({...});
const endTime = performance.now();
this.lastSearchStats = {
total: this.totalItems,
time: (endTime - startTime).toFixed(0),
};
API Integration​
The optimized search works with the existing ObjectsController.php and ObjectService.php:
API Endpoint:
GET /index.php/apps/openregister/api/objects/{register}/{schema}
Parameters:
_search: Combined search terms (space-separated)_limit: Results per page_page: Current page_facetable: Include facetable field discovery_facets: Facet configuration
Example Request:
GET /api/objects/4/22?_limit=20&_page=1&_search=test%20example&_facetable=true
Performance Improvements​
Before Optimization:​
- 4 API calls for typing 'test' (t, te, tes, test)
- Automatic triggering on every keystroke
- No performance feedback for users
- Single search term limitation
After Optimization:​
- 1 API call per explicit search action
- User-controlled search execution
- Real-time performance stats (execution time, result count)
- Multiple search terms with visual management
- Better UX with loading states and feedback
User Experience Improvements​
- Explicit Control: Users control when searches are executed
- Visual Feedback: Loading indicators and performance statistics
- Multiple Terms: Support for complex search queries
- Term Management: Easy addition/removal of search terms
- Performance Transparency: Users see search execution time and result counts
Technical Benefits​
- Reduced Server Load: Fewer unnecessary API calls
- Better Resource Usage: No redundant searches
- Improved Responsiveness: Faster UI interactions
- Enhanced Debugging: Performance metrics for troubleshooting
- Scalability: Better performance with large datasets
Usage Guidelines​
For Users:​
- Type search terms in the search field (separate multiple terms with commas or spaces)
- Click the Search button or press Enter to execute the search
- View performance statistics below the search field
- Remove individual search terms by clicking the X on term chips
For Developers:​
- The search now uses explicit actions instead of automatic triggers
- Multiple search terms are joined with spaces before sending to the API
- Performance monitoring is built-in for debugging
- The UI provides comprehensive feedback to users
Migration Notes​
Breaking Changes:​
- Removed automatic search on typing
- Search now requires explicit user action
Backward Compatibility:​
- API endpoints remain unchanged
- Search parameters format is preserved
- Existing search functionality is enhanced, not replaced
Future Enhancements​
- Search History: Store and recall previous searches
- Advanced Filters: Integration with faceted search
- Search Suggestions: Auto-complete based on previous searches
- Saved Searches: Allow users to save complex search queries
- Search Analytics: Track search patterns and optimization opportunities