diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 03c97fd8767..1e0e530bf19 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -212,6 +212,8 @@ Bug Fixes * SOLR-12868: Request forwarding for v2 API is broken (noble) +* SOLR-7557: Fix parsing of child documents using queryAndStreamResponse (Marvin Bredal Lillehaug/Stian Østerhaug via janhoy) + Improvements ---------------------- diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/StreamingBinaryResponseParser.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/StreamingBinaryResponseParser.java index 5f88672a7be..b70daeeed2d 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/StreamingBinaryResponseParser.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/StreamingBinaryResponseParser.java @@ -47,11 +47,21 @@ public class StreamingBinaryResponseParser extends BinaryResponseParser { public NamedList processResponse(InputStream body, String encoding) { try (JavaBinCodec codec = new JavaBinCodec() { + private int nestedLevel; + @Override public SolrDocument readSolrDocument(DataInputInputStream dis) throws IOException { + nestedLevel++; SolrDocument doc = super.readSolrDocument(dis); - callback.streamSolrDocument( doc ); - return null; + nestedLevel--; + if (nestedLevel == 0) { + // parent document + callback.streamSolrDocument(doc); + return null; + } else { + // child document + return doc; + } } @Override diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingBinaryTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingBinaryTest.java index 14280543061..bcab5675b43 100644 --- a/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingBinaryTest.java +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingBinaryTest.java @@ -16,12 +16,21 @@ */ package org.apache.solr.client.solrj.embedded; +import java.util.ArrayList; +import java.util.List; + import org.apache.solr.SolrTestCaseJ4.SuppressSSL; import org.apache.lucene.util.LuceneTestCase.Slow; import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.StreamingResponseCallback; import org.apache.solr.client.solrj.impl.BinaryRequestWriter; import org.apache.solr.client.solrj.impl.BinaryResponseParser; import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrClient; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.common.SolrDocument; +import org.apache.solr.common.SolrInputDocument; +import org.junit.Test; @Slow @SuppressSSL(bugUrl = "https://issues.apache.org/jira/browse/SOLR-5776") @@ -34,4 +43,51 @@ public class SolrExampleStreamingBinaryTest extends SolrExampleStreamingTest { client.setRequestWriter(new BinaryRequestWriter()); return client; } + + @Test + public void testQueryAndStreamResponse() throws Exception { + // index a simple document with one child + SolrClient client = getSolrClient(); + client.deleteByQuery("*:*"); + + SolrInputDocument child = new SolrInputDocument(); + child.addField("id", "child"); + child.addField("type_s", "child"); + child.addField("text_s", "text"); + + SolrInputDocument parent = new SolrInputDocument(); + parent.addField("id", "parent"); + parent.addField("type_s", "parent"); + parent.addChildDocument(child); + + client.add(parent); + client.commit(); + + // create a query with child doc transformer + SolrQuery query = new SolrQuery("{!parent which='type_s:parent'}text_s:text"); + query.addField("*,[child parentFilter='type_s:parent']"); + + // test regular query + QueryResponse response = client.query(query); + assertEquals(1, response.getResults().size()); + SolrDocument parentDoc = response.getResults().get(0); + assertEquals(1, parentDoc.getChildDocumentCount()); + + // test streaming + final List docs = new ArrayList<>(); + client.queryAndStreamResponse(query, new StreamingResponseCallback() { + @Override + public void streamSolrDocument(SolrDocument doc) { + docs.add(doc); + } + + @Override + public void streamDocListInfo(long numFound, long start, Float maxScore) { + } + }); + + assertEquals(1, docs.size()); + parentDoc = docs.get(0); + assertEquals(1, parentDoc.getChildDocumentCount()); + } }