mirror of https://github.com/apache/lucene.git
SOLR-14869: ChildDocTransformer should have omitted deleted child documents.
Closes #1970
This commit is contained in:
parent
2f651b156c
commit
fa3e1ad71f
|
@ -219,6 +219,8 @@ Optimizations
|
|||
Bug Fixes
|
||||
---------------------
|
||||
|
||||
* SOLR-14869: ChildDocTransformer should have omitted deleted child documents. (Bar Rotstein, David Smiley)
|
||||
|
||||
* SOLR-11656: TLOG replication doesn't work properly after rebalancing leaders. (Yuki Yano via
|
||||
Erick Erickson)
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.apache.lucene.index.LeafReaderContext;
|
|||
import org.apache.lucene.index.ReaderUtil;
|
||||
import org.apache.lucene.index.SortedDocValues;
|
||||
import org.apache.lucene.search.join.BitSetProducer;
|
||||
import org.apache.lucene.util.Bits;
|
||||
import org.apache.lucene.util.BitSet;
|
||||
import org.apache.solr.common.SolrDocument;
|
||||
import org.apache.solr.common.SolrException;
|
||||
|
@ -89,6 +90,7 @@ class ChildDocTransformer extends DocTransformer {
|
|||
final int segBaseId = leafReaderContext.docBase;
|
||||
final int segRootId = rootDocId - segBaseId;
|
||||
final BitSet segParentsBitSet = parentsFilter.getBitSet(leafReaderContext);
|
||||
final Bits liveDocs = leafReaderContext.reader().getLiveDocs();
|
||||
|
||||
if (segParentsBitSet == null) {
|
||||
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
|
||||
|
@ -117,9 +119,16 @@ class ChildDocTransformer extends DocTransformer {
|
|||
int matches = 0;
|
||||
// Loop each child ID up to the parent (exclusive).
|
||||
for (int docId = firstChildId; docId < rootDocId; ++docId) {
|
||||
final int segDocId = docId - segBaseId;
|
||||
|
||||
// check whether doc is "live"
|
||||
if (liveDocs != null && !liveDocs.get(segDocId)) {
|
||||
// doc is not "live"; return fast
|
||||
continue;
|
||||
}
|
||||
|
||||
// get the path. (note will default to ANON_CHILD_KEY if schema is not nested or empty string if blank)
|
||||
final String fullDocPath = getPathByDocId(docId - segBaseId, segPathDocValues);
|
||||
final String fullDocPath = getPathByDocId(segDocId, segPathDocValues);
|
||||
|
||||
if (isNestedSchema && !fullDocPath.startsWith(rootDocPath)) {
|
||||
// is not a descendant of the transformed doc; return fast.
|
||||
|
|
|
@ -135,6 +135,53 @@ public class TestChildDocTransformerHierarchy extends SolrTestCaseJ4 {
|
|||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithDeletedChildren() throws Exception {
|
||||
// add a doc to create another segment
|
||||
final String addNonTestedDoc =
|
||||
"{\n" +
|
||||
"\"add\": {\n" +
|
||||
"\"doc\": {\n" +
|
||||
"\"id\": " + -1000 + ", \n" +
|
||||
"\"type_s\": \"cake\", \n" +
|
||||
"}\n" +
|
||||
"}\n" +
|
||||
"}";
|
||||
|
||||
if (random().nextBoolean()) {
|
||||
updateJ(addNonTestedDoc, null);
|
||||
assertU(commit());
|
||||
}
|
||||
|
||||
indexSampleData(numberOfDocsPerNestedTest);
|
||||
// delete toppings path
|
||||
assertU(delQ("_nest_path_:\\/toppings"));
|
||||
assertU(commit());
|
||||
|
||||
try(SolrQueryRequest req = req("q", "type_s:donut", "sort", "id asc", "fl", "id, type_s, toppings, _nest_path_, [child childFilter='_nest_path_:/toppings' limit=1]",
|
||||
"fq", fqToExcludeNonTestedDocs)) {
|
||||
BasicResultContext res = (BasicResultContext) h.queryAndResponse("/select", req).getResponse();
|
||||
Iterator<SolrDocument> docsStreamer = res.getProcessedDocuments();
|
||||
while (docsStreamer.hasNext()) {
|
||||
SolrDocument doc = docsStreamer.next();
|
||||
cleanSolrDocumentFields(doc);
|
||||
assertFalse("root doc should not have anonymous child docs", doc.hasChildDocuments());
|
||||
assertNull("should not include deleted docs", doc.getFieldValues("toppings"));
|
||||
}
|
||||
}
|
||||
|
||||
assertJQ(req("q", "type_s:donut",
|
||||
"sort", "id asc",
|
||||
"fl", "*, [child limit=1]",
|
||||
"fq", fqToExcludeNonTestedDocs),
|
||||
"/response/docs/[0]/type_s==donut",
|
||||
"/response/docs/[0]/lonely/test_s==testing",
|
||||
"/response/docs/[0]/lonely/lonelyGrandChild/test2_s==secondTest",
|
||||
// "!" (negate): don't find toppings. The "limit" kept us from reaching these, which follow lonely.
|
||||
"!/response/docs/[0]/toppings/[0]/type_s==Regular"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChildFilterLimitJSON() throws Exception {
|
||||
indexSampleData(numberOfDocsPerNestedTest);
|
||||
|
|
Loading…
Reference in New Issue