You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by no...@apache.org on 2014/10/16 11:41:44 UTC

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

Author: noble
Date: Thu Oct 16 09:41:43 2014
New Revision: 1632259

URL: http://svn.apache.org/r1632259
Log:
SOLR-6307

Modified:
    lucene/dev/trunk/solr/CHANGES.txt
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/FieldType.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/TrieDateField.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/TrieFloatField.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/TrieIntField.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java
    lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/schema.xml
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/processor/AtomicUpdatesTest.java

Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=1632259&r1=1632258&r2=1632259&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Thu Oct 16 09:41:43 2014
@@ -167,11 +167,12 @@ New Features
 * SOLR-6585: RequestHandlers can optionaly handle sub paths as well (Noble Paul)
 
 * SOLR-6617: /update/json/docs path will use fully qualified node names by default
-             (NOble Paul)
+             (Noble Paul)
 
 * SOLR-4715: Add CloudSolrServer constructors which accept a HttpClient instance.
   (Hardik Upadhyay, Shawn Heisey, shalin)
 
+
 Bug Fixes
 ----------------------
 
@@ -233,6 +234,9 @@ Bug Fixes
 
 * SOLR-6624 Spelling mistakes in the Java source (Hrishikesh Gadre)
 
+* SOLR-6307: Atomic update remove does not work for int array or date array
+  (Anurag Sharma , noble)
+
 Optimizations
 ----------------------
 

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/FieldType.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/FieldType.java?rev=1632259&r1=1632258&r2=1632259&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/FieldType.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/FieldType.java Thu Oct 16 09:41:43 2014
@@ -965,6 +965,12 @@ public abstract class FieldType extends 
     }
     return analyzerProps;
   }
