Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d29e647
Support kNN filter on nested metadata
mayya-sharipova Oct 1, 2024
6e6abae
Update docs/changelog/113949.yaml
mayya-sharipova Oct 2, 2024
426db4d
Spotless
mayya-sharipova Oct 2, 2024
d9eb1e9
Address test failure
mayya-sharipova Oct 2, 2024
891b091
Fix test
mayya-sharipova Oct 2, 2024
923b6c0
Fix test failure
mayya-sharipova Oct 2, 2024
d9a13a9
Merge remote-tracking branch 'upstream/main' into knn_query_nested_fi…
mayya-sharipova Oct 2, 2024
9aa706f
Merge remote-tracking branch 'upstream/main' into knn_query_nested_fi…
mayya-sharipova Oct 25, 2024
9c56fff
Allow filters on both parent and nested metadata in the same knn query
mayya-sharipova Oct 25, 2024
afe3d8f
Merge remote-tracking branch 'upstream/main' into knn_query_nested_fi…
mayya-sharipova Jul 9, 2025
7bc25d3
Add documentation
mayya-sharipova Jul 9, 2025
e3b0251
Add pre-check for a query to be both on nested and parent metada field
mayya-sharipova Jul 9, 2025
a2f365e
Revert "Add pre-check for a query to be both on nested and parent met…
mayya-sharipova Jul 11, 2025
f423619
Add small changes
mayya-sharipova Jul 11, 2025
acbfccd
Add test for nested sibling docs
mayya-sharipova Jul 12, 2025
7cc0b09
Merge remote-tracking branch 'upstream/main' into knn_query_nested_fi…
mayya-sharipova Jul 12, 2025
1aa3605
Merge remote-tracking branch 'upstream/main' into knn_query_nested_fi…
mayya-sharipova Jul 29, 2025
5a818bc
Some adjustments
mayya-sharipova Jul 29, 2025
6c3230e
Merge remote-tracking branch 'upstream/main' into knn_query_nested_fi…
mayya-sharipova Jul 29, 2025
c0bb4ff
Update docs/changelog/113949.yaml
mayya-sharipova Jul 29, 2025
24e4943
Merge branch 'main' into knn_query_nested_filter
mayya-sharipova Jul 29, 2025
8f9cf54
Merge branch 'main' into knn_query_nested_filter
mayya-sharipova Jul 29, 2025
867b928
Merge branch 'main' into knn_query_nested_filter
mayya-sharipova Jul 29, 2025
cdf4e92
Merge branch 'main' into knn_query_nested_filter
mayya-sharipova Jul 29, 2025
d6d5f8e
Merge branch 'main' into knn_query_nested_filter
mayya-sharipova Jul 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ setup:
type: hnsw
m: 16
ef_construction: 200
nested2:
type: nested
properties:
key:
type: keyword
value:
type: keyword

- do:
index:
Expand All @@ -43,6 +50,12 @@ setup:
- paragraph_id: 1
vector: [240.0, 300, -3, 1, -20]
language: FR
nested2:
- key: "category"
value: "domestic"
- key: "level"
value: "beginner"


- do:
index:
Expand All @@ -60,6 +73,11 @@ setup:
- paragraph_id: 3
vector: [0, 1.0, 0, 1.8, -15.0]
language: FR
nested2:
- key: "category"
value: "wild"
- key: "level"
value: "beginner"

- do:
index:
Expand All @@ -71,6 +89,11 @@ setup:
- paragraph_id: 0
vector: [0.5, 111.3, -13.0, 14.8, -156.0]
language: FR
nested2:
- key: "category"
value: "domestic"
- key: "level"
value: "advanced"

- do:
indices.refresh: {}
Expand Down Expand Up @@ -561,3 +584,32 @@ setup:
- match: { hits.hits.0.inner_hits.nested.hits.hits.0.fields.nested.0.language.0: "FR" }
- close_to: { hits.hits.0._score: { value: 0.0043, error: 0.0001 } }

---
"Test filter on sibling nested fields doesn't work":
- requires:
capabilities:
- method: POST
path: /_search
capabilities: [ knn_filter_on_nested_fields ]
test_runner_features: ["capabilities", "close_to"]
reason: "Capability for filtering on nested fields required"

