krisk / Fuse

Lightweight fuzzy-search, in JavaScript
https://fusejs.io/
Apache License 2.0
17.76k stars 753 forks source link

Relevant results ranked low and irrelevant included using ignoreLocation #668

Closed 01binary closed 2 years ago

01binary commented 2 years ago

Hi, thanks for this library! I read the Scoring Theory and turned on ignoreLocation but I am still confused about the matches:

Of course I could sort and filter by match score (let's say cut off below .6 or .7 and sort descending) but I don't know how to compensate for completely irrelevant results :(

Steps to Reproduce

  1. Go to Fuse Live Demo
  2. Use the following data
[
  {
    "title": "Senior Frontend Engineer",
    "summary": "Building advanced data-driven user interfaces with React/Typescript and processing data from embedded devices."
  },
  {
    "title": "Enterprise Architect",
    "summary": "Guiding cloud transformation and building technical vision across teams at an established company. Working with Azure services, ASP.NET Core backend, Angular 8 frontend, and SQL Server databases."
  },
  {
    "title": "Senior Software Development Engineer",
    "summary": "Served as a technical lead and solution architect. Maintained a cloud-based litigation system for corporate law hosted in AWS."
  },
  {
    "title": "Senior Frontend Developer",
    "summary": "Led a team of outsourced developers. Developed and architected micro-services with Node.js/React and ASP.NET WebAPI."
  },
  {
    "title": "Senior Software Development Engineer",
    "summary": "Developed server-rendered React/Redux applications with expess.js, object oriented LESS styles, and ASP.NET WebAPI."
  },
  {
    "title": "Software Development Engineer",
    "summary": "Developed continuous integration and quality assurance tools. Maintained a cloud-based crash reporting system in Azure."
  },
  {
    "title": "Web and Print Designer",
    "summary": "Used SharePoint and jQuery to create content-driven sites, designed marketing materials in Adobe Creative Suite."
  },
  {
    "title": "Associate of Applied Science in IT & Multimedia",
    "summary": "Studied software development, graphic design, illustration, video production, 3D modeling and animation."
  },
  {
    "title": "Certifications",
    "summary": "70-486 ASP.NET MVC Web Applications. AWS Solutions Architect Associate."
  },
  {
    "title": "Interests",
    "summary": "Robotics, industrial design, graphic design, video and music production."
  },
]
  1. Use the following configuration and search pattern
const options = {
  // isCaseSensitive: false,
  includeScore: true,
  sortFn: (a, b) => a - b,
  // shouldSort: true,
  // includeMatches: false,
  // findAllMatches: false,
  // minMatchCharLength: 1,
  // location: 0,
  // threshold: 0.6,
  // distance: 100,
  // useExtendedSearch: false,
  ignoreLocation: true,
  // ignoreFieldNorm: false,
  // fieldNormWeight: 1,
  keys: [
    "title",
    "summary"
  ]
};

const fuse = new Fuse(list, options);

// Change the pattern
const pattern = "react"

return fuse.search(pattern)
  1. Observed results

When searching an online resume for "react", the program returns applicant's experiences that make no mention of react

  1. Expected results

When searching an online resume for "react", the program should return applicant's experiences where they mention they worked with React library

krisk commented 2 years ago

Have you tried changing minMatchCharLength? Part of the problem is that the pattern "react" closely matches other words in the list.

Try using the following options

const options = {
  minMatchCharLength: 3,
  ignoreLocation: true,
  keys: ['title', 'summary']
}
01binary commented 2 years ago

Thank you for the response! I see that Fuse isn't designed for precise matching, so I went with a hybrid approach. Keywords like react are searched using more basic string matching and tokenizing, and raw text is searched with Fuse (with the same keywords removed).