Implement an in-memory search engine

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
  }
]
*/