You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by sh...@apache.org on 2014/07/29 18:46:27 UTC

svn commit: r1614416 - in /lucene/dev/trunk/solr: ./ core/src/java/org/apache/solr/update/processor/ core/src/test-files/solr/collection1/conf/ core/src/test/org/apache/solr/update/processor/ example/example-schemaless/solr/collection1/conf/

Author: shalin
Date: Tue Jul 29 16:46:26 2014
New Revision: 1614416

URL: http://svn.apache.org/r1614416
Log:
SOLR-6020: Auto-generate a unique key in schema-less example if data does not have an id field

Added:
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/processor/UUIDUpdateProcessorFallbackTest.java   (with props)
Modified:
    lucene/dev/trunk/solr/CHANGES.txt
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/AbstractDefaultValueUpdateProcessorFactory.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/UUIDUpdateProcessorFactory.java
    lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml
    lucene/dev/trunk/solr/example/example-schemaless/solr/collection1/conf/solrconfig.xml

Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=1614416&r1=1614415&r2=1614416&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Tue Jul 29 16:46:26 2014
@@ -161,6 +161,11 @@ New Features
 * SOLR-6267: Let user override Interval Faceting key with LocalParams (Tomas Fernandez_Lobbe
   via Erick Erickson)
 
+* SOLR-6020: Auto-generate a unique key in schema-less example if data does not have an id field.
+  The UUIDUpdateProcessor was improved to not require a field name in configuration and generate
+  a UUID into the unique Key field.
+  (Vitaliy Zhovtyuk, hossman, Steve Rowe, Erik Hatcher, shalin)
+
 
 Bug Fixes
 ----------------------

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/AbstractDefaultValueUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/AbstractDefaultValueUpdateProcessorFactory.java?rev=1614416&r1=1614415&r2=1614416&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/AbstractDefaultValueUpdateProcessorFactory.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/AbstractDefaultValueUpdateProcessorFactory.java Tue Jul 29 16:46:26 2014
@@ -72,7 +72,7 @@ public abstract class AbstractDefaultVal
    * to any document which does not already have a value in 
    * <code>fieldName</code>
    */