- do:
search:
index: test
body:
_source: false
knn:
field: nested.vector
query_vector: [ -0.5, 90.0, -10, 14.8, -156.0 ]
filter:
nested:
path: nested2
query:
bool:
filter:
- match:
nested2.key: "category"
- match:
nested2.value: "domestic"
- match: { hits.total.value: 2}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here with the current implementation we can query nested sibling fields.

Copy link
Member

Choose a reason for hiding this comment

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

I was sort of hoping that we could do something similar in the nested query since we look to the parent level. But it gets too complicated given the nested context?

Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ setup:
dims: 5
index: true
similarity: l2_norm
nested2:
type: nested
properties:
key:
type: keyword
value:
type: keyword
aliases:
my_alias:
filter:
Expand All @@ -44,6 +51,11 @@ setup:
- paragraph_id: 1
vector: [240.0, 300, -3, 1, -20]
language: FR
nested2:
- key: "category"
value: "domestic"
- key: "level"
value: "beginner"

- do:
index:
Expand All @@ -61,6 +73,12 @@ setup:
- paragraph_id: 3
vector: [0, 1.0, 0, 1.8, -15.0]
language: FR
nested2:
- key: "category"
value: "wild"
- key: "level"
value: "beginner"


- do:
index:
Expand All @@ -72,6 +90,11 @@ setup:
- paragraph_id: 0
vector: [0.5, 111.3, -13.0, 14.8, -156.0]
language: FR
nested2:
- key: "category"
value: "domestic"
- key: "level"
value: "advanced"

- do:
indices.refresh: {}
Expand Down Expand Up @@ -521,3 +544,42 @@ setup:
- match: { hits.hits.0.inner_hits.nested.hits.hits.0.fields.nested.0.language.0: "FR" }
- close_to: { hits.hits.0._score: { value: 0.0041, error: 0.0001 } }
- close_to: { hits.hits.0.inner_hits.nested.hits.hits.0._score: { value: 0.0041, error: 0.0001 } }


---
"Test filter on sibling nested fields doesn't work":
- requires:
capabilities:
- method: POST
path: /_search
capabilities: [ knn_filter_on_nested_fields ]
test_runner_features: ["capabilities", "close_to"]
reason: "Capability for filtering on nested fields required"

- do:
search:
index: test
body:
_source: false
query:
nested:
path: nested
query:
knn:
field: nested.vector
query_vector: [-0.5, 90.0, -10, 14.8, -156.0]
k: 10
filter:
nested:
path: nested2
query:
bool:
filter:
- match:
nested2.key: "category"
- match:
nested2.value: "domestic"
inner_hits: { size: 3, "fields": [ "nested.paragraph_id", "nested.language"], _source: false }

- match: { hits.total.value: 0 }
Copy link
Contributor Author

@mayya-sharipova mayya-sharipova Jul 12, 2025

Choose a reason for hiding this comment

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

@benwtrent Notice how for nested query the DSL itself doesn't allow to filter on nested sibling fields, as the top level query:nested:path sets the parent context.

Copy link
Member

Choose a reason for hiding this comment

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

@mayya-sharipova thank you.

I was thinking it would be possible via boolean with two separate nested contexts.

Copy link
Member

Choose a reason for hiding this comment

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

They key issue is that with kNN search, we need to be clear that its within a SINGLE nested context (either top level, or its own context).

That gets tricky, and maybe we can make it better in the future. But the current compromise unblocks some folks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can not think of any way to support pre-filtering on nested sibling fields in knn query. We can do the following, but it would be post-filter:

  - do:
      search:
        index: test
        body:
          _source: false
          query:
            bool:
              must:
                - nested:
                    path: nested
                    query:
                      knn:
                        field: nested.vector
                        query_vector: [-0.5, 90.0, -10, 14.8, -156.0]
                        k: 10
              filter:
                - nested:
                    path: nested2
                    query:
                      bool:
                        filter:
                          - match:
                              nested2.key: "category"
                          - match:
                              nested2.value: "domestic"


Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ protected Query doToQuery(SearchExecutionContext context) throws IOException {
parentFilter = Queries.newNonNestedFilter(context.indexVersionCreated());
}
parentBitSet = context.bitsetFilter(parentFilter);
ArrayList<Query> filterAdjusted = new ArrayList<>(filtersInitial.size());
List<Query> filterAdjusted = new ArrayList<>(filtersInitial.size());
for (Query f : filtersInitial) {
// If filter matches non-nested docs, we assume this is a filter over parents docs,
// so we will modify it accordingly: matching parents docs with join to its child docs
Expand Down