Algolia Core Workflow B — Indexing & Data Sync
Overview
Keep your Algolia index synchronized with your source database. Covers full reindex, incremental updates, partial updates, synonyms, and query rules.
Prerequisites
- Completed
algolia-install-auth setup
- Familiarity with
algolia-core-workflow-a (search)
- Source database or API with change tracking (timestamps, events)
Instructions
Step 1: Full Reindex with replaceAllObjects
import { algoliasearch } from 'algoliasearch';
const client = algoliasearch(process.env.ALGOLIA_APP_ID!, process.env.ALGOLIA_ADMIN_KEY!);
async function fullReindex(records: Record<string, any>[]) {
const { taskID } = await client.replaceAllObjects({
indexName: 'products',
objects: records,
batchSize: 1000,
});
await client.waitForTask({ indexName: 'products', taskID });
console.log(`Full reindex complete: ${records.length} records`);
}
Step 2: Incremental Updates with partialUpdateObject
async function updateProductPrice(objectID: string, newPrice: number) {
await client.partialUpdateObject({
indexName: 'products',
objectID,
attributesToUpdate: {
price: newPrice,
updated_at: new Date().toISOString(),
},
createIfNotExists: false,
});
}
async function syncPriceChanges(changes: { id: string; price: number }[]) {
const { taskID } = await client.partialUpdateObjects({
indexName: 'products',
objects: changes.map(c => ({
objectID: c.id,
price: c.price,
updated_at: new Date().toISOString(),
})),
createIfNotExists: false,
});
await client.({ : , taskID });
}
Step 3: Manage Synonyms
await client.saveSynonyms({
indexName: 'products',
synonymHit: [
{
objectID: 'syn-1',
type: 'synonym',
synonyms: ['laptop', 'notebook', 'portable computer'],
},
{
objectID: 'syn-2',
type: 'oneWaySynonym',
input: 'phone',
synonyms: ['smartphone', 'mobile phone', 'cell phone'],
},
{
objectID: 'syn-3',
type: 'altCorrection1',
word: 'color',
corrections: ['colour'],
},
{
objectID: 'syn-4',
type: 'placeholder',
placeholder: '<size>',
replacements: ['small', 'medium', 'large', 'XL'],
},
],
forwardToReplicas: ,
: ,
});
Step 4: Configure Query Rules
await client.saveRule({
indexName: 'products',
objectID: 'rule-sale-banner',
rule: {
conditions: [{
anchoring: 'contains',
pattern: 'sale',
}],
consequence: {
promote: [{ objectID: 'promo-banner-sale', position: 0 }],
params: {
filters: 'on_sale = true',
},
},
description: 'When user searches "sale", filter to sale items and pin banner',
enabled: true,
},
});
await client.saveRule({
indexName: 'products',
objectID: 'rule-hide-discontinued',
rule: {
conditions: [{ anchoring: 'is', pattern: '' }],
consequence: {
hide: [{ objectID: 'discontinued-product-123' }],
},
description: 'Hide discontinued product from all searches',
: ,
},
});
Error Handling
| Error | Cause | Solution |
|---|
Record is too big (limit: 10KB) | Object exceeds free-tier limit | Strip unnecessary fields; paid plans allow 100KB |
Synonym already exists | Duplicate objectID | Use replaceExistingSynonyms: true or unique IDs |
Invalid rule condition | Wrong anchoring value | Use is, startsWith, endsWith, or contains |
| Partial update creates new record | createIfNotExists default is true | Set createIfNotExists: false |
Examples
Database Change Listener → Algolia Sync
import { getClient } from './algolia/client';
async function onDatabaseChange(event: { type: string; record: any }) {
const client = getClient();
const idx = 'products';
switch (event.type) {
case 'INSERT':
case 'UPDATE':
await client.saveObject({ indexName: idx, body: event.record });
break;
case 'DELETE':
await client.deleteObject({ indexName: idx, objectID: event.record.id });
break;
}
}
Search for Synonyms
const { hits } = await client.searchSynonyms({
indexName: 'products',
searchSynonymsParams: { query: 'phone', type: 'synonym' },
});
console.log(`Found ${hits.length} synonym sets matching "phone"`);
Resources
Next Steps
For common errors, see algolia-common-errors.