SOLR-12888: Run URP now auto-registers NestedUpdateProcessor before it.

This commit is contained in:
David Smiley 2019-01-08 23:23:02 -05:00
parent d814d862b0
commit df119573db
9 changed files with 43 additions and 26 deletions

View File

@ -136,6 +136,11 @@ Improvements
'status' field, a 'message' field giving more details on the error, and an optional 'exception' field. (Shalin Mangar,
Jason Gerlowski)
* SOLR-12888: The NestedUpdateProcessor (which populates internal fields for nested child docs) is now auto-registered
to run immediately prior to RunUpdateProcessor. If the schema has no _nest_*_ fields then it's a no-op.
RunUpdateProcessorFactory looks up a special/internal URP chain "_preRun_" which is implicitly defined but could be
defined by an app for customization if desired. (David Smiley)
Optimizations
----------------------

View File

@ -152,6 +152,7 @@ import org.apache.solr.update.UpdateHandler;
import org.apache.solr.update.VersionInfo;
import org.apache.solr.update.processor.DistributedUpdateProcessorFactory;
import org.apache.solr.update.processor.LogUpdateProcessorFactory;
import org.apache.solr.update.processor.NestedUpdateProcessorFactory;
import org.apache.solr.update.processor.RunUpdateProcessorFactory;
import org.apache.solr.update.processor.UpdateRequestProcessorChain;
import org.apache.solr.update.processor.UpdateRequestProcessorChain.ProcessorInfo;
@ -1434,7 +1435,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
/**
* Load the request processors
*/
private Map<String,UpdateRequestProcessorChain> loadUpdateProcessorChains() {
private Map<String,UpdateRequestProcessorChain> loadUpdateProcessorChains() {
Map<String, UpdateRequestProcessorChain> map = new HashMap<>();
UpdateRequestProcessorChain def = initPlugins(map,UpdateRequestProcessorChain.class, UpdateRequestProcessorChain.class.getName());
if(def == null){
@ -1452,6 +1453,10 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
}
map.put(null, def);
map.put("", def);
map.computeIfAbsent(RunUpdateProcessorFactory.PRE_RUN_CHAIN_NAME,
k -> new UpdateRequestProcessorChain(Collections.singletonList(new NestedUpdateProcessorFactory()), this));
return map;
}

View File

@ -62,7 +62,7 @@ public class LogUpdateProcessorFactory extends UpdateRequestProcessorFactory imp
@Override
public UpdateRequestProcessor getInstance(SolrQueryRequest req, SolrQueryResponse rsp, UpdateRequestProcessor next) {
return log.isInfoEnabled() ? new LogUpdateProcessor(req, rsp, this, next) : null;
return log.isInfoEnabled() ? new LogUpdateProcessor(req, rsp, this, next) : next;
}
static class LogUpdateProcessor extends UpdateRequestProcessor {

View File

@ -21,7 +21,7 @@ import org.apache.solr.response.SolrQueryResponse;
/**
* A No-Op implementation of DistributingUpdateProcessorFactory that
* allways returns null.
* allways returns the next processor instead of inserting a new URP in front of it.
* <p>
* This implementation may be useful for Solr installations in which neither
* the <code>{@link DistributedUpdateProcessorFactory}</code> nor any custom
@ -34,12 +34,12 @@ public class NoOpDistributingUpdateProcessorFactory
extends UpdateRequestProcessorFactory
implements DistributingUpdateProcessorFactory {
/** Returns null
/** Returns the next
*/
@Override
public UpdateRequestProcessor getInstance(SolrQueryRequest req,
SolrQueryResponse rsp,
UpdateRequestProcessor next ) {
return null;
return next;
}
}

View File

@ -35,10 +35,19 @@ import org.apache.solr.update.*;
*/
public class RunUpdateProcessorFactory extends UpdateRequestProcessorFactory
{
public static final String PRE_RUN_CHAIN_NAME = "_preRun_";
@Override
public UpdateRequestProcessor getInstance(SolrQueryRequest req, SolrQueryResponse rsp, UpdateRequestProcessor next)
{
return new RunUpdateProcessor(req, next);
RunUpdateProcessor runUpdateProcessor = new RunUpdateProcessor(req, next);
UpdateRequestProcessorChain preRun = req.getCore().getUpdateProcessingChain(PRE_RUN_CHAIN_NAME);
if (preRun != null) {
return preRun.createProcessor(req, rsp, false, runUpdateProcessor);
} else {
return runUpdateProcessor;
}
}
}

View File

@ -180,7 +180,6 @@ public final class UpdateRequestProcessorChain implements PluginInfoInitialized
this.solrCore = solrCore;
}
/**
* Uses the factories in this chain to creates a new
* <code>UpdateRequestProcessor</code> instance specific for this request.
@ -193,13 +192,17 @@ public final class UpdateRequestProcessorChain implements PluginInfoInitialized
* @see DistributingUpdateProcessorFactory#DISTRIB_UPDATE_PARAM
*/
public UpdateRequestProcessor createProcessor(SolrQueryRequest req,
SolrQueryResponse rsp)
{
UpdateRequestProcessor processor = null;
UpdateRequestProcessor last = null;
SolrQueryResponse rsp) {
final String distribPhase = req.getParams().get(DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM);
final boolean skipToDistrib = distribPhase != null;
return createProcessor(req, rsp, skipToDistrib, null);
}
/**
* @lucene.internal
*/
public UpdateRequestProcessor createProcessor(SolrQueryRequest req,
SolrQueryResponse rsp, boolean skipToDistrib, UpdateRequestProcessor last) {
boolean afterDistrib = true; // we iterate backwards, so true to start
for (int i = chain.size() - 1; i >= 0; i--) {
@ -216,8 +219,8 @@ public final class UpdateRequestProcessorChain implements PluginInfoInitialized
}
}
processor = factory.getInstance(req, rsp, last);
last = processor == null ? last : processor;
// create a new URP with current "last" following it; then replace "last" with this new URP
last = factory.getInstance(req, rsp, last);
}
return last;
@ -242,7 +245,7 @@ public final class UpdateRequestProcessorChain implements PluginInfoInitialized
//port-processor is tried to be inserted before RunUpdateProcessor
insertBefore(urps, post, RunUpdateProcessorFactory.class, urps.size() - 1);
UpdateRequestProcessorChain result = new UpdateRequestProcessorChain(urps, core);
if (log.isInfoEnabled()) {
if (log.isDebugEnabled()) {
ArrayList<String> names = new ArrayList<>(urps.size());
for (UpdateRequestProcessorFactory urp : urps) names.add(urp.getClass().getSimpleName());
log.debug("New dynamic chain constructed : " + StrUtils.join(names, '>'));

View File

@ -30,11 +30,6 @@
<directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.RAMDirectoryFactory}"/>
<schemaFactory class="ClassicIndexSchemaFactory"/>
<updateRequestProcessorChain name="nested">
<processor class="solr.NestedUpdateProcessorFactory" />
<processor class="solr.RunUpdateProcessorFactory" />
</updateRequestProcessorChain>
<updateRequestProcessorChain name="comprehensive">
<processor class="solr.FieldLengthUpdateProcessorFactory">
<arr name="typeClass">

View File

@ -48,14 +48,14 @@ public class TestChildDocTransformerHierarchy extends SolrTestCaseJ4 {
@BeforeClass
public static void beforeClass() throws Exception {
initCore("solrconfig-update-processor-chains.xml", "schema-nest.xml"); // use "nest" schema
initCore("solrconfig-minimal.xml", "schema-nest.xml"); // use "nest" schema
if(random().nextBoolean()) {
idCounter.set(-100); // start docIDs at -100 for these random docs we don't care about (all less than 0)
// create random segments
final int numOfDocs = 10;
for(int i = 0; i < numOfDocs; ++i) {
updateJ(generateDocHierarchy(i), params("update.chain", "nested"));
updateJ(generateDocHierarchy(i), null);
if(random().nextBoolean()) {
assertU(commit());
}
@ -287,7 +287,7 @@ public class TestChildDocTransformerHierarchy extends SolrTestCaseJ4 {
"}\n" +
"}\n" +
"}";
updateJ(addDocWoChildren, params("update.chain", "nested"));
updateJ(addDocWoChildren, null);
assertU(commit());
assertJQ(req("q", "type_s:cake",
@ -299,7 +299,7 @@ public class TestChildDocTransformerHierarchy extends SolrTestCaseJ4 {
private void indexSampleData(int numDocs) throws Exception {
for(int i = 0; i < numDocs; ++i) {
updateJ(generateDocHierarchy(i), params("update.chain", "nested"));
updateJ(generateDocHierarchy(i), null);
}
assertU(commit());
}

View File

@ -90,7 +90,7 @@ public class TestNestedUpdateProcessor extends SolrTestCaseJ4 {
@BeforeClass
public static void beforeClass() throws Exception {
initCore("solrconfig-update-processor-chains.xml", "schema-nest.xml");
initCore("solrconfig-minimal.xml", "schema-nest.xml");
}
@Before
@ -189,7 +189,7 @@ public class TestNestedUpdateProcessor extends SolrTestCaseJ4 {
}
private void indexSampleData(String cmd) throws Exception {
updateJ(cmd, params("update.chain", "nested"));
updateJ(cmd, null);
assertU(commit());
}
}