Skip to content

Threshold filtering not applied correctly with certain distance configurations #813

@CorentinLallier

Description

@CorentinLallier

Is there an existing issue for this?

  • I have searched the existing issues

Description of the bug

Hello,

It seems Fuse.js v7.1.0 does not properly apply threshold-based score filtering in multiple configuration scenarios. While threshold correctly determines the match window (threshold × distance), it fails to filter results by score quality when certain combinations of ignoreLocation and distance parameters are used.

The threshold option serves two purposes:

  1. Match Window: threshold × distance determines how far from the expected location a pattern can appear (this works correctly)
  2. Score Filtering: Results with scores greater than threshold should be excluded (this is broken)

I was expecting score filtering should always be applied regardless of the ignoreLocation or distance settings. Even if a match passes the match window check, if its final score exceeds the threshold, it should be filtered out.

The Fuse.js version where this bug is happening.

Other (please specify in description)

Is this a regression?

  • This is a regression bug

Which version did this behavior use to work in?

None

Steps To Reproduce

import Fuse from "fuse.js";

const items = [
  {
    id: "s3",
    name: "Simple Storage Service",
    displayName: "AWS Simple Storage Service",
    tags: ["Amazon", "AWS"],
    description: "Amazon Simple Storage Service (S3) is object storage built to store and retrieve any amount of data from anywhere."
  },
  {
    id: "efs",
    name: "Elastic File System",
    displayName: "Elastic File System",
    tags: ["Amazon", "AWS"],
    description: "Amazon Elastic File System (Amazon EFS) provides simple, scalable file storage for use with Amazon EC2 Linux and Mac instances in the Amazon Web Services Cloud."
  }
];

const query = "Simple Storage Service";
const threshold = 0.3;

// Test Case 1: ignoreLocation: false + distance: 500 (BUG)
const fuse1 = new Fuse(items, {
  threshold,
  ignoreLocation: false,
  distance: 500,
  keys: [
    { name: 'name', weight: 0.7 },
    { name: 'displayName', weight: 0.15 },
    { name: 'tags', weight: 0.15 },
    { name: 'description', weight: 0.1 }
  ],
  includeScore: true
});

const results1 = fuse1.search(query);
console.log("Test 1 - ignoreLocation: false + distance: 500");
console.log(`Results: ${results1.length} (expected: 1)`);
results1.forEach(r => {
  console.log(`  - ${r.item.name}: score=${r.score} ${r.score > threshold ? '❌ ABOVE THRESHOLD' : '✅'}`);
});
// Actual: Returns 2 results (includes "Elastic File System" with score 0.98)
// Expected: Should return only 1 result ("Simple Storage Service" with score ~0.127)

// Test Case 2: ignoreLocation: true (BUG)
const fuse2 = new Fuse(items, {
  threshold,
  ignoreLocation: true,
  keys: [
    { name: 'name', weight: 0.7 },
    { name: 'displayName', weight: 0.15 },
    { name: 'tags', weight: 0.15 },
    { name: 'description', weight: 0.1 }
  ],
  includeScore: true
});

const results2 = fuse2.search(query);
console.log("\nTest 2 - ignoreLocation: true");
console.log(`Results: ${results3.length} (expected: 1)`);
results2.forEach(r => {
  console.log(`  - ${r.item.name}: score=${r.score} ${r.score > threshold ? '❌ ABOVE THRESHOLD' : '✅'}`);
});
// Actual: Returns 2 results (includes "Elastic File System" with score 0.924)
// Expected: Should return only 1 result ("Simple Storage Service" with score ~0.031)

Expected behavior

I think the threshold should also filter final results by score quality. Results with scores greater than the threshold should be excluded from the results.

Screenshots

No response

Additional context

  1. Is this the intended behavior, or is this a bug?
  2. If intended, could the documentation be updated to clarify when threshold filtering is applied?
  3. If a bug, are there plans to fix this in a future release?

Thank you for your time and for maintaining this excellent library!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions