Index: lucene/CHANGES.txt
===================================================================
--- lucene/CHANGES.txt	(revision 1535296)
+++ lucene/CHANGES.txt	(working copy)
@@ -120,6 +120,9 @@
 * LUCENE-5274: FastVectorHighlighter now supports highlighting against several
   indexed fields. (Nik Everett via Adrien Grand)
 
+* LUCENE-5304: SingletonSortedSetDocValues can now return the wrapped
+  SortedDocValues (Robert Muir, Adrien Grand)
+
 Bug Fixes
 
 * LUCENE-4998: Fixed a few places to pass IOContext.READONCE instead
Index: lucene/core/src/java/org/apache/lucene/index/SingletonSortedSetDocValues.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/index/SingletonSortedSetDocValues.java	(revision 1535293)
+++ lucene/core/src/java/org/apache/lucene/index/SingletonSortedSetDocValues.java	(working copy)
@@ -37,6 +37,11 @@
     assert NO_MORE_ORDS == -1; // this allows our nextOrd() to work for missing values without a check
   }
 
+  /** Return the wrapped {@link SortedDocValues} */
+  public SortedDocValues getSortedDocValues() {
+    return in;
+  }
+
   @Override
   public long nextOrd() {
     if (set) {
Index: solr/CHANGES.txt
===================================================================
--- solr/CHANGES.txt	(revision 1535293)
+++ solr/CHANGES.txt	(working copy)
@@ -141,6 +141,9 @@
 
 * SOLR-5370: Requests to recover when an update fails should be done in 
   background threads. (Mark Miller)
+
+* LUCENE-5300,LUCENE-5304: Specialized faceting for fields which are declared as
+  multi-valued in the schema but are actually single-valued. (Adrien Grand)
   
 Security
 ----------------------
Index: solr/core/src/java/org/apache/solr/request/DocValuesFacets.java
===================================================================
--- solr/core/src/java/org/apache/solr/request/DocValuesFacets.java	(revision 1535293)
+++ solr/core/src/java/org/apache/solr/request/DocValuesFacets.java	(working copy)
@@ -131,7 +131,13 @@
             if (sub == null) {
               sub = SortedSetDocValues.EMPTY;
             }
-            accumMulti(counts, startTermIndex, sub, disi, subIndex, ordinalMap);
+            if (sub instanceof SingletonSortedSetDocValues) {
+              // some codecs may optimize SORTED_SET storage for single-valued fields
+              final SortedDocValues values = ((SingletonSortedSetDocValues) sub).getSortedDocValues();
+              accumSingle(counts, startTermIndex, values, disi, subIndex, ordinalMap);
+            } else {
+              accumMulti(counts, startTermIndex, sub, disi, subIndex, ordinalMap);
+            }
           } else {
             SortedDocValues sub = leaf.reader().getSortedDocValues(fieldName);
             if (sub == null) {
Index: solr/core/src/test/org/apache/solr/TestRandomDVFaceting.java
===================================================================
--- solr/core/src/test/org/apache/solr/TestRandomDVFaceting.java	(revision 1535293)
+++ solr/core/src/test/org/apache/solr/TestRandomDVFaceting.java	(working copy)
@@ -66,6 +66,7 @@
     types.add(new FldType("small2_s",ZERO_ONE, new SVal('a',(char)('c'+indexSize/3),1,1)));
     types.add(new FldType("small2_ss",ZERO_TWO, new SVal('a',(char)('c'+indexSize/3),1,1)));
     types.add(new FldType("small3_ss",new IRange(0,25), new SVal('A','z',1,1)));
+    types.add(new FldType("small4_ss",ZERO_ONE, new SVal('a',(char)('c'+indexSize/3),1,1))); // to test specialization when a multi-valued field is actually single-valued
     types.add(new FldType("small_i",ZERO_ONE, new IRange(0,5+indexSize/3)));
     types.add(new FldType("small2_i",ZERO_ONE, new IRange(0,5+indexSize/3)));
     types.add(new FldType("small2_is",ZERO_TWO, new IRange(0,5+indexSize/3)));
