如何在javascript中按相关性对搜索结果排序

如何在javascript中按相关性对搜索结果排序,javascript,arrays,json,sorting,search,Javascript,Arrays,Json,Sorting,Search,我正在建立一个自定义搜索,从现在开始,如果我输入“TheR”,我会首先得到与戒指同行的结果列表,因为短语“TheRing”在它的.text中。我希望国王的回归是第一位的。有没有一种方法可以使.name字段更具相关性,或者根据name.field和输入文本对匹配数组进行排序 HTML 您可以映射数据以包含相关性点: const index=wait res.json(); const searchTextLowercased=searchText.toLowerCase(); const rank

我正在建立一个自定义搜索,从现在开始,如果我输入“TheR”,我会首先得到与戒指同行的结果列表,因为短语“TheRing”在它的.text中。我希望国王的回归是第一位的。有没有一种方法可以使.name字段更具相关性,或者根据name.field和输入文本对匹配数组进行排序

HTML


您可以映射数据以包含相关性点:

const index=wait res.json();
const searchTextLowercased=searchText.toLowerCase();
const rankedIndex=index.map(条目=>{
设点=0;
if(entry.name.toLowerCase().includes(searchTextLowercased)){
积分+=2;
}
if(entry.text.toLowerCase().includes(searchTextLowercased)){
积分+=1;
}
返回{…条目,点};
}).排序((a,b)=>b.点-a.点);
这样,您就可以在
rankedIndex
const中对结果进行排序


请记住,您的代码可能需要一些重构,因为每次搜索都要获取数据。我假设您的
searchIndex()
每次按键或类似操作都会被调用。

这个问题没有明确的答案。您可以使用不同的策略来评估相关性。我可以使用wathever解决方案,将名称和文本进行优先级排序。您可以按匹配/不匹配对其进行排序,还是需要更高级的内容?我正在尝试按相关性对其进行排序,因此,首先是名称,然后是文本。或者,我也会尝试从字符串开始搜索,我使用了RegExp(
^${searchText}
,'gi');但如果我只写“king”,我将不会得到任何结果。你不应该像那样使用正则表达式,因为正则表达式使用特殊字符。相反,请比较if
string.toLowerCase().includes(searchText.toLowerCase())
。它可以工作,但有一个问题,出于某种原因,某些结果似乎有4分。因此,如果我写字母“a”,但某些结果在文本中有更多匹配项,即使它的名称以字母“c”开头,它也会在上面。如果你在我发布代码时使用我的代码,这是不可能的。我只是在匹配项中重命名rankedIndex,因为脚本使用了它。我没有做任何其他修改。
<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>
const searchIndex = async searchText => {
 const res = await fetch('/data/index.json');
 const index = await res.json();

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

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

 outputHtml(matches);
};

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

// Show 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;
 }
};
 [
  {
    "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"
  }
]