This is an automated email from the ASF dual-hosted git repository.

epugh pushed a commit to branch branch_10x
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/branch_10x by this push:
     new 5ebffb9b638 SOLR-18039: Support repeated parents.preFilter in 
KnnQParser (#4139)
5ebffb9b638 is described below

commit 5ebffb9b63860f943ac6b0189af5caa963cec569
Author: Arup Chauhan <[email protected]>
AuthorDate: Thu Feb 19 07:54:59 2026 -0600

    SOLR-18039: Support repeated parents.preFilter in KnnQParser (#4139)
    
    Signed-off-by: Arup Chauhan <[email protected]>
---
 .../unreleased/parents-prefilter-multi-value.yml   |  9 ++++++++
 .../org/apache/solr/search/vector/KnnQParser.java  | 24 ++++++++++++++--------
 .../join/BlockJoinNestedVectorsQParserTest.java    | 17 +++++++++++++++
 3 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/changelog/unreleased/parents-prefilter-multi-value.yml 
b/changelog/unreleased/parents-prefilter-multi-value.yml
new file mode 100644
index 00000000000..15e6615aa4e
--- /dev/null
+++ b/changelog/unreleased/parents-prefilter-multi-value.yml
@@ -0,0 +1,9 @@
+# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc
+title: Support repeated parents.preFilter values in nested vector knn queries
+type: fixed # added, changed, fixed, deprecated, removed, dependency_update, 
security, other
+authors:
+  - name: Arup Chauhan
+    nick: arup-chauhan
+links:
+  - name: SOLR-18039
+    url: https://issues.apache.org/jira/browse/SOLR-18039
diff --git a/solr/core/src/java/org/apache/solr/search/vector/KnnQParser.java 
b/solr/core/src/java/org/apache/solr/search/vector/KnnQParser.java
index 95ff94ea372..2170f56f19b 100644
--- a/solr/core/src/java/org/apache/solr/search/vector/KnnQParser.java
+++ b/solr/core/src/java/org/apache/solr/search/vector/KnnQParser.java
@@ -133,10 +133,11 @@ public class KnnQParser extends AbstractVectorQParserBase 
{
     final Integer filteredSearchThreshold = 
localParams.getInt(FILTERED_SEARCH_THRESHOLD);
 
     // check for parent diversification logic...
-    final String parentsFilterQuery = localParams.get(PARENTS_PRE_FILTER);
+    final String[] parentsFilterQueries = 
localParams.getParams(PARENTS_PRE_FILTER);
     final String allParentsQuery = localParams.get(CHILDREN_OF);
 
-    boolean isDiversifyingChildrenKnnQuery = null != parentsFilterQuery || 
null != allParentsQuery;
+    boolean isDiversifyingChildrenKnnQuery =
+        null != parentsFilterQueries || null != allParentsQuery;
     if (isDiversifyingChildrenKnnQuery) {
       if (null == allParentsQuery) {
         throw new SolrException(
@@ -150,7 +151,7 @@ public class KnnQParser extends AbstractVectorQParserBase {
       final BitSetProducer allParentsBitSet =
           BlockJoinParentQParser.getCachedBitSetProducer(
               req, subQuery(allParentsQuery, null).getQuery());
-      final BooleanQuery acceptedParents = 
getParentsFilter(parentsFilterQuery);
+      final BooleanQuery acceptedParents = 
getParentsFilter(parentsFilterQueries);
 
       Query acceptedChildren =
           getChildrenFilter(getFilterQuery(), acceptedParents, 
allParentsBitSet);
@@ -183,14 +184,19 @@ public class KnnQParser extends AbstractVectorQParserBase 
{
         filteredSearchThreshold);
   }
 
-  private BooleanQuery getParentsFilter(String parentsFilterQuery) throws 
SyntaxError {
+  private BooleanQuery getParentsFilter(String[] parentsFilterQueries) throws 
SyntaxError {
     BooleanQuery.Builder acceptedParentsBuilder = new BooleanQuery.Builder();
-    if (parentsFilterQuery != null) {
-      final Query parentsFilter = subQuery(parentsFilterQuery, 
null).getQuery();
-      acceptedParentsBuilder.add(parentsFilter, BooleanClause.Occur.FILTER);
+    if (parentsFilterQueries != null) {
+      for (String parentsFilterQuery : parentsFilterQueries) {
+        final QParser parser = subQuery(parentsFilterQuery, null);
+        parser.setIsFilter(true);
+        final Query parentsFilter = parser.getQuery();
+        if (parentsFilter != null) {
+          acceptedParentsBuilder.add(parentsFilter, 
BooleanClause.Occur.FILTER);
+        }
+      }
     }
-    BooleanQuery acceptedParents = acceptedParentsBuilder.build();
-    return acceptedParents;
+    return acceptedParentsBuilder.build();
   }
 
   private Query getChildrenFilter(
diff --git 
a/solr/core/src/test/org/apache/solr/search/join/BlockJoinNestedVectorsQParserTest.java
 
b/solr/core/src/test/org/apache/solr/search/join/BlockJoinNestedVectorsQParserTest.java
index 3dbf2f98037..176aaf224c1 100644
--- 
a/solr/core/src/test/org/apache/solr/search/join/BlockJoinNestedVectorsQParserTest.java
+++ 
b/solr/core/src/test/org/apache/solr/search/join/BlockJoinNestedVectorsQParserTest.java
@@ -229,6 +229,23 @@ public class BlockJoinNestedVectorsQParserTest extends 
SolrTestCaseJ4 {
         "//result/doc[3]/str[@name='id'][.='2']");
   }
 
+  @Test
+  public void 
parentRetrievalFloat_knnChildrenWithMultipleParentFilters_shouldReturnKnnParents()
 {
+    assertQ(
+        req(
+            "q", "{!parent which=$allParents score=max v=$children.q}",
+            "fl", "id,score",
+            "children.q",
+                "{!knn f=vector topK=3 parents.preFilter=$parentFilter1 
parents.preFilter=$parentFilter2 childrenOf=$allParents}"
+                    + FLOAT_QUERY_VECTOR,
+            "allParents", "parent_s:[* TO *]",
+            "parentFilter1", "parent_s:(a c)",
+            "parentFilter2", "parent_s:(c e)"),
+        "//*[@numFound='2']",
+        "//result/doc[1]/str[@name='id'][.='8']",
+        "//result/doc[2]/str[@name='id'][.='2']");
+  }
+
   @Test
   public void
       
parentRetrievalFloat_knnChildrenWithParentFilterAndChildrenFilter_shouldReturnKnnParents()
 {

Reply via email to