-  protected static abstract class DefaultValueUpdateProcessor 
+  static abstract class DefaultValueUpdateProcessor
     extends UpdateRequestProcessor {
 
     final String fieldName;

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/UUIDUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/UUIDUpdateProcessorFactory.java?rev=1614416&r1=1614415&r2=1614416&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/UUIDUpdateProcessorFactory.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/UUIDUpdateProcessorFactory.java Tue Jul 29 16:46:26 2014
@@ -17,29 +17,28 @@
 
 package org.apache.solr.update.processor;
 
-import java.io.IOException;
 import java.util.UUID;
 import java.util.Locale;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.solr.common.SolrException;
 import static org.apache.solr.common.SolrException.ErrorCode.*;
-import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.response.SolrQueryResponse;
-import org.apache.solr.update.AddUpdateCommand;
+import org.apache.solr.schema.SchemaField;
 
 
 /**
  * <p>
- * An update processor that adds a newly generated <code>UUID</code> value 
- * to any document being added that does not already have a value in the 
+ * An update processor that adds a newly generated <code>UUID</code> value
+ * to any document being added that does not already have a value in the
  * specified field.
  * </p>
  *
  * <p>
- * In the example configuration below, if a document does not contain a value 
- * in the <code>id</code> field, a new <code>UUID</code> will be generated 
+ * In the example configuration below, if a document does not contain a value
+ * in the <code>id</code> field, a new <code>UUID</code> will be generated
  * and added as the value of that field.
  * <p>
  *
@@ -48,19 +47,46 @@ import org.apache.solr.update.AddUpdateC
  *   &lt;str name="fieldName"&gt;id&lt;/str&gt;
  * &lt;/processor&gt;
  * </pre>
- * 
+ *
+ * <p>
+ * If field name is omitted in processor configuration,
+ * then  @{link org.apache.solr.schema.IndexSchema#getUniqueKeyField()}</code>
+ * is used as field and a new <code>UUID</code> will be generated
+ * and added as the value of that field. The field type of the uniqueKeyField
+ * must be anything which accepts a string or UUID value.
+ * <p>
  * @see UUID
  */
-public class UUIDUpdateProcessorFactory
-  extends AbstractDefaultValueUpdateProcessorFactory {
+public class UUIDUpdateProcessorFactory extends UpdateRequestProcessorFactory {
+
+  protected String fieldName = null;
 
-  @Override
-  public UpdateRequestProcessor getInstance(SolrQueryRequest req, 
-                                            SolrQueryResponse rsp, 
+  @SuppressWarnings("unchecked")
+  public void init(NamedList args) {
+
+    Object obj = args.remove("fieldName");
+    if (null != obj) {
+      fieldName = obj.toString();
+    }
+
+    if (0 < args.size()) {
+      throw new SolrException(SERVER_ERROR,
+          "Unexpected init param(s): '" +
+              args.getName(0) + "'");
+    }
+  }
+
+  public UpdateRequestProcessor getInstance(SolrQueryRequest req,
+                                            SolrQueryResponse rsp,
                                             UpdateRequestProcessor next ) {
-    return new DefaultValueUpdateProcessor(fieldName, next) {
+    if (StringUtils.isEmpty(fieldName)) {
+      SchemaField schemaField = req.getSchema().getUniqueKeyField();
+      fieldName = schemaField.getName();
+    }
+
+    return new AbstractDefaultValueUpdateProcessorFactory.DefaultValueUpdateProcessor(fieldName, next) {
       @Override
-      public Object getDefaultValue() { 
+      public Object getDefaultValue() {
         return UUID.randomUUID().toString().toLowerCase(Locale.ROOT);
       }
     };

Modified: lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml?rev=1614416&r1=1614415&r2=1614416&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml (original)
+++ lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/solrconfig-update-processor-chains.xml Tue Jul 29 16:46:26 2014
@@ -468,6 +468,18 @@
     </processor>
   </updateRequestProcessorChain>
 
+
+  <updateRequestProcessorChain name="default-values-fallback-to-unique">
+    <processor class="solr.UUIDUpdateProcessorFactory">
+      <str name="fieldName">id</str>
+    </processor>
+  </updateRequestProcessorChain>
+
+  <updateRequestProcessorChain name="default-values-fallback-to-unique-automatically">
+    <processor class="solr.UUIDUpdateProcessorFactory">
+    </processor>
+  </updateRequestProcessorChain>
+
   <updateRequestProcessorChain name="uniq-values">
     <processor class="solr.UniqFieldsUpdateProcessorFactory">
       <str name="fieldRegex">uniq_.*</str>

Added: lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/processor/UUIDUpdateProcessorFallbackTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/processor/UUIDUpdateProcessorFallbackTest.java?rev=1614416&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/processor/UUIDUpdateProcessorFallbackTest.java (added)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/processor/UUIDUpdateProcessorFallbackTest.java Tue Jul 29 16:46:26 2014
@@ -0,0 +1,155 @@
+package org.apache.solr.update.processor;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.SolrInputField;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.request.LocalSolrQueryRequest;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.request.SolrRequestInfo;
+import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.update.AddUpdateCommand;
+import org.junit.BeforeClass;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.UUID;
+
+public class UUIDUpdateProcessorFallbackTest extends SolrTestCaseJ4 {
+
+  @BeforeClass
+  public static void beforeClass() throws Exception {
+    initCore("solrconfig-update-processor-chains.xml", "schema.xml");
+  }
+
+  public void testFallbackToUnique() throws Exception {
+    Date now = new Date();
+
+    // get all defaults
+    SolrInputDocument d = processAdd("default-values-fallback-to-unique",
+                   doc(f("name", "Existing", "Values")));
+
+    assertNotNull(d);
+
+    assertNotNull(d.getFieldValue("id"));
+    assertNotNull(UUID.fromString(d.getFieldValue("id").toString()));
+
+    // get all defaults
+    d = processAdd("default-values-fallback-to-unique-automatically",
+        doc(f("name", "Existing", "Values")));
+
+    assertNotNull(d);
+
+    assertNotNull(d.getFieldValue("id"));
+    assertNotNull(UUID.fromString(d.getFieldValue("id").toString()));
+
+    // defaults already specified
+    d = processAdd("default-values-fallback-to-unique",
+                   doc(f("timestamp", now),
+                       f("id", "550e8400-e29b-41d4-a716-446655440000"),
+                       f("processor_default_s", "I HAVE A VALUE"),
+                       f("processor_default_i", 12345),
+                       f("name", "Existing", "Values")));
+
+    assertNotNull(d);
+
+    assertEquals("550e8400-e29b-41d4-a716-446655440000",
+                 d.getFieldValue("id"));
+
+    // defaults already specified
+    d = processAdd("default-values-fallback-to-unique-automatically",
+        doc(f("timestamp", now),
+            f("id", "550e8400-e29b-41d4-a716-446655440000"),
+            f("processor_default_s", "I HAVE A VALUE"),
+            f("processor_default_i", 121),
+            f("name", "Existing", "Values")));
+
+    assertNotNull(d);
+
+    assertEquals("550e8400-e29b-41d4-a716-446655440000",
+        d.getFieldValue("id"));
+    assertEquals(121, d.getFieldValue("processor_default_i"));
+  }
+
+
+  /** 
+   * Convenience method for building up SolrInputDocuments
+   */
+  SolrInputDocument doc(SolrInputField... fields) {
+    SolrInputDocument d = new SolrInputDocument();
+    for (SolrInputField f : fields) {
+      d.put(f.getName(), f);
+    }
+    return d;
+  }
+
+  /** 
+   * Convenience method for building up SolrInputFields
+   */
+  SolrInputField field(String name, float boost, Object... values) {
+    SolrInputField f = new SolrInputField(name);
+    for (Object v : values) {
+      f.addValue(v, 1.0F);
+    }
+    f.setBoost(boost);
+    return f;
+  }
+
+  /** 
+   * Convenience method for building up SolrInputFields with default boost
+   */
+  SolrInputField f(String name, Object... values) {
+    return field(name, 1.0F, values);
+  }
+
+
+  /**
+   * Runs a document through the specified chain, and returns the final 
+   * document used when the chain is completed (NOTE: some chains may 
+   * modify the document in place
+   */
+  SolrInputDocument processAdd(final String chain, 
+                               final SolrInputDocument docIn) 
+    throws IOException {
+
+    SolrCore core = h.getCore();
+    UpdateRequestProcessorChain pc = core.getUpdateProcessingChain(chain);
+    assertNotNull("No Chain named: " + chain, pc);
+
+    SolrQueryResponse rsp = new SolrQueryResponse();
+
+    SolrQueryRequest req = new LocalSolrQueryRequest
+      (core, new ModifiableSolrParams());
+    try {
+      SolrRequestInfo.setRequestInfo(new SolrRequestInfo(req,rsp));
+      AddUpdateCommand cmd = new AddUpdateCommand(req);
+      cmd.solrDoc = docIn;
+
+      UpdateRequestProcessor processor = pc.createProcessor(req, rsp);
+      processor.processAdd(cmd);
+
+      return cmd.solrDoc;
+    } finally {
+      SolrRequestInfo.clearRequestInfo();
+      req.close();
+    }
+  }
+}

Modified: lucene/dev/trunk/solr/example/example-schemaless/solr/collection1/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/example/example-schemaless/solr/collection1/conf/solrconfig.xml?rev=1614416&r1=1614415&r2=1614416&view=diff
==============================================================================
--- lucene/dev/trunk/solr/example/example-schemaless/solr/collection1/conf/solrconfig.xml (original)
+++ lucene/dev/trunk/solr/example/example-schemaless/solr/collection1/conf/solrconfig.xml Tue Jul 29 16:46:26 2014
@@ -1549,6 +1549,9 @@
        See http://wiki.apache.org/solr/GuessingFieldTypes
     -->
   <updateRequestProcessorChain name="add-unknown-fields-to-the-schema">
+    <!-- UUIDUpdateProcessorFactory will generate an id if none is present in the incoming document -->
+    <processor class="solr.UUIDUpdateProcessorFactory" />
+
     <processor class="solr.LogUpdateProcessorFactory"/>
     <processor class="solr.DistributedUpdateProcessorFactory"/>
     <processor class="solr.RemoveBlankFieldUpdateProcessorFactory"/>