krisk / Fuse

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

Score is not working correctly #354

Closed laurentiustroia closed 4 years ago

laurentiustroia commented 4 years ago

Hi,

in last version 3.6.1 the score is not between 0 and 1. This can be check on https://fusejs.io/ too.

Example request + config:

  shouldSort: true,
  includeScore: true,
  threshold: 0,
  location: 0,
  distance: 0,
  maxPatternLength: 32,
  minMatchCharLength: 1,
  keys: [
    "title",
    "author.firstName"
  ]
};
var fuse = new Fuse(list, options); // "list" is the item array
var result = fuse.search("Old Man's War");

the output:

[
  {
    "item": {
      "title": "Old Man's War",
      "author": {
        "firstName": "John",
        "lastName": "Scalzi"
      }
    },
    "score": 2.220446049250313e-16
  }
]
laurentiustroia commented 4 years ago

Before last release this was 0 if exact match

krisk commented 4 years ago

@laurentiustroia, 2.220446049250313e-16 evaluates to 0.0000000000000002220446049250313 😄 .

True that the previous release was an exact 0, but I've been making some modifications to increase perf. Nonetheless, I'm making some other adjustments that should make an exact match a score of 0. Bear with me.

In the meantime, is the score not being zero breaking some logic for you?

laurentiustroia commented 4 years ago

Me based on that score to know when is exact match, otherwise is good to update the docs to know exactly how i can see exact match vs a variation name, example, if search red in above array ["red", "redis"]

MadsMadsDk commented 4 years ago

I ran in to this issue as well. As a quick workaround, I applied .toFixed(2) to the score, so I was able to filter exact results from partial matches.

acnebs commented 4 years ago

Yeah, this broke my logic and took me a while to debug. The docs should definitely be changed if an exact match is no longer strict equality 0.

@MadsMadsDk I'm not sure that is the best way to do it, as partial match scores can be as low as 0.001, which with your fix would be cast as "perfect" even though it's not quite.

I've gone with this for the time being:

const perfectMatch = result.score < 1E-10;

But I think it would be very good to have a solution with a strong guarantee when a result is a perfect match.

krisk commented 4 years ago

Addressed this in v5.2.2-alpha.0.

However, I'm undecided about this. I've started a discussion in #397.

[Will close this and use the above issue instead]