krisk / Fuse

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

includeMatches includes unexpected matches #505

Closed hadley closed 3 years ago

hadley commented 3 years ago

Describe the bug

On the live demo page, I use the following code:

const options = {
  // isCaseSensitive: false,
  // includeScore: false,
  // shouldSort: true,
  includeMatches: true,
  // findAllMatches: false,
  // minMatchCharLength: 1,
  // location: 0,
  threshold: 0.1,
  // distance: 100,
  // useExtendedSearch: false,
  // ignoreLocation: false,
  // ignoreFieldNorm: false,
  keys: [
    "title",
    "author.firstName"
  ]
};

const fuse = new Fuse(list, options);

// Change the pattern
const pattern = "war"

return fuse.search(pattern)

and it returns two results:

[
  {
    "item": {
      "title": "Backwards, Red Dwarf",
      "author": {
        "firstName": "Rob",
        "lastName": "Grant"
      }
    },
    "refIndex": 17,
    "matches": [
      {
        "indices": [
          [1, 1],
          [4, 6],
          [16, 18]
        ],
        "value": "Backwards, Red Dwarf",
        "key": "title"
      }
    ]
  },
  {
    "item": {
      "title": "Old Man's War",
      "author": {
        "firstName": "John",
        "lastName": "Scalzi"
      }
    },
    "refIndex": 0,
    "matches": [
      {
        "indices": [
          [5, 5],
          [10, 12]
        ],
        "value": "Old Man's War",
        "key": "title"
      }
    ]
  }
]

The matches appear to include text that doesn't match. E.g. the first match includes indices [1, 1], i.e. "a".

Version

6.4.2

krisk commented 3 years ago

"a" is indeed matching (since the pattern is "war"). One way to omit single character matches is to set minMatchCharLength to a value > 1.

hadley commented 3 years ago

In that case, this is probably a duplicate of #504, because it surprises me that the match can be shorter than the search term.

hadley commented 3 years ago

Thinking about this more, I think I generally want a prefix match — i.e. if the use has typed "war", I want to match "war", "warfare", "warlord", but not "award", and not "a". This isn't quite ^war because I'd still like some fuzziness , and I want to apply it automatically to searches (although I guess I could just turn on extended search and paste "^" to the front of the search string).

github-actions[bot] commented 3 years ago

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