+
+  /**Converts any Object to a java Object native to this field type
+   */
+  public Object toNativeType(Object val) {
+    return val;
+  }
   
   /** 
    * Convert a value used by the FieldComparator for this FieldType's SortField

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/TrieDateField.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/TrieDateField.java?rev=1632259&r1=1632258&r2=1632259&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/TrieDateField.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/TrieDateField.java Thu Oct 16 09:41:43 2014
@@ -344,4 +344,14 @@ public class TrieDateField extends TrieF
               max == null ? null : max.getTime(),
               minInclusive, maxInclusive);
   }
+
+  @Override
+  public Object toNativeType(Object val) {
+    if(val==null) return null;
+    if (val instanceof Date) return  val;
+
+    if (val instanceof String) return parseMath(null,(String)val);
+
+    return super.toNativeType(val);
+  }
 }

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/TrieFloatField.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/TrieFloatField.java?rev=1632259&r1=1632258&r2=1632259&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/TrieFloatField.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/TrieFloatField.java Thu Oct 16 09:41:43 2014
@@ -37,4 +37,12 @@ public class TrieFloatField extends Trie
   {
     type=TrieTypes.FLOAT;
   }
+
+  @Override
+  public Object toNativeType(Object val) {
+    if(val==null) return null;
+    if (val instanceof Number) return ((Number) val).floatValue();
+    if (val instanceof String) return Float.parseFloat((String) val);
+    return super.toNativeType(val);
+  }
 }

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/TrieIntField.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/TrieIntField.java?rev=1632259&r1=1632258&r2=1632259&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/TrieIntField.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/TrieIntField.java Thu Oct 16 09:41:43 2014
@@ -31,4 +31,17 @@ public class TrieIntField extends TrieFi
   {
     type=TrieTypes.INTEGER;
   }
+
+  @Override
+  public Object toNativeType(Object val) {
+    if(val==null) return null;
+    if (val instanceof Number) return ((Number) val).intValue();
+    try {
+      if (val instanceof String) return Integer.parseInt((String) val);
+    } catch (NumberFormatException e) {
+      Float v = Float.parseFloat((String) val);
+      return v.intValue();
+    }
+    return super.toNativeType(val);
+  }
 }

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java?rev=1632259&r1=1632258&r2=1632259&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java Thu Oct 16 09:41:43 2014
@@ -37,7 +37,6 @@ import java.util.concurrent.locks.Reentr
 
 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;
@@ -75,6 +74,7 @@ import org.apache.solr.request.SolrReque
 import org.apache.solr.response.SolrQueryResponse;
 import org.apache.solr.schema.IndexSchema;
 import org.apache.solr.schema.SchemaField;
+import org.apache.solr.schema.TrieDateField;
 import org.apache.solr.update.AddUpdateCommand;
 import org.apache.solr.update.CommitUpdateCommand;
 import org.apache.solr.update.DeleteUpdateCommand;
@@ -1144,7 +1144,7 @@ public class DistributedUpdateProcessor 
               break;
             case "remove":
               updateField = true;
-              doRemove(oldDoc, sif, fieldVal);
+              doRemove(oldDoc, sif, fieldVal, schema);
               break;
             case "inc":
               updateField = true;
@@ -1200,21 +1200,29 @@ public class DistributedUpdateProcessor 
       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) {
+    if(existingField == null) return false;
+    SchemaField sf = schema.getField(name);
+    int oldSize = existingField.getValueCount();
+
+    if (sf != null) {
       final Collection<Object> original = existingField.getValues();
       if (fieldVal instanceof Collection) {
-        original.removeAll((Collection) fieldVal);
+        for (Object object : (Collection)fieldVal){
+          original.remove(sf.getType().toNativeType(object));
+        }
       } else {
-        original.remove(fieldVal);
+        original.remove(sf.getType().toNativeType(fieldVal));
       }
 
       oldDoc.setField(name, original);
 
     }
+    
+    return oldSize > existingField.getValueCount();
   }
 
 

Modified: lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/schema.xml
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/schema.xml?rev=1632259&r1=1632258&r2=1632259&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/schema.xml (original)
+++ lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/schema.xml Thu Oct 16 09:41:43 2014
@@ -518,6 +518,9 @@
    <field name="timestamp" type="date" indexed="true" stored="true" docValues="true" default="NOW" multiValued="false"/>
    <field name="multiDefault" type="string" indexed="true" stored="true" default="muLti-Default" multiValued="true"/>
    <field name="intDefault" type="int" indexed="true" stored="true" default="42" multiValued="false"/>
+   <field name="intRemove" type="int" indexed="true" stored="true" multiValued="true"/>
+   <field name="dateRemove" type="date" indexed="true" stored="true" multiValued="true"/>
+   <field name="floatRemove" type="float" indexed="true" stored="true" multiValued="true"/>
 
    <field name="nopositionstext" type="nopositions" indexed="true" stored="true"/>
 

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/processor/AtomicUpdatesTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/processor/AtomicUpdatesTest.java?rev=1632259&r1=1632258&r2=1632259&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/processor/AtomicUpdatesTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/processor/AtomicUpdatesTest.java Thu Oct 16 09:41:43 2014
@@ -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 @@ public class AtomicUpdatesTest extends S
   }
 
   @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<Long> removeList = new ArrayList<Long>();
+    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<Long>();
+    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<Long> removeList = new ArrayList<Long>();
+    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<Long>();
+    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<String> removeList = new ArrayList<String>();
+    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<String>();
+    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<Long> removeList = new ArrayList<Long>();
+    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<Long>();
+    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<Float> removeList = new ArrayList<Float>();
+    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<Float>();
+    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<Double> removeList = new ArrayList<Double>();
+    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<Double>();
+    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<String> removeList = new ArrayList<String>();
+    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<String>();
+    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<Date> removeList = new ArrayList<Date>();
+    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<Date>();
+    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<Float> removeList = new ArrayList<Float>();
+    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<Float>();
+    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<String> removeList = new ArrayList<String>();
+    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<String>();
+    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");