krisk / Fuse

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

Score appears to be unreliable for matches at start of string #730

Closed apuchitnis closed 6 months ago

apuchitnis commented 11 months ago

Is there an existing issue for this?

Description of the bug

See the code:

const Fuse = require('fuse.js');

const fuseOptions = {
  includeScore: true,
  minMatchCharLength: 3,
  threshold: 1,
  ignoreLocation: true,
  keys: ['text'],
};

const list = [
  {
    text: 'Chemical Overreaction / Compound Fracture',
  },
];

const fuse = new Fuse(list, fuseOptions);

// Change the pattern
const searchPattern = ' Chemical'; // score is 0.375
// const searchPattern = 'Chemical'; // score is 0.045

const res = fuse.search(searchPattern);
if (res.length > 0) {
  console.log(JSON.stringify(res));
} else {
  console.log('could not find match');
}

oddly, when adding a space at the start of the search pattern, the score dramatically reduces. This is unexpected, as the two strings are quite different other than the space at the start of the string. This suggests that there could be a bug to me.

The Fuse.js version where this bug is happening.

6.6.2

Is this a regression?

Which version did this behavior use to work in?

None

Steps To Reproduce

See description :) Also https://stackblitz.com/edit/fusejs-repro?file=package.json,index.js,style.css

Expected behavior

I don't expect there to be a match without the space at the front.

Screenshots

No response

Additional context

No response

apuchitnis commented 11 months ago

this might be another bug -- if I set the threshold to 0.01, the searchPattern that leads to a score of 0.045 success, when it shouldn't:

const Fuse = require('fuse.js');

const fuseOptions = {
  includeScore: true,
  minMatchCharLength: 3,
  threshold: 0.01,
  ignoreLocation: true,
  keys: ['text'],
};

const list = [
  {
    text: 'Chemical Overreaction / Compound Fracture',
  },
];

const fuse = new Fuse(list, fuseOptions);

// Change the pattern
// const searchPattern = ' Chemical'; // score is 0.375
const searchPattern = 'Chemical'; // score is 0.045

const res = fuse.search(searchPattern);
if (res.length > 0) {
  console.log(JSON.stringify(res));
} else {
  console.log('could not find match');
}
github-actions[bot] commented 7 months ago

This issue is stale because it has been open 120 days with no activity. Remove stale label or comment or this will be closed in 30 days