Skip to content

Fix search result rendering for returned matches#366

Merged
appflowy merged 1 commit into
mainfrom
fix/search-results-score-threshold
May 25, 2026
Merged

Fix search result rendering for returned matches#366
appflowy merged 1 commit into
mainfrom
fix/search-results-score-threshold

Conversation

@appflowy
Copy link
Copy Markdown
Contributor

@appflowy appflowy commented May 24, 2026

Summary

  • explicitly send search score threshold 0.2 to search endpoints
  • fetch missing view metadata for returned search results not present in the loaded outline
  • add coverage for rendering search results missing from the current outline

Tests

  • pnpm exec jest src/components/app/search/tests/BestMatch.test.tsx --no-coverage --runInBand
  • pnpm run type-check
  • pnpm exec eslint --quiet --ext .ts,.tsx src/application/services/js-services/http/misc-api.ts src/components/app/search/BestMatch.tsx src/components/app/search/tests/BestMatch.test.tsx

Summary by Sourcery

Improve search result handling by filtering low-score matches and loading missing view metadata for search results.

Bug Fixes:

  • Ensure search results render correctly when their views are not present in the current outline by lazily fetching missing view metadata.

Enhancements:

  • Add support for resolving search result views from multiple candidate identifiers and skipping invalid space results.
  • Refactor best-match search item building to be asynchronous and sequence-aware to avoid stale updates during pagination.

Build:

  • Configure search API requests to send a minimum score threshold parameter to reduce low-quality matches.

Tests:

  • Extend BestMatch tests to cover loading view metadata for search results not present in the outline and verify rendered item titles.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 24, 2026

Reviewer's Guide

This PR tightens search result relevance and ensures search results render even when their views are not present in the current outline by adding a score threshold to search APIs, lazily loading missing view metadata on the client, and extending tests to cover these flows.

Sequence diagram for search workspace APIs with score threshold

sequenceDiagram
  actor User
  participant BestMatch
  participant miscApi
  participant SearchAPI

  User->>BestMatch: type in search query
  BestMatch->>miscApi: searchWorkspaceDocuments(workspaceId, query)
  miscApi->>SearchAPI: GET /api/search/{workspaceId}
  activate SearchAPI
  Note right of miscApi: params: query, limit, preview_size,
  Note right of miscApi: score = SEARCH_SCORE_THRESHOLD (0.2)
  SearchAPI-->>miscApi: APIResponse<SearchDocumentResponseItem[]>
  deactivate SearchAPI
  miscApi-->>BestMatch: SearchDocumentResponseItem[]
  BestMatch->>miscApi: searchWorkspaceDocumentPage(workspaceId, query, offset)
  miscApi->>SearchAPI: GET /api/search/{workspaceId}/documents
  activate SearchAPI
  Note right of miscApi: params include score = SEARCH_SCORE_THRESHOLD (0.2)
  SearchAPI-->>miscApi: APIResponse<SearchDocumentResponsePage>
  deactivate SearchAPI
  miscApi-->>BestMatch: SearchDocumentResponsePage
Loading

Sequence diagram for lazy loading missing search result views

sequenceDiagram
  participant BestMatch
  participant ViewService

  BestMatch->>BestMatch: handleSearch(query)
  BestMatch->>BestMatch: mergeSearchResults([], page.items)
  BestMatch->>BestMatch: buildSearchItems(results)
  activate BestMatch
  BestMatch->>BestMatch: resolveSearchResultView(outline, item*)
  alt view found in outline
    BestMatch-->>BestMatch: use existing view
  else view missing from outline
    BestMatch->>BestMatch: getSearchResultViewIdCandidates(item)
    loop candidates viewId
      BestMatch->>ViewService: get(workspaceId, viewId)
      alt ViewService.get succeeds
        ViewService-->>BestMatch: View
        BestMatch-->>BestMatch: break loop
      else ViewService.get throws
        ViewService-->>BestMatch: error
      end
    end
  end
  BestMatch-->>BestMatch: items: SearchViewListItem[]
  BestMatch->>BestMatch: [searchSeqRef.current !== searchSeq]
  alt sequence changed
    BestMatch-->>BestMatch: abort using searchItems
  else sequence unchanged
    BestMatch-->>BestMatch: setItems(searchItems)
  end
  deactivate BestMatch
Loading

File-Level Changes

Change Details Files
Add search score threshold parameter to workspace search HTTP calls to limit low-relevance results.
  • Introduce SEARCH_SCORE_THRESHOLD constant set to 0.2 for search APIs
  • Pass score threshold in query params for searchWorkspaceDocuments requests
  • Pass score threshold in query params for paginated searchWorkspaceDocumentPage requests
src/application/services/js-services/http/misc-api.ts
Resolve and fetch view metadata for search results that are missing from the current outline so they can be rendered.
  • Add helper to compute candidate view IDs from search result fields (object_id, database_view_id, database_id)
  • Implement loadSearchResultView to try fetching a view by candidate IDs and handle non-view IDs gracefully
  • Update buildSearchItems to be async, pre-resolving views via outline lookup or remote fetch and skipping space views
  • Ensure search handlers await item building, check sequence after async work, and avoid races when updating items and results
src/components/app/search/BestMatch.tsx
Expand BestMatch tests to cover lazy loading of missing view metadata and updated rendering behavior.
  • Mock ViewService.get and ViewList component to verify rendered item names
  • Add factory helper for creating View instances in tests
  • Reset outline and mock behaviors before each test, including default getView rejection
  • Add test that simulates a search result not in the outline and asserts that ViewService.get is called and result name is rendered
  • Refactor test helper to accept search value and wire new async behavior
src/components/app/search/__tests__/BestMatch.test.tsx

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@appflowy appflowy merged commit 8563d1b into main May 25, 2026
13 checks passed
@appflowy appflowy deleted the fix/search-results-score-threshold branch May 25, 2026 02:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant