Arranging search findings based on relevance using javascript

I'm developing a personalized search feature. Currently, when I type "The R," the search results list starts with The Fellowship of the Ring because the phrase "the ring" is in its .text property. However, I want The Return of the King to appear first. Is there a way to prioritize the .name field or arrange the match array based on the name .field and input text?

HTML

<section class="container-fluid px-0 justify-content-center">
  <div class="row no-gutters">
    <div class="col d-flex justify-content-center search">
      <form class="form-inline position-relative">
        <input id="search" class="form-control form-control-search" type="text" placeholder="Search..." aria-label="Search">
      </form>
      <div id="match-list" class="d-none"></div>
    </div>
  </div>
</section>

JAVASCRIPT

const searchIndex = async searchText => {
 const res = await fetch('/data/index.json');
 const index = await res.json();

  matchList.classList.remove("d-none");
 // Retrieve matches for the current text input
 let matches = index.filter(index => {
  const regex = new RegExp(`${searchText}`, 'gi');
  return index.name.match(regex) || index.text.match(regex);
 });

 // Clear the search when input or matches are empty
 if (searchText.length === 0) {
   clearSearch();
 }

 outputHtml(matches);
};

function clearSearch(){
  matches = [];
  matchList.classList.add("d-none");
}

// Display results in HTML
const outputHtml = matches => {
 if (matches.length > 0) {
  const html = matches.map(function(match){
      return `<a href="${match.url}">
      <div class="media mb-2">
        <div class="component-icon-slot my-auto" style="background-image: url('/img/${match.url}/icon.png"></div>
          <div class="media-body pl-2">
            <h3 class="mt-0 mb-0">${match.name}</h3>
            <b>${match.type}</b><br/>
            <i>Found in <b>${match.product}</b></i><br/>
            ${match.text}
          </div>
        </div></a>`
    }
}).join('');
  matchList.innerHTML = html;
 }
};

index.JSON

 [
  {
    "name": "The Fellowship of the Rings",
    "type": "book",
    "text": "Bilbo reveals that he intends to leave the Shire for one last adventure, and he leaves his inheritance, including the Ring, to his nephew Frodo. Gandalf investigates...",
    "url": "books/the-fellowship-of-the-rings",
    "product": "Books"
  },
  {
    "name": "The Two Towers",
    "type": "book",
    "text": "Awakening from a dream of Gandalf fighting the Balrog in Moria, Frodo Baggins and Samwise Gamgee find themselves lost in the Emyn Muil near Mordor and discover they are being tracked by Gollum, a former bearer of the One Ring.",
    "url": "books/the-two-towers",
    "product": "Books"
  },
  {
    "name": "The Return of the King",
    "type": "book",
    "text": "Gandalf flies in with eagles to rescue the Hobbits, who awaken in Minas Tirith and are reunited with the surviving Fellowship.",
    "url": "books/the-return-of-the-king",
    "product": "Books"
  }
]

Answer №1

One strategy to improve search relevance is by mapping your data with weighted points:

const index = await res.json();
const searchTermLowercased = searchTerm.toLowerCase();

const rankedIndex = index.map(item => {
    let points = 0;

    if (item.name.toLowerCase().includes(searchTermLowercased)) {
        points += 2;
    }

    if (item.text.toLowerCase().includes(searchTermLowercased)) {
        points += 1;
    }

    return {...item, points};
}).sort((x, y) => y.points - x.points);

This approach provides you with sorted results in the rankedIndex constant.

Remember to consider code optimization since fetching data for every search might require refactoring. It's important to optimize the searchIndex() function, especially if it gets called frequently during user input.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing deferred to ensure that one function completes before triggering a refresh

In my JavaScript code, I have an ajax call that receives a GUID from the server-side code in the response. After getting the GUID successfully, it is used to make a call to an iframe. The ultimate goal is to refresh the page once the iframe has completed i ...

The slice() method in arrays provides a reference to the elements rather than copying

In my file, I am exporting an object in the following manner: export const LINECHART2_DATA = { series: [{ data: [], name: 'HR', }, { etc... }] } The way I import it is like this: import { LINECHART2_DAT ...

Efficiently Parse JSON Data with Variable Root Name

Currently, I have successful codes that can de-serialize a JSON message. The JSON message contains a root name of "response", and the Response class has been annotated accordingly to reflect this. However, in practice, the JSON message may originate from ...

My array is experiencing issues due to the UITableView indexPath

After attempting to access the SECOND item in my array, I encountered an error. Strangely, when I access the first item in the array within my table view cell, everything seems fine. However, as soon as I try to access the 2nd cell/item in the array, I rec ...

The createReadStream function cannot be found in the uploaded image

I am currently using node v14.17.0, "apollo-server-express": "^2.25.0", "graphql-upload": "^12.0.0" I'm facing an issue with uploading an image as I don't receive the createReadStream from the image that I upload via graphiql. Specifically, I am ...

VueJS - Vuefire - Unexpected Error: document.onSnapshot is not a valid function

I'm currently working on integrating Vuefire into my project. I have been following the instructions provided on the Vuefire website, but I am encountering an error. db.js: import firebase from 'firebase/app' import 'firebase/firestore ...

Exploring ways to retrieve boolean values with Angular and PHP

I am currently learning Angular and PHP and I am trying to make some modifications to the tutorial found at . Specifically, I want to change the second value to a checkbox and retrieve its value using both Angular and PHP. However, I am encountering an iss ...

Interactive Zoomable Tree with d3.js

I am looking to customize the zoomable icicle plot in d3js by incorporating my own data. Unfortunately, I am unable to locate the "readme.json" file for data modification and cannot get the graph to display on my local machine. Where can I find this elus ...

Executing jQuery AJAX requests in a chain with interdependent tasks

I am struggling to grasp the concept of magic deferred objects with jQuery. Consider the following code snippet: function callWebService(uri, filter, callback) { var data = {}; if (filter && filter != '') data['$filter&apos ...

Show a dynamic modal with a widget displayed inside

I am facing an issue with my Angular.js website that is filled with a multitude of widgets. Each widget consists of a template.html file paired with a controller.js file to form an angular module. These widgets are utilized on a dashboard where users have ...

Ldap.js: exploring nested searches

My current task involves using ldapjs to conduct a search where the filter is dependent on the outcome of a preceding search. ldapClient.search(base1, opts1, (err1, res1) => { res1.on("searchEntry", entry => { const myObj = { attr1: entr ...

A guide on implementing Google reCAPTCHA in a Nuxt.js website

Trying to implement the recaptcha-module from nuxt-community in my Nuxt project but struggling with verifying if the user has passed the check. The documentation and example provided are not clear enough for me (https://github.com/nuxt-community/recaptch ...

Row within a table displaying link-like behavior

Here is the code I'm currently using: $('.table-striped tr').click( function() { var link = $(this).find('a').attr('href'); if(link != 'undefined') { window.location = link; } }).hover( func ...

Unable to retrieve object element in angular

weatherApp.controller('forecastController', ['$scope','weatherService','$resource','$log', function($scope,weatherService,$resource,$log){ var cnto =3; $scope.forecastholder = weatherService.holder; $scope ...

How can I add color to arrow icons in tabulator group rows?

Is there a way to specify the color of the arrows in collapsed/expanded group rows? Also, what CSS code should I use to define the font color for column group summaries? You can view an example of what I am trying to customize here: https://jsfiddle.net/s ...

The .val() and focus() methods are not functioning correctly

I am having an issue with a simple script: when I input a link to an image in the form's INPUT field, it should automatically display a preview of the image: https://example.com/image.jpg However, when I input the same link not by using ctrl+C/ctr ...

Exploring multiple arrays with nested loops using the JOLT library

Within my input data, there is a list of individuals. Each individual has multiple addresses and roles on the contract. For example : Individual #001 has : two addresses - secondary residence and tax address ; two roles - co-subscriber and insured Indi ...

Challenges associated with utilizing img src in JavaScript

I am facing a simple issue. I have carInfo data retrieved from a JSON file, but I am struggling to correctly parse the img source stored in the variable $imgsrc instead of treating it as a string called "$imgsrc". This data needs to be appended to my HTML ...

The element is implicitly classified as an 'any' type due to the index expression not being of type 'number'

Encountering a specific error, I am aware of what the code signifies but unsure about the correct interface format: An error is occurring due to an 'any' type being implicitly assigned as the index expression is not of type 'number'. ...

Implementing gridlines on a webpage using HTML and JavaScript to mimic the grid layout found in Visual Studios

Currently, I have a grid snap function in place, however, I am looking to add light grey lines horizontally and vertically on my Designing application. The goal is to achieve a similar aesthetic to Visual Studios' form designing feature. Utilizing so ...