Skip to content

Conversation

@JosephDoUrden
Copy link

Summary

Fixes incorrect document deletion when using deep nested field filters
(e.g. main.items.{status: active && price: <100}).


Root Cause

validate_object_filter() in src/filter_result_iterator.cpp has two code paths:

  • Batched path (when is_filter_result_initialized is true)
  • Non-batched path (used during iterative AND/OR evaluation)

The batched path correctly used get_nested_field_doc() to traverse deep
nested JSON structures.

However, the non-batched path accessed:

document[filter_node->object_field_name]

This fails for multi-level paths such as main.items, because it attempts
to look up the literal key instead of navigating:

main → items

As a result, nested filters could match incorrectly, leading to unintended
document deletions.


Solution

Updated the non-batched path to use get_nested_field_doc(), making it
consistent with the batched implementation.

Before

for (const auto& nested_object: document[filter_node->object_field_name])

After

const auto& doc = get_nested_field_doc(filter_node->object_field_name, document);
for (const auto& nested_object: doc)


Files Changed

  • src/filter_result_iterator.cpp
    → Use get_nested_field_doc() in non-batched validation path (1-line fix)

  • test/core_api_utils_test.cpp
    → Added two test cases covering nested and deep-nested delete filters


Test Plan

Added:

  • DeleteDocumentsWithNestedFieldFilter
  • DeleteDocumentsWithDeepNestedFieldFilter

Both tests verify:

  • Only matching documents are deleted
  • Non-matching documents remain
  • AND conditions within the same nested object are respected

Run tests:

bazel test //:typesense-test --test_filter="CoreAPIUtilsTest.DeleteDocumentsWithNestedFieldFilter"

bazel test //:typesense-test --test_filter="CoreAPIUtilsTest.DeleteDocumentsWithDeepNestedFieldFilter"

Or full suite:

bazel test //:typesense-test


Checklist

  • Minimal fix (single logic change)
  • Tests added
  • No unrelated refactors

Closes #2765

…tched validation

In validate_object_filter(), the non-batched code path directly accessed
document[filter_node->object_field_name], which fails for deep nested
field paths like "main.items" or "root.main.ingredients". This caused
incorrect filter matching during iterative AND/OR evaluation.

The fix uses get_nested_field_doc() to properly navigate the JSON
structure, consistent with the batched code path.

Added test coverage for nested field filter delete operations including
deep nested paths.

Closes typesense#2765
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.

API Key for operations/schema_changes not working

1 participant