atomic-algolia
Version:
An NPM package for running atomic updates to an Algolia index
110 lines (90 loc) • 3.07 kB
JavaScript
var debug = require('debug')('atomic-algolia:actionAdd');
var idsFromIndex = require("./idsFromIndex");
var md5 = require("md5");
module.exports = function calculateOperations(newIndex, oldIndex) {
var newIndexIds = [];
var oldIndexIds = [];
if (Array.isArray(newIndex)) {
newIndexIds = idsFromIndex(newIndex);
}
if (Array.isArray(oldIndex)) {
oldIndexIds = idsFromIndex(oldIndex);
}
debug('New Index IDs: %o', newIndexIds);
debug('Old Index IDs: %o', oldIndexIds);
var existingHits = [];
var operations = {
ignore: [],
update: [],
add: newIndexIds,
"delete": oldIndexIds
};
if (newIndexIds.length > 0 && oldIndexIds.length > 0) {
existingHits = findExistingHits(newIndexIds, oldIndexIds);
operations.add = findNewHits(newIndexIds, oldIndexIds);
operations["delete"] = findExpiredHits(newIndexIds, oldIndexIds);
}
if (existingHits.length > 0) {
operations.ignore = findUnchangedHits(existingHits, newIndex, oldIndex);
operations.update = findChangedHits(existingHits, newIndex, oldIndex);
}
debug('Existing Hits: %o', existingHits);
debug('Add Operations: %o', operations.add);
debug('Delete Operations: %o', operations["delete"]);
debug('Update Operations: %o', operations.update);
debug('Ignore Operations: %o', operations.ignore);
return operations;
};
function findNewHits(newIndexIds, oldIndexIds) {
return newIndexIds.filter(function (id) {
return oldIndexIds.indexOf(id) === -1;
});
}
function findExpiredHits(newIndexIds, oldIndexIds) {
return oldIndexIds.filter(function (id) {
return newIndexIds.indexOf(id) === -1;
});
}
function findExistingHits(newIndexIds, oldIndexIds) {
return newIndexIds.filter(function (id) {
return oldIndexIds.indexOf(id) !== -1;
});
}
function findUnchangedHits(existingHits, newIndex, oldIndex) {
return existingHits.filter(function (id) {
var shouldUpdate = compareHitFromIndexes(id, newIndex, oldIndex);
if (shouldUpdate !== true) {
return id;
}
});
}
function findChangedHits(existingHits, newIndex, oldIndex) {
return existingHits.filter(function (id) {
var shouldUpdate = compareHitFromIndexes(id, newIndex, oldIndex);
if (shouldUpdate === true) {
return id;
}
});
}
function compareHitFromIndexes(id, newIndex, oldIndex) {
var newHit = newIndex.filter(function (hit) {
return hit.objectID === id;
});
var oldHit = oldIndex.filter(function (hit) {
return String(hit.objectID) === String(id);
});
debug('New hit: %o', newHit);
debug('Old hit: %o', oldHit);
if (newHit.length > 0 && oldHit.length > 0) {
var newHitSorted = JSON.stringify(newHit[0], Object.keys(newHit[0]).sort());
var oldHitSorted = JSON.stringify(oldHit[0], Object.keys(oldHit[0]).sort());
var newHash = md5(newHitSorted);
var oldHash = md5(oldHitSorted);
debug('Comparing new to old:');
debug('%o <> %o', newHitSorted, oldHitSorted);
debug('%s <> %s', newHash, oldHash);
return newHash !== oldHash;
}
return null;
}
;