Skip to main content

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:

  1. Excessive API Calls: Typing 'test' would fire 4 separate API calls (one for each letter: 't', 'te', 'tes', 'test')
  2. Poor User Experience: No visual feedback about search terms or performance
  3. Automatic Search: Search triggered automatically on every keystroke after 1 second delay
  4. 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​

  1. Explicit Control: Users control when searches are executed
  2. Visual Feedback: Loading indicators and performance statistics
  3. Multiple Terms: Support for complex search queries
  4. Term Management: Easy addition/removal of search terms
  5. Performance Transparency: Users see search execution time and result counts

Technical Benefits​

  1. Reduced Server Load: Fewer unnecessary API calls
  2. Better Resource Usage: No redundant searches
  3. Improved Responsiveness: Faster UI interactions
  4. Enhanced Debugging: Performance metrics for troubleshooting
  5. Scalability: Better performance with large datasets

Usage Guidelines​

For Users:​

  1. Type search terms in the search field (separate multiple terms with commas or spaces)
  2. Click the Search button or press Enter to execute the search
  3. View performance statistics below the search field
  4. Remove individual search terms by clicking the X on term chips

For Developers:​

  1. The search now uses explicit actions instead of automatic triggers
  2. Multiple search terms are joined with spaces before sending to the API
  3. Performance monitoring is built-in for debugging
  4. 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​

  1. Search History: Store and recall previous searches
  2. Advanced Filters: Integration with faceted search
  3. Search Suggestions: Auto-complete based on previous searches
  4. Saved Searches: Allow users to save complex search queries
  5. Search Analytics: Track search patterns and optimization opportunities