SOLR-8050: Partial update on document with multivalued date field fails to parse date and can also fail to remove dates in some cases.

This closes #202

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1709042 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Shalin Shekhar Mangar 2015-10-16 15:37:42 +00:00
parent d417229dce
commit 70ae2272df
7 changed files with 92 additions and 13 deletions

View File

@ -271,6 +271,9 @@ Bug Fixes
(Gregory Chanan)
* SOLR-8107: bin/solr -f should use exec to start the JVM (Martijn Koster via Timothy Potter)
* SOLR-8050: Partial update on document with multivalued date field fails to parse date and can
also fail to remove dates in some cases. (Burkhard Buelte, Luc Vanlerberghe, shalin)
Optimizations
----------------------

View File

@ -566,6 +566,11 @@ public class TrieField extends PrimitiveFieldType {
@Override
public String storedToIndexed(StorableField f) {
final BytesRefBuilder bytes = new BytesRefBuilder();
storedToIndexed(f, bytes);
return bytes.get().utf8ToString();
}
private void storedToIndexed(StorableField f, final BytesRefBuilder bytes) {
final Number val = f.numericValue();
if (val != null) {
switch (type) {
@ -620,7 +625,6 @@ public class TrieField extends PrimitiveFieldType {
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown type for trie field: " + f.name());
}
}
return bytes.get().utf8ToString();
}
@Override
@ -712,7 +716,7 @@ public class TrieField extends PrimitiveFieldType {
if (sf.multiValued()) {
BytesRefBuilder bytes = new BytesRefBuilder();
readableToIndexed(value.toString(), bytes);
storedToIndexed(field, bytes);
fields.add(new SortedSetDocValuesField(sf.getName(), bytes.get()));
} else {
final long bits;

View File

@ -124,11 +124,13 @@ public class AtomicUpdateDocumentMerger {
}
protected void doSet(SolrInputDocument toDoc, SolrInputField sif, Object fieldVal) {
toDoc.setField(sif.getName(), fieldVal, sif.getBoost());
SchemaField sf = schema.getField(sif.getName());
toDoc.setField(sif.getName(), sf.getType().toNativeType(fieldVal), sif.getBoost());
}
protected void doAdd(SolrInputDocument toDoc, SolrInputField sif, Object fieldVal) {
toDoc.addField(sif.getName(), fieldVal, sif.getBoost());
SchemaField sf = schema.getField(sif.getName());
toDoc.addField(sif.getName(), sf.getType().toNativeType(fieldVal), sif.getBoost());
}
protected void doInc(SolrInputDocument toDoc, SolrInputField sif, Object fieldVal) {
@ -159,18 +161,19 @@ public class AtomicUpdateDocumentMerger {
toDoc.setField(sif.getName(), result, sif.getBoost());
}
}
protected void doRemove(SolrInputDocument toDoc, SolrInputField sif, Object fieldVal) {
final String name = sif.getName();
SolrInputField existingField = toDoc.get(name);
if(existingField == null) return;
if (existingField == null) return;
SchemaField sf = schema.getField(name);
if (sf != null) {
final Collection<Object> original = existingField.getValues();
if (fieldVal instanceof Collection) {
for (Object object : (Collection)fieldVal){
original.remove(sf.getType().toNativeType(object));
for (Object object : (Collection) fieldVal) {
Object o = sf.getType().toNativeType(object);
original.remove(o);
}
} else {
original.remove(sf.getType().toNativeType(fieldVal));

View File

@ -83,7 +83,7 @@
-->
<fieldType name="date" class="solr.TrieDateField" precisionStep="0"/>
<fieldType name="tdate" class="solr.TrieDateField" precisionStep="6"/>
<fieldType name="tdatedv" class="solr.TrieDateField" precisionStep="6" docValues="true" multiValued="true"/>
<fieldType name="tdatedv" class="solr.TrieDateField" precisionStep="6" docValues="true"/>
<fieldType name="dateRange" class="solr.DateRangeField" />
<fieldType name="location_rpt" class="solr.SpatialRecursivePrefixTreeFieldType"
@ -608,8 +608,12 @@
<dynamicField name="*_tdt" type="tdate" indexed="true" stored="true"/>
<dynamicField name="*_tdt1" type="tdate" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_tdtdv" type="tdatedv" indexed="true" stored="true"/>
<dynamicField name="*_tdtdv1" type="tdatedv" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="*_drf" type="dateRange" indexed="true" stored="true"/>
<dynamicField name="*_tdts" type="tdate" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="*_tdtdvs" type="tdatedv" indexed="true" stored="true"/>
<dynamicField name="*_sI" type="string" indexed="true" stored="false"/>
<dynamicField name="*_sS" type="string" indexed="false" stored="true"/>
<dynamicField name="t_*" type="text" indexed="true" stored="true"/>

View File

@ -96,7 +96,7 @@ public class IndexSchemaTest extends SolrTestCaseJ4 {
// Test TrieDate fields. The following asserts are expecting a field type defined as:
String expectedDefinition = "<fieldtype name=\"tdatedv\" class=\"solr.TrieDateField\" " +
"precisionStep=\"6\" docValues=\"true\" multiValued=\"true\"/>";
FieldType tdatedv = schema.getFieldType("foo_tdtdv");
FieldType tdatedv = schema.getFieldType("foo_tdtdvs");
assertTrue("Expecting a field type defined as " + expectedDefinition,
tdatedv instanceof TrieDateField);
assertTrue("Expecting a field type defined as " + expectedDefinition,

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.google.common.collect.ImmutableMap;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.schema.TrieDateField;
@ -13,8 +14,6 @@ import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import com.google.common.collect.ImmutableMap;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@ -945,6 +944,72 @@ public class AtomicUpdatesTest extends SolrTestCaseJ4 {
assertQ(req("q", "cat:ccc", "indent", "true"), "//result[@numFound = '1']");
}
public void testAtomicUpdatesOnDateFields() throws Exception {
String[] dateFieldNames = {"simple_tdt1", "simple_tdts", "simple_tdtdv1", "simple_tdtdvs"};
SolrInputDocument doc = new SolrInputDocument();
doc.setField("id", "6");
// Even adding a single value here for the multiValue field causes the update later on to fail
doc.setField("simple_tdt1", "1986-01-01T00:00:00Z"); // single-valued
doc.setField("simple_tdts", new String[] {"1986-01-01T00:00:00Z"});
doc.setField("simple_tdtdv", "1986-01-01T00:00:00Z");
doc.setField("simple_tdtdvs", new String[] {"1986-01-01T00:00:00Z"});
// An independent field that we want to update later on
doc.setField("other_i", "42");
assertU(adoc(doc));
assertU(commit());
assertQ(req("q", "id:6"), "boolean(//result/doc/date[@name='simple_tdt1'])");
for (String dateFieldName : dateFieldNames) {
// none (this can fail with Invalid Date String exception)
doc = new SolrInputDocument();
doc.setField("id", "6");
doc.setField("other_i", ImmutableMap.of("set", "43")); // set the independent field to another value
assertU(adoc(doc));
if (dateFieldName.endsWith("s")) {
// add
doc = new SolrInputDocument();
doc.setField("id", "6");
doc.setField("other_i", ImmutableMap.of("set", "43")); // set the independent field to another value
doc.setField(dateFieldName, ImmutableMap.of("add", "1987-01-01T00:00:00Z"));
assertU(adoc(doc));
// remove
doc = new SolrInputDocument();
doc.setField("id", "6");
doc.setField("other_i", ImmutableMap.of("set", "43")); // set the independent field to another value
doc.setField(dateFieldName, ImmutableMap.of("remove", "1987-01-01T00:00:00Z"));
assertU(adoc(doc));
} else {
// set
doc = new SolrInputDocument();
doc.setField("id", "6");
doc.setField("other_i", ImmutableMap.of("set", "43")); // set the independent field to another value
doc.setField(dateFieldName, ImmutableMap.of("set", "1987-01-01T00:00:00Z"));
assertU(adoc(doc));
// unset
doc = new SolrInputDocument();
doc.setField("id", "6");
doc.setField("other_i", ImmutableMap.of("set", "43")); // set the independent field to another value
doc.setField(dateFieldName, map("set", null));
assertU(adoc(doc));
}
assertU(commit());
if (dateFieldName.endsWith("s")) {
assertQ(req("q", "id:6"), "//result/doc[count(arr[@name='" + dateFieldName + "'])=1]");
assertQ(req("q", "id:6"), "//result/doc/arr[@name='" + dateFieldName + "'][count(date)=1]");
} else {
assertQ(req("q", "id:6"), "//result/doc[count(date[@name='" + dateFieldName + "'])=0]");
}
}
}
@Test
public void testInvalidOperation() {
SolrInputDocument doc;

View File

@ -72,7 +72,7 @@ public class UpdateProcessorTestBase extends SolrTestCaseJ4 {
UpdateRequestProcessor processor = pc.createProcessor(req, rsp);
if (null != processor) {
// test chain might be empty or short circuted.
// test chain might be empty or short circuited.
processor.processAdd(cmd);
}