Implement an in-memory search engine where multiple documents could be stored under a particular namespace and search on them and sort the search results by passing the orderBy parameter.
Example
const searchEngine = new InMemorySearch(); searchEngine.addDocuments('Movies', {name: 'Avenger', rating: 8.5, year: 2017}, {name: 'Black Adam', rating: 8.7, year: 2022}, {name: 'Jhon Wick 4', rating: 8.2, year: 2023}, {name: 'Black Panther', rating: 9.0, year: 2022} ); console.log(searchEngine.search('Movies', (e) => e.rating > 8.5, {key: 'rating', asc: false})); /* [ { "name": "Black Panther", "rating": 9, "year": 2022 }, { "name": "Black Adam", "rating": 8.7, "year": 2022 } ] */
To implement this, we can use a map to register and track different namespaces and their associated documents.
For searching, we will take the namespace and a callback function that will filter the value based on the output of this callback function.
This function will also accept an option orderBy parameter, that will have the key and the order on which the search result will be ordered.
class InMemorySearch { constructor() { // to track namespace and its document this.entities = new Map(); } // register the new namespace registerNameSpace(name){ this.entities.set(name, []); } // add document to the namespace addDocuments(nameSpace, ...documents){ const existing = this.entities.get(nameSpace); // if the namespace does not exists // create one and add the documents if(!existing){ this.entities.set(nameSpace, [...documents]); } // else add the merge the documents else{ this.entities.set(nameSpace, [...existing, ...documents]); } } // search the documents of the given namespace search(nameSpace, filterFN, orderByFN){ // get the namespace const docs = this.entities.get(nameSpace); // get it filtered const filtered = docs.filter((e) => filterFN(e)); // if orderby is requestd if(orderByFN){ const {key, asc} = orderByFN; // orderby the searched result // based on the key and order requested return filtered.sort((a, b) => { if(asc){ return a[key] - b[key]; }else{ return b[key] - a[key]; } }); } return filtered; } };
Input: const searchEngine = new InMemorySearch(); searchEngine.addDocuments('Movies', {name: 'Avenger', rating: 8.5, year: 2017}, {name: 'Black Adam', rating: 8.7, year: 2022}, {name: 'Jhon Wick 4', rating: 8.2, year: 2023}, {name: 'Black Panther', rating: 9.0, year: 2022} ); console.log(searchEngine.search('Movies', (e) => e.rating > 8.5, {key: 'rating', asc: false})); Output: /* [ { "name": "Black Panther", "rating": 9, "year": 2022 }, { "name": "Black Adam", "rating": 8.7, "year": 2022 } ] */