Index: core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java =================================================================== --- core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java (revision 1631811) +++ core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java (working copy) @@ -37,7 +37,6 @@ import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRefBuilder; -import org.apache.lucene.util.CharsRef; import org.apache.lucene.util.CharsRefBuilder; import org.apache.solr.client.solrj.request.UpdateRequest; import org.apache.solr.cloud.CloudDescriptor; @@ -73,8 +72,12 @@ import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.request.SolrRequestInfo; import org.apache.solr.response.SolrQueryResponse; +import org.apache.solr.schema.FieldType; import org.apache.solr.schema.IndexSchema; import org.apache.solr.schema.SchemaField; +import org.apache.solr.schema.TrieDateField; +import org.apache.solr.schema.TrieFloatField; +import org.apache.solr.schema.TrieIntField; import org.apache.solr.update.AddUpdateCommand; import org.apache.solr.update.CommitUpdateCommand; import org.apache.solr.update.DeleteUpdateCommand; @@ -1144,7 +1147,7 @@ break; case "remove": updateField = true; - doRemove(oldDoc, sif, fieldVal); + doRemove(oldDoc, sif, fieldVal, schema); break; case "inc": updateField = true; @@ -1200,24 +1203,119 @@ oldDoc.setField(sif.getName(), result, sif.getBoost()); } } - - private void doRemove(SolrInputDocument oldDoc, SolrInputField sif, Object fieldVal) { + + private boolean doRemove(SolrInputDocument oldDoc, SolrInputField sif, Object fieldVal, IndexSchema schema) { final String name = sif.getName(); SolrInputField existingField = oldDoc.get(name); - if (existingField != null) { + SchemaField sf = schema.getField(name); + int oldSize = existingField.getValueCount(); + + if (existingField != null && sf != null) { final Collection original = existingField.getValues(); - if (fieldVal instanceof Collection) { - original.removeAll((Collection) fieldVal); - } else { - original.remove(fieldVal); + FieldType oldFieldType = sf.getType(); + if (oldFieldType instanceof TrieIntField){ + if (fieldVal instanceof Collection) { + for (Object object : (Collection)fieldVal){ + removeInt(original, object); + } + } else { + removeInt(original, fieldVal); + } } - + else if (oldFieldType instanceof TrieDateField){ + if (fieldVal instanceof Collection) { + for (Object object : (Collection)fieldVal){ + removeDate(original, object); + } + } else { + removeDate(original, fieldVal); + } + } + else if (oldFieldType instanceof TrieFloatField){ //JsonLoader gives only Double and Solr support float as well, + if (fieldVal instanceof Collection) { + for (Object object : (Collection)fieldVal){ + removeFloat(original, object); + } + } else { + removeFloat(original, fieldVal); + } + } + else{ + if (fieldVal instanceof Collection) { + original.removeAll((Collection) fieldVal); + } else { + original.remove(fieldVal); + } + } oldDoc.setField(name, original); - } + + return oldSize > existingField.getValueCount(); } - - + + + private boolean removeInt(Collection original, Object object){ + boolean removed = false; + if (object instanceof Long){ + removed = original.remove(((Long)object).intValue()); + } + else if (object instanceof Double){ + removed = original.remove(((Double)object).intValue()); + } + else if (object instanceof String){ + boolean nonIntegerFormat = false; + try{ + removed = original.remove(Integer.parseInt(object.toString())); + }catch(NumberFormatException e){ //log exception when "string" contains invalid integer + nonIntegerFormat = true; + if (log.isDebugEnabled()) + log.debug("removeInt(original:["+original.toString() + "], object:[" + object.toString()+"])\n" + + e.getMessage()); + } + // when Double value passed as a String + if(!removed && nonIntegerFormat) + removed = original.remove((new Double(Double.parseDouble(object.toString()))).intValue()); + // when Float value passed as a String + if(!removed && nonIntegerFormat) + removed = original.remove(new Float(Float.parseFloat(object.toString())).intValue()); + } + return removed; + } + + private boolean removeDate(Collection original, Object object){ + boolean removed = false; + if (object instanceof String){ + try{ + removed = original.remove((new TrieDateField()).parseMath(null, object.toString())); + }catch (SolrException e){ //log exception for invalid string not converted to UTC date + if (log.isDebugEnabled()) + log.debug("removeDate(original:["+original.toString() + "], object:[" + object.toString()+"])\n" + + e.getMessage()); + } + } + return removed; + } + + private boolean removeFloat(Collection original, Object object){ + boolean removed = false; + if (object instanceof Long){ + removed = original.remove(((Long)object).floatValue()); + } + else if (object instanceof Double){ + removed = original.remove(((Double)object).floatValue()); + } + else if (object instanceof String){ + try{ + removed = original.remove(Float.parseFloat((String)object)); + }catch(NumberFormatException e){ // log exception for invalid float string + if (log.isDebugEnabled()) + log.debug("removeFloat(original:["+original.toString() + "], object:[" + object.toString()+"])\n" + + e.getMessage()); + } + } + return removed; + } + @Override public void processDelete(DeleteUpdateCommand cmd) throws IOException { updateCommand = cmd; Index: core/src/test/org/apache/solr/update/processor/AtomicUpdatesTest.java =================================================================== --- core/src/test/org/apache/solr/update/processor/AtomicUpdatesTest.java (revision 1631811) +++ core/src/test/org/apache/solr/update/processor/AtomicUpdatesTest.java (working copy) @@ -1,14 +1,18 @@ package org.apache.solr.update.processor; -import com.google.common.collect.ImmutableMap; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.schema.TrieDateField; import org.junit.Before; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; -import java.util.ArrayList; -import java.util.List; +import com.google.common.collect.ImmutableMap; /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -108,6 +112,710 @@ } @Test + public void testRemoveInteger() throws Exception { + SolrInputDocument doc; + + doc = new SolrInputDocument(); + doc.setField("id", "1001"); + doc.setField("intRemove", new String[]{"111", "222", "333", "333", "444"}); + + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "1002"); + doc.setField("intRemove", new String[]{"111", "222", "222", "333", "444"}); + assertU(adoc(doc)); + + + doc = new SolrInputDocument(); + doc.setField("id", "1020"); + doc.setField("intRemove", new String[]{"111", "333", "444"}); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "1021"); + doc.setField("intRemove", new String[]{"111", "222", "444"}); + assertU(adoc(doc)); + + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:222", "indent", "true"), "//result[@numFound = '3']"); + + + doc = new SolrInputDocument(); + doc.setField("id", "1001"); + List removeList = new ArrayList(); + removeList.add(new Long(222)); + removeList.add(new Long(333)); + doc.setField("intRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:222", "indent", "true"), "//result[@numFound = '2']"); + + doc = new SolrInputDocument(); + doc.setField("id", "1021"); + removeList = new ArrayList(); + removeList.add(new Long(222)); + removeList.add(new Long(333)); + doc.setField("intRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:222", "indent", "true"), "//result[@numFound = '1']"); + + doc = new SolrInputDocument(); + doc.setField("id", "1001"); + doc.setField("intRemove", ImmutableMap.of("remove", 111)); //behavior when hitting Solr directly + + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:111", "indent", "true"), "//result[@numFound = '3']"); + } + + + @Test + public void testRemoveIntegerInDocSavedWithInteger() throws Exception { + SolrInputDocument doc; + + doc = new SolrInputDocument(); + doc.setField("id", "1001"); + doc.setField("intRemove", new Integer[]{111, 222, 333, 333, 444}); + + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "1002"); + doc.setField("intRemove", new Integer[]{111, 222, 222, 333, 444}); + assertU(adoc(doc)); + + + doc = new SolrInputDocument(); + doc.setField("id", "1020"); + doc.setField("intRemove", new Integer[]{111, 333, 444}); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "1021"); + doc.setField("intRemove", new Integer[]{111, 222, 444}); + assertU(adoc(doc)); + + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:222", "indent", "true"), "//result[@numFound = '3']"); + + + doc = new SolrInputDocument(); + doc.setField("id", "1001"); + List removeList = new ArrayList(); + removeList.add(new Long(222)); + removeList.add(new Long(333)); + doc.setField("intRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:222", "indent", "true"), "//result[@numFound = '2']"); + + doc = new SolrInputDocument(); + doc.setField("id", "1021"); + removeList = new ArrayList(); + removeList.add(new Long(222)); + removeList.add(new Long(333)); + doc.setField("intRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:222", "indent", "true"), "//result[@numFound = '1']"); + + doc = new SolrInputDocument(); + doc.setField("id", "1001"); + doc.setField("intRemove", ImmutableMap.of("remove", 111)); //behavior when hitting Solr directly + + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:111", "indent", "true"), "//result[@numFound = '3']"); + } + + @Test + public void testRemoveIntegerUsingStringType() throws Exception { + SolrInputDocument doc; + + doc = new SolrInputDocument(); + doc.setField("id", "1001"); + doc.setField("intRemove", new String[]{"111", "222", "333", "333", "444"}); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "1002"); + doc.setField("intRemove", new String[]{"111", "222", "222", "333", "444"}); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "1020"); + doc.setField("intRemove", new String[]{"111", "333", "444"}); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "1021"); + doc.setField("intRemove", new String[]{"111", "222", "444"}); + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:222", "indent", "true"), "//result[@numFound = '3']"); + + + doc = new SolrInputDocument(); + doc.setField("id", "1001"); + List removeList = new ArrayList(); + removeList.add("222"); + removeList.add("333"); + doc.setField("intRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:222", "indent", "true"), "//result[@numFound = '2']"); + + doc = new SolrInputDocument(); + doc.setField("id", "1021"); + removeList = new ArrayList(); + removeList.add("222"); + removeList.add("333"); + doc.setField("intRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:222", "indent", "true"), "//result[@numFound = '1']"); + + doc = new SolrInputDocument(); + doc.setField("id", "1001"); + doc.setField("intRemove", ImmutableMap.of("remove", "111")); //behavior when hitting Solr directly + + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:111", "indent", "true"), "//result[@numFound = '3']"); + } + + @Test + public void testRemoveIntegerUsingLongType() throws Exception { + SolrInputDocument doc; + + doc = new SolrInputDocument(); + doc.setField("id", "1001"); + doc.setField("intRemove", new Long[]{111L, 222L, 333L, 333L, 444L}); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "1002"); + doc.setField("intRemove", new Long[]{111L, 222L, 222L, 333L, 444L}); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "1020"); + doc.setField("intRemove", new Long[]{111L, 333L, 444L}); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "1021"); + doc.setField("intRemove", new Long[]{111L, 222L, 444L}); + assertU(adoc(doc)); + + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:222", "indent", "true"), "//result[@numFound = '3']"); + + doc = new SolrInputDocument(); + doc.setField("id", "1001"); + List removeList = new ArrayList(); + removeList.add(222L); + removeList.add(333L); + doc.setField("intRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:222", "indent", "true"), "//result[@numFound = '2']"); + + doc = new SolrInputDocument(); + doc.setField("id", "1021"); + removeList = new ArrayList(); + removeList.add(222L); + removeList.add(333L); + doc.setField("intRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:222", "indent", "true"), "//result[@numFound = '1']"); + + doc = new SolrInputDocument(); + doc.setField("id", "1001"); + doc.setField("intRemove", ImmutableMap.of("remove", 111L)); //behavior when hitting Solr directly + + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:111", "indent", "true"), "//result[@numFound = '3']"); + } + + + @Test + public void testRemoveIntegerUsingFloatType() throws Exception { + SolrInputDocument doc; + + doc = new SolrInputDocument(); +// add with float in integer field +// doc.setField("id", "1001"); +// doc.setField("intRemove", new Float[]{111.10F, 222.20F, 333.30F, 333.30F, 444.40F}); +// assertU(adoc(doc)); +// +// doc = new SolrInputDocument(); +// doc.setField("id", "1002"); +// doc.setField("intRemove", new Float[]{111.10F, 222.20F, 222.20F, 333.30F, 444.40F}); +// assertU(adoc(doc)); +// +// doc = new SolrInputDocument(); +// doc.setField("id", "1020"); +// doc.setField("intRemove", new Float[]{111.10F, 333.30F, 444.40F}); +// assertU(adoc(doc)); +// +// doc = new SolrInputDocument(); +// doc.setField("id", "1021"); +// doc.setField("intRemove", new Float[]{111.10F, 222.20F, 444.40F}); + + doc.setField("id", "1001"); + doc.setField("intRemove", new String[]{"111", "222", "333", "333", "444"}); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "1002"); + doc.setField("intRemove", new String[]{"111", "222", "222", "333", "444"}); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "1020"); + doc.setField("intRemove", new String[]{"111", "333", "444"}); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "1021"); + doc.setField("intRemove", new String[]{"111", "222", "444"}); + assertU(adoc(doc)); + + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:222", "indent", "true"), "//result[@numFound = '3']"); + + + doc = new SolrInputDocument(); + doc.setField("id", "1001"); + List removeList = new ArrayList(); + removeList.add(222.20F); + removeList.add(333.30F); + doc.setField("intRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:222", "indent", "true"), "//result[@numFound = '2']"); + + doc = new SolrInputDocument(); + doc.setField("id", "1021"); + removeList = new ArrayList(); + removeList.add(222.20F); + removeList.add(333.30F); + doc.setField("intRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:222", "indent", "true"), "//result[@numFound = '1']"); + + doc = new SolrInputDocument(); + doc.setField("id", "1001"); + doc.setField("intRemove", ImmutableMap.of("remove", 111L)); //behavior when hitting Solr directly + + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:111", "indent", "true"), "//result[@numFound = '3']"); + } + + + @Test + public void testRemoveIntegerUsingDoubleType() throws Exception { + SolrInputDocument doc; + + doc = new SolrInputDocument(); + doc.setField("id", "1001"); + doc.setField("intRemove", new String[]{"11111111", "22222222", "33333333", "33333333", "44444444"}); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "1002"); + doc.setField("intRemove", new String[]{"11111111", "22222222", "22222222", "33333333", "44444444"}); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "1020"); + doc.setField("intRemove", new String[]{"11111111", "33333333", "44444444"}); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "1021"); + doc.setField("intRemove", new String[]{"11111111", "22222222", "44444444"}); + assertU(adoc(doc)); + + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:22222222", "indent", "true"), "//result[@numFound = '3']"); + + + doc = new SolrInputDocument(); + doc.setField("id", "1001"); + List removeList = new ArrayList(); + removeList.add(22222222D); + removeList.add(33333333D); + doc.setField("intRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:22222222", "indent", "true"), "//result[@numFound = '2']"); + + doc = new SolrInputDocument(); + doc.setField("id", "1021"); + removeList = new ArrayList(); + removeList.add(22222222D); + removeList.add(33333333D); + doc.setField("intRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:22222222", "indent", "true"), "//result[@numFound = '1']"); + + doc = new SolrInputDocument(); + doc.setField("id", "1001"); + doc.setField("intRemove", ImmutableMap.of("remove", 11111111D)); //behavior when hitting Solr directly + + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "intRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "intRemove:11111111", "indent", "true"), "//result[@numFound = '3']"); + } + + @Test + public void testRemoveDateUsingStringType() throws Exception { + SolrInputDocument doc; + + doc = new SolrInputDocument(); + doc.setField("id", "10001"); + doc.setField("dateRemove", new String[]{"2014-09-01T12:00:00Z", "2014-09-02T12:00:00Z", "2014-09-03T12:00:00Z", "2014-09-03T12:00:00Z", "2014-09-04T12:00:00Z"}); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "10002"); + doc.setField("dateRemove", new String[]{"2014-09-01T12:00:00Z", "2014-09-02T12:00:00Z", "2014-09-02T12:00:00Z", "2014-09-03T12:00:00Z", "2014-09-04T12:00:00Z"}); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "10020"); + doc.setField("dateRemove", new String[]{"2014-09-01T12:00:00Z", "2014-09-03T12:00:00Z", "2014-09-04T12:00:00Z"}); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "10021"); + doc.setField("dateRemove", new String[]{"2014-09-01T12:00:00Z", "2014-09-02T12:00:00Z", "2014-09-04T12:00:00Z"}); + assertU(adoc(doc)); + + assertU(commit()); + + assertQ(req("q", "dateRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "dateRemove:\"2014-09-02T12:00:00Z\"", "indent", "true"), "//result[@numFound = '3']"); + + doc = new SolrInputDocument(); + doc.setField("id", "10001"); + List removeList = new ArrayList(); + removeList.add("2014-09-02T12:00:00Z"); + removeList.add("2014-09-03T12:00:00Z"); + + doc.setField("dateRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "dateRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "dateRemove:\"2014-09-02T12:00:00Z\"", "indent", "true"), "//result[@numFound = '2']"); + + doc = new SolrInputDocument(); + doc.setField("id", "10021"); + removeList = new ArrayList(); + removeList.add("2014-09-02T12:00:00Z"); + removeList.add("2014-09-03T12:00:00Z"); + doc.setField("dateRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "dateRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "dateRemove:\"2014-09-02T12:00:00Z\"", "indent", "true"), "//result[@numFound = '1']"); + + doc = new SolrInputDocument(); + doc.setField("id", "10001"); + doc.setField("dateRemove", ImmutableMap.of("remove", "2014-09-01T12:00:00Z")); //behavior when hitting Solr directly + + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "dateRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "dateRemove:\"2014-09-01T12:00:00Z\"", "indent", "true"), "//result[@numFound = '3']"); + } + + @Ignore("Remove Date is not supported in other formats than UTC") + @Test + public void testRemoveDateUsingDateType() throws Exception { + SolrInputDocument doc; + + doc = new SolrInputDocument(); + doc.setField("id", "10001"); + TrieDateField trieDF = new TrieDateField(); + Date tempDate = trieDF.parseMath(null, "2014-02-01T12:00:00Z"); + doc.setField("dateRemove", new Date[]{trieDF.parseMath(null, "2014-02-01T12:00:00Z"), + trieDF.parseMath(null, "2014-07-02T12:00:00Z"), + trieDF.parseMath(null, "2014-02-03T12:00:00Z"), + trieDF.parseMath(null, "2014-02-03T12:00:00Z"), + trieDF.parseMath(null, "2014-02-04T12:00:00Z") + }); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "10002"); + doc.setField("dateRemove", new Date[]{trieDF.parseMath(null, "2014-02-01T12:00:00Z"), + trieDF.parseMath(null, "2014-07-02T12:00:00Z"), + trieDF.parseMath(null, "2014-02-02T12:00:00Z"), + trieDF.parseMath(null, "2014-02-03T12:00:00Z"), + trieDF.parseMath(null, "2014-02-04T12:00:00Z") + }); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "10020"); + doc.setField("dateRemove", new Date[]{trieDF.parseMath(null, "2014-02-01T12:00:00Z"), + trieDF.parseMath(null, "2014-02-03T12:00:00Z"), + trieDF.parseMath(null, "2014-02-04T12:00:00Z") + }); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "10021"); + doc.setField("dateRemove", new Date[]{trieDF.parseMath(null, "2014-02-01T12:00:00Z"), + trieDF.parseMath(null, "2014-02-02T12:00:00Z"), + trieDF.parseMath(null, "2014-02-04T12:00:00Z") + }); + assertU(adoc(doc)); + + assertU(commit()); + + assertQ(req("q", "dateRemove:*", "indent", "true"), "//result[@numFound = '4']"); + String dateString = trieDF.parseMath(null, "2014-02-02T12:00:00Z").toString(); +// assertQ(req("q", "dateRemove:"+URLEncoder.encode(dateString, "UTF-8"), "indent", "true"), "//result[@numFound = '3']"); +// assertQ(req("q", "dateRemove:\"2014-09-02T12:00:00Z\"", "indent", "true"), "//result[@numFound = '3']"); +// assertQ(req("q", "dateRemove:"+dateString, "indent", "true"), "//result[@numFound = '3']"); //Sun Feb 02 10:00:00 FNT 2014 + assertQ(req("q", "dateRemove:\"Sun Feb 02 10:00:00 FNT 2014\"", "indent", "true"), "//result[@numFound = '3']"); //Sun Feb 02 10:00:00 FNT 2014 + + + doc = new SolrInputDocument(); + doc.setField("id", "10001"); + List removeList = new ArrayList(); + removeList.add(trieDF.parseMath(null, "2014-09-02T12:00:00Z")); + removeList.add(trieDF.parseMath(null, "2014-09-03T12:00:00Z")); + + doc.setField("dateRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "dateRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "dateRemove:\"2014-09-02T12:00:00Z\"", "indent", "true"), "//result[@numFound = '2']"); + + doc = new SolrInputDocument(); + doc.setField("id", "10021"); + removeList = new ArrayList(); + removeList.add(trieDF.parseMath(null, "2014-09-02T12:00:00Z")); + removeList.add(trieDF.parseMath(null, "2014-09-03T12:00:00Z")); + doc.setField("dateRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "dateRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "dateRemove:\"2014-09-02T12:00:00Z\"", "indent", "true"), "//result[@numFound = '1']"); + + doc = new SolrInputDocument(); + doc.setField("id", "10001"); + doc.setField("dateRemove", ImmutableMap.of("remove", trieDF.parseMath(null, "2014-09-01T12:00:00Z"))); //behavior when hitting Solr directly + + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "dateRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "dateRemove:\"2014-09-01T12:00:00Z\"", "indent", "true"), "//result[@numFound = '3']"); + } + + @Test + public void testRemoveFloatUsingFloatType() throws Exception { + SolrInputDocument doc; + + doc = new SolrInputDocument(); + doc.setField("id", "10001"); + doc.setField("floatRemove", new Float[]{111.111F, 222.222F, 333.333F, 333.333F, 444.444F}); + + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "10002"); + doc.setField("floatRemove", new Float[]{111.111F, 222.222F, 222.222F, 333.333F, 444.444F}); + assertU(adoc(doc)); + + + doc = new SolrInputDocument(); + doc.setField("id", "10020"); + doc.setField("floatRemove", new Float[]{111.111F, 333.333F, 444.444F}); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "10021"); + doc.setField("floatRemove", new Float[]{111.111F, 222.222F, 444.444F}); + assertU(adoc(doc)); + + assertU(commit()); + + assertQ(req("q", "floatRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "floatRemove:\"222.222\"", "indent", "true"), "//result[@numFound = '3']"); + + + doc = new SolrInputDocument(); + doc.setField("id", "10001"); + List removeList = new ArrayList(); + removeList.add(222.222F); + removeList.add(333.333F); + + doc.setField("floatRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "floatRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "floatRemove:\"222.222\"", "indent", "true"), "//result[@numFound = '2']"); + + doc = new SolrInputDocument(); + doc.setField("id", "10021"); + removeList = new ArrayList(); + removeList.add(222.222F); + removeList.add(333.333F); + doc.setField("floatRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "floatRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "floatRemove:\"222.222\"", "indent", "true"), "//result[@numFound = '1']"); + + doc = new SolrInputDocument(); + doc.setField("id", "10001"); + doc.setField("floatRemove", ImmutableMap.of("remove", "111.111")); //behavior when hitting Solr directly + + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "floatRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "floatRemove:\"111.111\"", "indent", "true"), "//result[@numFound = '3']"); + } + + @Test + public void testRemoveFloatUsingStringType() throws Exception { + SolrInputDocument doc; + + doc = new SolrInputDocument(); + doc.setField("id", "10001"); + doc.setField("floatRemove", new String[]{"111.111", "222.222", "333.333", "333.333", "444.444"}); + + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "10002"); + doc.setField("floatRemove", new String[]{"111.111", "222.222", "222.222", "333.333", "444.444"}); + assertU(adoc(doc)); + + + doc = new SolrInputDocument(); + doc.setField("id", "10020"); + doc.setField("floatRemove", new String[]{"111.111", "333.333", "444.444"}); + assertU(adoc(doc)); + + doc = new SolrInputDocument(); + doc.setField("id", "10021"); + doc.setField("floatRemove", new String[]{"111.111", "222.222", "444.444"}); + assertU(adoc(doc)); + + assertU(commit()); + + assertQ(req("q", "floatRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "floatRemove:\"222.222\"", "indent", "true"), "//result[@numFound = '3']"); + + + doc = new SolrInputDocument(); + doc.setField("id", "10001"); + List removeList = new ArrayList(); + removeList.add("222.222"); + removeList.add("333.333"); + + doc.setField("floatRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "floatRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "floatRemove:\"222.222\"", "indent", "true"), "//result[@numFound = '2']"); + + doc = new SolrInputDocument(); + doc.setField("id", "10021"); + removeList = new ArrayList(); + removeList.add("222.222"); + removeList.add("333.333"); + doc.setField("floatRemove", ImmutableMap.of("remove", removeList)); //behavior when hitting Solr through ZK + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "floatRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "floatRemove:\"222.222\"", "indent", "true"), "//result[@numFound = '1']"); + + doc = new SolrInputDocument(); + doc.setField("id", "10001"); + doc.setField("floatRemove", ImmutableMap.of("remove", "111.111")); //behavior when hitting Solr directly + + assertU(adoc(doc)); + assertU(commit()); + + assertQ(req("q", "floatRemove:*", "indent", "true"), "//result[@numFound = '4']"); + assertQ(req("q", "floatRemove:\"111.111\"", "indent", "true"), "//result[@numFound = '3']"); + } + + @Test public void testAdd() throws Exception { SolrInputDocument doc = new SolrInputDocument(); doc.setField("id", "3"); Index: core/src/test-files/solr/collection1/conf/schema.xml =================================================================== --- core/src/test-files/solr/collection1/conf/schema.xml (revision 1631811) +++ core/src/test-files/solr/collection1/conf/schema.xml (working copy) @@ -518,6 +518,9 @@ + + +