Skip to content

Fallback search may lose merged ordering due to id__in queryset #663

@harikadanduprolu

Description

@harikadanduprolu

Issue summary

Problem

When using the database search backend, the search view gathers results from multiple page models (for example BlogPage, BreadPage, and LocationPage). Each model-level search returns results ordered within that model.

The fallback search then merges those results into a list of page IDs and fetches the pages using:

Page.objects.filter(id__in=ids)

However, id__in does not preserve the ordering of the provided ID list. As a result, the merged ordering can be lost and the final results may appear in database/default order rather than the intended merged order.

This occurs in the fallback search logic implemented in views.py.

Scope

This issue affects the database-backend fallback search path only (non-Elasticsearch setups).

Why this matters

As the demo site is extended to support larger datasets (for example dozens or hundreds of pages per section), incorrect ordering can make search results appear inconsistent and less representative of how search behaves in real Wagtail sites.

Proposed solution

Preserve the merged ID ordering when constructing the final queryset, for example by applying explicit ordering using a Case/When expression so that the final queryset preserves the merged ID order deterministically.

Expected behavior

Merged fallback search results preserve deterministic ordering while continuing to support pagination.

Acceptance criteria

  • Combined fallback results preserve the intended merged ordering.
  • Pagination behavior remains unchanged.
  • The returned set of pages remains identical (only ordering changes).

Implementation note

The current fallback concatenates model result sets, so cross-model relevance ranking is already heuristic. This change focuses only on preserving the existing merged ordering so that ordering information is not lost during the final queryset fetch.

Steps to reproduce

  1. Run the project using the default database search backend.
  2. Create or generate multiple pages across different models (BlogPage, BreadPage, LocationPage) with overlapping keywords.
  3. Search for a keyword that matches multiple page types.
  4. Observe that the result order may differ from the merged ordering produced by the individual searches.

Additional information

No response

Can be reproduced

Not confirmed

Technical details

OS: Windows
Python version: 3.13.0
Django version: 6.0.3
Wagtail version: 7.2.3

Working on this

I would be interested in working on a PR for this if the approach is acceptable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions