You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ho...@apache.org on 2014/09/04 20:31:35 UTC
svn commit: r1622525 - in /lucene/dev/branches/branch_4x: ./ dev-tools/
lucene/ lucene/analysis/
lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/
lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/std40/
lucene...
Author: hossman
Date: Thu Sep 4 18:31:33 2014
New Revision: 1622525
URL: http://svn.apache.org/r1622525
Log:
SOLR-6024: Fix StatsComponent when using docValues=true multiValued=true (merge r1622386, and DocValuesStats.java specific changes from r1594441, r1594445, r1595259, r1600688, r1602997)
Added:
lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/request/DocValuesStats.java (with props)
Modified:
lucene/dev/branches/branch_4x/ (props changed)
lucene/dev/branches/branch_4x/dev-tools/ (props changed)
lucene/dev/branches/branch_4x/lucene/ (props changed)
lucene/dev/branches/branch_4x/lucene/BUILD.txt (props changed)
lucene/dev/branches/branch_4x/lucene/CHANGES.txt (props changed)
lucene/dev/branches/branch_4x/lucene/JRE_VERSION_MIGRATION.txt (props changed)
lucene/dev/branches/branch_4x/lucene/LICENSE.txt (props changed)
lucene/dev/branches/branch_4x/lucene/MIGRATE.txt (props changed)
lucene/dev/branches/branch_4x/lucene/NOTICE.txt (props changed)
lucene/dev/branches/branch_4x/lucene/README.txt (props changed)
lucene/dev/branches/branch_4x/lucene/SYSTEM_REQUIREMENTS.txt (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/ (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/Lucene47WordDelimiterFilter.java (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/std40/ASCIITLD.jflex-macro (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/std40/SUPPLEMENTARY.jflex-macro (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/std40/StandardTokenizerImpl40.java (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/std40/StandardTokenizerImpl40.jflex (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/std40/UAX29URLEmailTokenizerImpl40.java (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/std40/UAX29URLEmailTokenizerImpl40.jflex (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/std40/package.html (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLucene47WordDelimiterFilter.java (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/icu/src/java/org/apache/lucene/collation/ICUCollationKeyFilterFactory.java (props changed)
lucene/dev/branches/branch_4x/lucene/benchmark/ (props changed)
lucene/dev/branches/branch_4x/lucene/build.xml (props changed)
lucene/dev/branches/branch_4x/lucene/classification/ (props changed)
lucene/dev/branches/branch_4x/lucene/classification/build.xml (props changed)
lucene/dev/branches/branch_4x/lucene/classification/ivy.xml (props changed)
lucene/dev/branches/branch_4x/lucene/classification/src/ (props changed)
lucene/dev/branches/branch_4x/lucene/codecs/ (props changed)
lucene/dev/branches/branch_4x/lucene/common-build.xml (props changed)
lucene/dev/branches/branch_4x/lucene/core/ (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions2.java (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/index/index.40.cfs.zip (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/index/index.40.nocfs.zip (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/index/index.40.optimized.cfs.zip (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/index/index.40.optimized.nocfs.zip (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/search/TestSort.java (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/search/TestSortDocValues.java (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/search/TestSortRandom.java (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/search/TestTotalHitCountCollector.java (props changed)
lucene/dev/branches/branch_4x/lucene/demo/ (props changed)
lucene/dev/branches/branch_4x/lucene/expressions/ (props changed)
lucene/dev/branches/branch_4x/lucene/facet/ (props changed)
lucene/dev/branches/branch_4x/lucene/grouping/ (props changed)
lucene/dev/branches/branch_4x/lucene/highlighter/ (props changed)
lucene/dev/branches/branch_4x/lucene/ivy-ignore-conflicts.properties (props changed)
lucene/dev/branches/branch_4x/lucene/ivy-settings.xml (props changed)
lucene/dev/branches/branch_4x/lucene/ivy-versions.properties (props changed)
lucene/dev/branches/branch_4x/lucene/join/ (props changed)
lucene/dev/branches/branch_4x/lucene/licenses/ (props changed)
lucene/dev/branches/branch_4x/lucene/memory/ (props changed)
lucene/dev/branches/branch_4x/lucene/misc/ (props changed)
lucene/dev/branches/branch_4x/lucene/module-build.xml (props changed)
lucene/dev/branches/branch_4x/lucene/queries/ (props changed)
lucene/dev/branches/branch_4x/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionQuerySort.java (props changed)
lucene/dev/branches/branch_4x/lucene/queryparser/ (props changed)
lucene/dev/branches/branch_4x/lucene/replicator/ (props changed)
lucene/dev/branches/branch_4x/lucene/sandbox/ (props changed)
lucene/dev/branches/branch_4x/lucene/site/ (props changed)
lucene/dev/branches/branch_4x/lucene/spatial/ (props changed)
lucene/dev/branches/branch_4x/lucene/spatial/src/java/org/apache/lucene/spatial/bbox/ (props changed)
lucene/dev/branches/branch_4x/lucene/spatial/src/java/org/apache/lucene/spatial/util/ShapeAreaValueSource.java (props changed)
lucene/dev/branches/branch_4x/lucene/spatial/src/test-files/data/simple-bbox.txt (props changed)
lucene/dev/branches/branch_4x/lucene/spatial/src/test-files/simple-Queries-BBox.txt (props changed)
lucene/dev/branches/branch_4x/lucene/spatial/src/test/org/apache/lucene/spatial/bbox/ (props changed)
lucene/dev/branches/branch_4x/lucene/suggest/ (props changed)
lucene/dev/branches/branch_4x/lucene/test-framework/ (props changed)
lucene/dev/branches/branch_4x/lucene/test-framework/src/java/org/apache/lucene/codecs/cranky/ (props changed)
lucene/dev/branches/branch_4x/lucene/tools/ (props changed)
lucene/dev/branches/branch_4x/lucene/version.properties (props changed)
lucene/dev/branches/branch_4x/solr/ (props changed)
lucene/dev/branches/branch_4x/solr/CHANGES.txt (contents, props changed)
lucene/dev/branches/branch_4x/solr/LICENSE.txt (props changed)
lucene/dev/branches/branch_4x/solr/NOTICE.txt (props changed)
lucene/dev/branches/branch_4x/solr/README.txt (props changed)
lucene/dev/branches/branch_4x/solr/SYSTEM_REQUIREMENTS.txt (props changed)
lucene/dev/branches/branch_4x/solr/bin/ (props changed)
lucene/dev/branches/branch_4x/solr/build.xml (props changed)
lucene/dev/branches/branch_4x/solr/cloud-dev/ (props changed)
lucene/dev/branches/branch_4x/solr/common-build.xml (props changed)
lucene/dev/branches/branch_4x/solr/contrib/ (props changed)
lucene/dev/branches/branch_4x/solr/core/ (props changed)
lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/component/StatsComponent.java
lucene/dev/branches/branch_4x/solr/core/src/test-files/solr/collection1/conf/schema11.xml
lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/core/TestConfig.java (props changed)
lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/handler/component/StatsComponentTest.java
lucene/dev/branches/branch_4x/solr/example/ (props changed)
lucene/dev/branches/branch_4x/solr/licenses/ (props changed)
lucene/dev/branches/branch_4x/solr/licenses/httpclient-LICENSE-ASL.txt (props changed)
lucene/dev/branches/branch_4x/solr/licenses/httpclient-NOTICE.txt (props changed)
lucene/dev/branches/branch_4x/solr/licenses/httpcore-LICENSE-ASL.txt (props changed)
lucene/dev/branches/branch_4x/solr/licenses/httpcore-NOTICE.txt (props changed)
lucene/dev/branches/branch_4x/solr/licenses/httpmime-LICENSE-ASL.txt (props changed)
lucene/dev/branches/branch_4x/solr/licenses/httpmime-NOTICE.txt (props changed)
lucene/dev/branches/branch_4x/solr/scripts/ (props changed)
lucene/dev/branches/branch_4x/solr/site/ (props changed)
lucene/dev/branches/branch_4x/solr/solrj/ (props changed)
lucene/dev/branches/branch_4x/solr/test-framework/ (props changed)
lucene/dev/branches/branch_4x/solr/webapp/ (props changed)
Modified: lucene/dev/branches/branch_4x/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/CHANGES.txt?rev=1622525&r1=1622524&r2=1622525&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/CHANGES.txt (original)
+++ lucene/dev/branches/branch_4x/solr/CHANGES.txt Thu Sep 4 18:31:33 2014
@@ -79,6 +79,9 @@ Bug Fixes
* SOLR-4406: Fix RawResponseWriter to respect 'base' writer
(Steve Davids, hossman)
+* SOLR-6024: Fix StatsComponent when using docValues="true" multiValued="true"
+ (Vitaliy Zhovtyuk & Tomas Fernandez-Lobbe via hossman)
+
Other Changes
---------------------
Modified: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/component/StatsComponent.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/component/StatsComponent.java?rev=1622525&r1=1622524&r2=1622525&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/component/StatsComponent.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/component/StatsComponent.java Thu Sep 4 18:31:33 2014
@@ -37,6 +37,7 @@ import org.apache.solr.common.params.Sta
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.common.util.StrUtils;
+import org.apache.solr.request.DocValuesStats;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.UnInvertedField;
import org.apache.solr.schema.FieldType;
@@ -312,11 +313,15 @@ class SimpleStats {
SchemaField sf = schema.getField(statsField);
FieldType ft = sf.getType();
NamedList<?> stv;
-
+
if (sf.multiValued() || ft.multiValuedFieldCache()) {
- //use UnInvertedField for multivalued fields
- UnInvertedField uif = UnInvertedField.getUnInvertedField(statsField, searcher);
- stv = uif.getStats(searcher, docs, calcDistinct, facets).getStatsValues();
+ if(sf.hasDocValues()) {
+ stv = DocValuesStats.getCounts(searcher, sf.getName(), docs, calcDistinct, facets).getStatsValues();
+ } else {
+ //use UnInvertedField for multivalued fields
+ UnInvertedField uif = UnInvertedField.getUnInvertedField(statsField, searcher);
+ stv = uif.getStats(searcher, docs, calcDistinct, facets).getStatsValues();
+ }
} else {
stv = getFieldCacheStats(statsField, calcDistinct, facets);
}
Added: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/request/DocValuesStats.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/request/DocValuesStats.java?rev=1622525&view=auto
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/request/DocValuesStats.java (added)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/request/DocValuesStats.java Thu Sep 4 18:31:33 2014
@@ -0,0 +1,200 @@
+package org.apache.solr.request;
+
+/*
+ * 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 java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.lucene.index.AtomicReaderContext;
+import org.apache.lucene.index.DocValues;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.index.MultiDocValues.MultiSortedDocValues;
+import org.apache.lucene.index.MultiDocValues.MultiSortedSetDocValues;
+import org.apache.lucene.index.MultiDocValues.OrdinalMap;
+import org.apache.lucene.index.SortedDocValues;
+import org.apache.lucene.index.SortedSetDocValues;
+import org.apache.lucene.search.DocIdSet;
+import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.Filter;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.TermRangeQuery;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.LongValues;
+import org.apache.solr.handler.component.FieldFacetStats;
+import org.apache.solr.handler.component.StatsValues;
+import org.apache.solr.handler.component.StatsValuesFactory;
+import org.apache.solr.schema.FieldType;
+import org.apache.solr.schema.SchemaField;
+import org.apache.solr.search.DocSet;
+import org.apache.solr.search.SolrIndexSearcher;
+
+/**
+ * Computes term stats for docvalues field (single or multivalued).
+ * <p>
+ * Instead of working on a top-level reader view (binary-search per docid),
+ * it collects per-segment, but maps ordinals to global ordinal space using
+ * MultiDocValues' OrdinalMap.
+ */
+public class DocValuesStats {
+ private DocValuesStats() {}
+
+ public static StatsValues getCounts(SolrIndexSearcher searcher, String fieldName, DocSet docs, boolean calcDistinct, String[] facet) throws IOException {
+ SchemaField schemaField = searcher.getSchema().getField(fieldName);
+ FieldType ft = schemaField.getType();
+ StatsValues res = StatsValuesFactory.createStatsValues(schemaField, calcDistinct);
+
+ //Initialize facetstats, if facets have been passed in
+ final FieldFacetStats[] facetStats = new FieldFacetStats[facet.length];
+ int upto = 0;
+ for (String facetField : facet) {
+ SchemaField facetSchemaField = searcher.getSchema().getField(facetField);
+ facetStats[upto++] = new FieldFacetStats(searcher, facetField, schemaField, facetSchemaField, calcDistinct);
+ }
+
+ // TODO: remove multiValuedFieldCache(), check dv type / uninversion type?
+ final boolean multiValued = schemaField.multiValued() || ft.multiValuedFieldCache();
+
+ SortedSetDocValues si; // for term lookups only
+ OrdinalMap ordinalMap = null; // for mapping per-segment ords to global ones
+ if (multiValued) {
+ si = searcher.getAtomicReader().getSortedSetDocValues(fieldName);
+ if (si instanceof MultiSortedSetDocValues) {
+ ordinalMap = ((MultiSortedSetDocValues)si).mapping;
+ }
+ } else {
+ SortedDocValues single = searcher.getAtomicReader().getSortedDocValues(fieldName);
+ si = single == null ? null : DocValues.singleton(single);
+ if (single instanceof MultiSortedDocValues) {
+ ordinalMap = ((MultiSortedDocValues)single).mapping;
+ }
+ }
+ if (si == null) {
+ si = DocValues.emptySortedSet();
+ }
+ if (si.getValueCount() >= Integer.MAX_VALUE) {
+ throw new UnsupportedOperationException("Currently this stats method is limited to " + Integer.MAX_VALUE + " unique terms");
+ }
+
+ DocSet missing = docs.andNot( searcher.getDocSet(new TermRangeQuery(fieldName, null, null, false, false)));
+
+ final int nTerms = (int) si.getValueCount();
+
+ // count collection array only needs to be as big as the number of terms we are
+ // going to collect counts for.
+ final int[] counts = new int[nTerms];
+
+ Filter filter = docs.getTopFilter();
+ List<AtomicReaderContext> leaves = searcher.getTopReaderContext().leaves();
+ for (int subIndex = 0; subIndex < leaves.size(); subIndex++) {
+ AtomicReaderContext leaf = leaves.get(subIndex);
+ DocIdSet dis = filter.getDocIdSet(leaf, null); // solr docsets already exclude any deleted docs
+ DocIdSetIterator disi = null;
+ if (dis != null) {
+ disi = dis.iterator();
+ }
+ if (disi != null) {
+ int docBase = leaf.docBase;
+ if (multiValued) {
+ SortedSetDocValues sub = leaf.reader().getSortedSetDocValues(fieldName);
+ if (sub == null) {
+ sub = DocValues.emptySortedSet();
+ }
+ final SortedDocValues singleton = DocValues.unwrapSingleton(sub);
+ if (singleton != null) {
+ // some codecs may optimize SORTED_SET storage for single-valued fields
+ accumSingle(counts, docBase, facetStats, singleton, disi, subIndex, ordinalMap);
+ } else {
+ accumMulti(counts, docBase, facetStats, sub, disi, subIndex, ordinalMap);
+ }
+ } else {
+ SortedDocValues sub = leaf.reader().getSortedDocValues(fieldName);
+ if (sub == null) {
+ sub = DocValues.emptySorted();
+ }
+ accumSingle(counts, docBase, facetStats, sub, disi, subIndex, ordinalMap);
+ }
+ }
+ }
+
+ // add results in index order
+ for (int ord = 0; ord < counts.length; ord++) {
+ int count = counts[ord];
+ if (count > 0) {
+ final BytesRef value = si.lookupOrd(ord);
+ res.accumulate(value, count);
+ for (FieldFacetStats f : facetStats) {
+ f.accumulateTermNum(ord, value);
+ }
+ }
+ }
+
+ res.addMissing(missing.size());
+ if (facetStats.length > 0) {
+ for (FieldFacetStats f : facetStats) {
+ Map<String, StatsValues> facetStatsValues = f.facetStatsValues;
+ FieldType facetType = searcher.getSchema().getFieldType(f.name);
+ for (Map.Entry<String,StatsValues> entry : facetStatsValues.entrySet()) {
+ String termLabel = entry.getKey();
+ int missingCount = searcher.numDocs(new TermQuery(new Term(f.name, facetType.toInternal(termLabel))), missing);
+ entry.getValue().addMissing(missingCount);
+ }
+ res.addFacet(f.name, facetStatsValues);
+ }
+ }
+ return res;
+ }
+
+ /** accumulates per-segment single-valued stats */
+ static void accumSingle(int counts[], int docBase, FieldFacetStats[] facetStats, SortedDocValues si, DocIdSetIterator disi, int subIndex, OrdinalMap map) throws IOException {
+ final LongValues ordMap = map == null ? null : map.getGlobalOrds(subIndex);
+ int doc;
+ while ((doc = disi.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
+ int term = si.getOrd(doc);
+ if (term >= 0) {
+ if (map != null) {
+ term = (int) ordMap.get(term);
+ }
+ counts[term]++;
+ for (FieldFacetStats f : facetStats) {
+ f.facetTermNum(docBase + doc, term);
+ }
+ }
+ }
+ }
+
+ /** accumulates per-segment multi-valued stats */
+ static void accumMulti(int counts[], int docBase, FieldFacetStats[] facetStats, SortedSetDocValues si, DocIdSetIterator disi, int subIndex, OrdinalMap map) throws IOException {
+ final LongValues ordMap = map == null ? null : map.getGlobalOrds(subIndex);
+ int doc;
+ while ((doc = disi.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
+ si.setDocument(doc);
+ long ord;
+ while ((ord = si.nextOrd()) != SortedSetDocValues.NO_MORE_ORDS) {
+ int term = (int) ord;
+ if (map != null) {
+ term = (int) ordMap.get(term);
+ }
+ counts[term]++;
+ for (FieldFacetStats f : facetStats) {
+ f.facetTermNum(docBase + doc, term);
+ }
+ }
+ }
+ }
+}
Modified: lucene/dev/branches/branch_4x/solr/core/src/test-files/solr/collection1/conf/schema11.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/test-files/solr/collection1/conf/schema11.xml?rev=1622525&r1=1622524&r2=1622525&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/test-files/solr/collection1/conf/schema11.xml (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/test-files/solr/collection1/conf/schema11.xml Thu Sep 4 18:31:33 2014
@@ -332,7 +332,10 @@ valued. -->
<field name="_version_" type="long" indexed="true" stored="true" multiValued="false" />
<field name="cat" type="string" indexed="true" stored="true" multiValued="true"/>
- <field name="cat_length" type="text_length" indexed="true" stored="true" multiValued="true"/>
+ <field name="cat_docValues" type="string" indexed="true" stored="true" docValues="true" multiValued="true" />
+ <field name="cat_intDocValues" type="tint" indexed="true" stored="true" docValues="true" multiValued="true" />
+ <field name="cat_floatDocValues" type="tfloat" indexed="true" stored="true" docValues="true" multiValued="true" />
+ <field name="cat_length" type="text_length" indexed="true" stored="true" multiValued="true"/>
<!-- Dynamic field definitions. If a field name is not found, dynamicFields
will be used if the name matches any of the patterns.
@@ -341,32 +344,52 @@ valued. -->
EXAMPLE: name="*_i" will match any field ending in _i (like myid_i, z_i)
Longer patterns will be matched first. if equal size patterns
both match, the first appearing in the schema will be used. -->
- <dynamicField name="*_s" type="string" indexed="true" stored="true"/>
- <dynamicField name="*_ss" type="string" indexed="true" stored="true" multiValued="true"/>
- <dynamicField name="*_sS" type="string" indexed="false" stored="true"/>
- <dynamicField name="*_ii" type="integer" indexed="true" stored="true" multiValued="true"/>
- <dynamicField name="*_i" type="sint" indexed="true" stored="true"/>
- <dynamicField name="*_is" type="sint" indexed="true" stored="true" multiValued="true"/>
- <dynamicField name="*_l" type="slong" indexed="true" stored="true"/>
- <dynamicField name="*_f" type="sfloat" indexed="true" stored="true"/>
- <dynamicField name="*_d" type="sdouble" indexed="true" stored="true"/>
-
+ <dynamicField name="*_s" type="string" indexed="true" stored="true"/>
+ <dynamicField name="*_ss" type="string" indexed="true" stored="true" multiValued="true"/>
+ <dynamicField name="*_sS" type="string" indexed="false" stored="true"/>
+ <dynamicField name="*_i" type="sint" indexed="true" stored="true"/>
+ <dynamicField name="*_is" type="sint" indexed="true" stored="true" multiValued="true"/>
+ <dynamicField name="*_ii" type="integer" indexed="true" stored="true" multiValued="true"/>
+ <dynamicField name="*_l" type="slong" indexed="true" stored="true"/>
+ <dynamicField name="*_f" type="sfloat" indexed="true" stored="true"/>
+ <dynamicField name="*_d" type="sdouble" indexed="true" stored="true"/>
+
<dynamicField name="*_pi" type="integer" indexed="true" stored="true"/>
<dynamicField name="*_pl" type="long" indexed="true" stored="true"/>
<dynamicField name="*_pf" type="float" indexed="true" stored="true"/>
<dynamicField name="*_pd" type="double" indexed="true" stored="true"/>
- <dynamicField name="*_ti" type="tint" indexed="true" stored="true"/>
- <dynamicField name="*_tl" type="tlong" indexed="true" stored="true"/>
- <dynamicField name="*_tf" type="tfloat" indexed="true" stored="true"/>
- <dynamicField name="*_td" type="tdouble" indexed="true" stored="true"/>
- <dynamicField name="*_tdt" type="tdate" indexed="true" stored="true"/>
-
- <dynamicField name="*_tis" type="tints" indexed="true" stored="true"/>
- <dynamicField name="*_tls" type="tlongs" indexed="true" stored="true"/>
- <dynamicField name="*_tfs" type="tfloats" indexed="true" stored="true"/>
- <dynamicField name="*_tds" type="tdoubles" indexed="true" stored="true"/>
- <dynamicField name="*_tdts" type="tdates" indexed="true" stored="true"/>
+ <dynamicField name="*_ti" type="tint" indexed="true" stored="true"/>
+ <dynamicField name="*_ti_dv" type="tint" indexed="true" stored="true" docValues="true"/>
+ <dynamicField name="*_ti_ni_dv" type="tint" indexed="true" stored="true" docValues="true"/>
+ <dynamicField name="*_tl" type="tlong" indexed="true" stored="true"/>
+ <dynamicField name="*_tl_dv" type="tlong" indexed="true" stored="true" docValues="true"/>
+ <dynamicField name="*_tl_ni_dv" type="tlong" indexed="false" stored="true" docValues="true"/>
+ <dynamicField name="*_tf" type="tfloat" indexed="true" stored="true"/>
+ <dynamicField name="*_tf_dv" type="tfloat" indexed="true" stored="true" docValues="true"/>
+ <dynamicField name="*_tf_ni_dv" type="tfloat" indexed="false" stored="true" docValues="true"/>
+ <dynamicField name="*_td" type="tdouble" indexed="true" stored="true"/>
+ <dynamicField name="*_td_dv" type="tdouble" indexed="true" stored="true" docValues="true"/>
+ <dynamicField name="*_td_ni_dv" type="tdouble" indexed="false" stored="true" docValues="true"/>
+ <dynamicField name="*_tdt" type="tdate" indexed="true" stored="true"/>
+ <dynamicField name="*_tdt_dv" type="tdate" indexed="true" stored="true" docValues="true"/>
+ <dynamicField name="*_tdt_ni_dv" type="tdate" indexed="false" stored="true" docValues="true"/>
+
+ <dynamicField name="*_tis" type="tints" indexed="true" stored="true"/>
+ <dynamicField name="*_tis_dv" type="tints" indexed="true" stored="true" docValues="true"/>
+ <dynamicField name="*_tis_ni_dv" type="tints" indexed="false" stored="true" docValues="true"/>
+ <dynamicField name="*_tls" type="tlongs" indexed="true" stored="true"/>
+ <dynamicField name="*_tls_dv" type="tlongs" indexed="true" stored="true" docValues="true"/>
+ <dynamicField name="*_tls_ni_dv" type="tlongs" indexed="false" stored="true" docValues="true"/>
+ <dynamicField name="*_tfs" type="tfloats" indexed="true" stored="true"/>
+ <dynamicField name="*_tfs_dv" type="tfloats" indexed="true" stored="true" docValues="true"/>
+ <dynamicField name="*_tfs_ni_dv" type="tfloats" indexed="false" stored="true" docValues="true"/>
+ <dynamicField name="*_tds" type="tdoubles" indexed="true" stored="true"/>
+ <dynamicField name="*_tds_dv" type="tdoubles" indexed="true" stored="true" docValues="true"/>
+ <dynamicField name="*_tds_ni_dv" type="tdoubles" indexed="false" stored="true" docValues="true"/>
+ <dynamicField name="*_tdts" type="tdates" indexed="true" stored="true"/>
+ <dynamicField name="*_tdts_dv" type="tdates" indexed="true" stored="true" docValues="true"/>
+ <dynamicField name="*_tdts_ni_dv" type="tdates" indexed="false" stored="true" docValues="true"/>
<dynamicField name="*_t" type="text" indexed="true" stored="true"/>
<dynamicField name="*_b" type="boolean" indexed="true" stored="true"/>
Modified: lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/handler/component/StatsComponentTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/handler/component/StatsComponentTest.java?rev=1622525&r1=1622524&r2=1622525&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/handler/component/StatsComponentTest.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/handler/component/StatsComponentTest.java Thu Sep 4 18:31:33 2014
@@ -18,12 +18,16 @@ package org.apache.solr.handler.componen
import java.text.DateFormat;
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
+import org.apache.lucene.util.LuceneTestCase;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.MapSolrParams;
import org.apache.solr.common.params.StatsParams;
@@ -38,6 +42,7 @@ import org.junit.BeforeClass;
/**
* Statistics Component Test
*/
+@LuceneTestCase.SuppressCodecs({"Lucene3x", "Lucene40", "Lucene41", "Lucene42"})
public class StatsComponentTest extends AbstractSolrTestCase {
@BeforeClass
@@ -49,25 +54,36 @@ public class StatsComponentTest extends
public void setUp() throws Exception {
super.setUp();
clearIndex();
+ assertU(commit());
lrf = h.getRequestFactory("standard", 0, 20);
}
public void testStats() throws Exception {
for (String f : new String[] {
"stats_i","stats_l","stats_f","stats_d",
- "stats_ti","stats_tl","stats_tf","stats_td"
+ "stats_ti","stats_tl","stats_tf","stats_td",
+ "stats_ti_dv","stats_tl_dv","stats_tf_dv","stats_td_dv"
+// , TODO: enable this test after SOLR-6452 is fixed
+// "stats_ti_ni_dv","stats_tl_ni_dv","stats_tf_ni_dv","stats_td_ni_dv"
}) {
doTestFieldStatisticsResult(f);
doTestFieldStatisticsMissingResult(f);
doTestFacetStatisticsResult(f);
doTestFacetStatisticsMissingResult(f);
+ clearIndex();
+ assertU(commit());
}
for (String f : new String[] {"stats_ii", // plain int
"stats_is", // sortable int
- "stats_tis","stats_tfs","stats_tls","stats_tds" // trie fields
+ "stats_tis","stats_tfs","stats_tls","stats_tds", // trie fields
+ "stats_tis_dv","stats_tfs_dv","stats_tls_dv","stats_tds_dv" // Doc Values
+// , TODO: enable this test after SOLR-6452 is fixed
+ //"stats_tis_ni_dv","stats_tfs_ni_dv","stats_tls_ni_dv","stats_tds_ni_dv" // Doc Values Not indexed
}) {
doTestMVFieldStatisticsResult(f);
+ clearIndex();
+ assertU(commit());
}
}
@@ -87,7 +103,7 @@ public class StatsComponentTest extends
, "//long[@name='count'][.='4']"
, "//long[@name='missing'][.='0']"
, "//long[@name='countDistinct'][.='4']"
- , "count(//arr[@name='distinctValues']/*)='4'"
+ , "count(//arr[@name='distinctValues']/*)=4"
, "//double[@name='sumOfSquares'][.='3000.0']"
, "//double[@name='mean'][.='-25.0']"
, "//double[@name='stddev'][.='12.909944487358056']"
@@ -98,6 +114,7 @@ public class StatsComponentTest extends
public void doTestMVFieldStatisticsResult(String f) throws Exception {
assertU(adoc("id", "1", f, "-10", f, "-100", "active_s", "true"));
assertU(adoc("id", "2", f, "-20", f, "200", "active_s", "true"));
+ assertU(commit());
assertU(adoc("id", "3", f, "-30", f, "-1", "active_s", "false"));
assertU(adoc("id", "4", f, "-40", f, "10", "active_s", "false"));
assertU(adoc("id", "5", "active_s", "false"));
@@ -110,7 +127,7 @@ public class StatsComponentTest extends
, "//long[@name='count'][.='8']"
, "//long[@name='missing'][.='1']"
, "//long[@name='countDistinct'][.='8']"
- , "count(//arr[@name='distinctValues']/*)='8'"
+ , "count(//arr[@name='distinctValues']/*)=8"
, "//double[@name='sumOfSquares'][.='53101.0']"
, "//double[@name='mean'][.='1.125']"
, "//double[@name='stddev'][.='87.08852228787508']"
@@ -123,7 +140,7 @@ public class StatsComponentTest extends
, "//long[@name='count'][.='8']"
, "//long[@name='missing'][.='1']"
, "//long[@name='countDistinct'][.='8']"
- , "count(//lst[@name='" + f + "']/arr[@name='distinctValues']/*)='8'"
+ , "count(//lst[@name='" + f + "']/arr[@name='distinctValues']/*)=8"
, "//double[@name='sumOfSquares'][.='53101.0']"
, "//double[@name='mean'][.='1.125']"
, "//double[@name='stddev'][.='87.08852228787508']"
@@ -136,7 +153,7 @@ public class StatsComponentTest extends
, "//lst[@name='true']/long[@name='count'][.='4']"
, "//lst[@name='true']/long[@name='missing'][.='0']"
, "//lst[@name='true']//long[@name='countDistinct'][.='4']"
- , "count(//lst[@name='true']/arr[@name='distinctValues']/*)='4'"
+ , "count(//lst[@name='true']/arr[@name='distinctValues']/*)=4"
, "//lst[@name='true']/double[@name='sumOfSquares'][.='50500.0']"
, "//lst[@name='true']/double[@name='mean'][.='17.5']"
, "//lst[@name='true']/double[@name='stddev'][.='128.16005617976296']"
@@ -149,7 +166,7 @@ public class StatsComponentTest extends
, "//lst[@name='false']/long[@name='count'][.='4']"
, "//lst[@name='false']/long[@name='missing'][.='1']"
, "//lst[@name='true']//long[@name='countDistinct'][.='4']"
- , "count(//lst[@name='true']/arr[@name='distinctValues']/*)='4'"
+ , "count(//lst[@name='true']/arr[@name='distinctValues']/*)=4"
, "//lst[@name='false']/double[@name='sumOfSquares'][.='2601.0']"
, "//lst[@name='false']/double[@name='mean'][.='-15.25']"
, "//lst[@name='false']/double[@name='stddev'][.='23.59908190304586']"
@@ -180,7 +197,7 @@ public class StatsComponentTest extends
"//long[@name='count'][.='3']",
"//long[@name='missing'][.='1']",
"//long[@name='countDistinct'][.='3']",
- "count(//arr[@name='distinctValues']/str)='3'");
+ "count(//arr[@name='distinctValues']/str)=3");
}
public void testFieldStatisticsResultsDateField() throws Exception {
@@ -211,7 +228,7 @@ public class StatsComponentTest extends
"//date[@name='min'][.='1970-01-02T10:17:36Z']",
"//date[@name='max'][.='1970-01-12T10:20:54Z']",
"//long[@name='countDistinct'][.='2']",
- "count(//arr[@name='distinctValues']/date)='2'"
+ "count(//arr[@name='distinctValues']/date)=2"
// "//date[@name='sum'][.='1970-01-13T20:38:30Z']", // sometimes 29.999Z
// "//date[@name='mean'][.='1970-01-07T10:19:15Z']" // sometiems 14.999Z
);
@@ -233,7 +250,7 @@ public class StatsComponentTest extends
, "//long[@name='count'][.='3']"
, "//long[@name='missing'][.='1']"
, "//long[@name='countDistinct'][.='3']"
- , "count(//arr[@name='distinctValues']/*)='3'"
+ , "count(//arr[@name='distinctValues']/*)=3"
, "//double[@name='sumOfSquares'][.='2100.0']"
, "//double[@name='mean'][.='-23.333333333333332']"
, "//double[@name='stddev'][.='15.275252316519467']"
@@ -258,7 +275,7 @@ public class StatsComponentTest extends
, pre+"/lst[@name='true']/long[@name='count'][.='2']"
, pre+"/lst[@name='true']/long[@name='missing'][.='0']"
, pre + "/lst[@name='true']/long[@name='countDistinct'][.='2']"
- , "count(" + pre + "/lst[@name='true']/arr[@name='distinctValues']/*)='2'"
+ , "count(" + pre + "/lst[@name='true']/arr[@name='distinctValues']/*)=2"
, pre+"/lst[@name='true']/double[@name='sumOfSquares'][.='500.0']"
, pre+"/lst[@name='true']/double[@name='mean'][.='15.0']"
, pre+"/lst[@name='true']/double[@name='stddev'][.='7.0710678118654755']"
@@ -271,7 +288,7 @@ public class StatsComponentTest extends
, pre+"/lst[@name='false']/long[@name='count'][.='2']"
, pre+"/lst[@name='false']/long[@name='missing'][.='0']"
, pre + "/lst[@name='true']/long[@name='countDistinct'][.='2']"
- , "count(" + pre + "/lst[@name='true']/arr[@name='distinctValues']/*)='2'"
+ , "count(" + pre + "/lst[@name='true']/arr[@name='distinctValues']/*)=2"
, pre+"/lst[@name='false']/double[@name='sumOfSquares'][.='2500.0']"
, pre+"/lst[@name='false']/double[@name='mean'][.='35.0']"
, pre+"/lst[@name='false']/double[@name='stddev'][.='7.0710678118654755']"
@@ -293,7 +310,7 @@ public class StatsComponentTest extends
, "//lst[@name='true']/long[@name='count'][.='2']"
, "//lst[@name='true']/long[@name='missing'][.='0']"
, "//lst[@name='true']/long[@name='countDistinct'][.='2']"
- , "count(//lst[@name='true']/arr[@name='distinctValues']/*)='2'"
+ , "count(//lst[@name='true']/arr[@name='distinctValues']/*)=2"
, "//lst[@name='true']/double[@name='sumOfSquares'][.='500.0']"
, "//lst[@name='true']/double[@name='mean'][.='15.0']"
, "//lst[@name='true']/double[@name='stddev'][.='7.0710678118654755']"
@@ -306,7 +323,7 @@ public class StatsComponentTest extends
, "//lst[@name='false']/long[@name='count'][.='1']"
, "//lst[@name='false']/long[@name='missing'][.='1']"
, "//lst[@name='false']/long[@name='countDistinct'][.='1']"
- , "count(//lst[@name='false']/arr[@name='distinctValues']/*)='1'"
+ , "count(//lst[@name='false']/arr[@name='distinctValues']/*)=1"
, "//lst[@name='false']/double[@name='sumOfSquares'][.='1600.0']"
, "//lst[@name='false']/double[@name='mean'][.='40.0']"
, "//lst[@name='false']/double[@name='stddev'][.='0.0']"
@@ -427,4 +444,186 @@ public class StatsComponentTest extends
, "//lst[@name='id2']/double[@name='min'][.='2.0']"
, "//lst[@name='id2']/double[@name='max'][.='3.0']");
}
+
+ // SOLR-6024
+ public void testFieldStatisticsDocValuesAndMultiValued() throws Exception {
+ SolrCore core = h.getCore();
+
+ // precondition for the test
+ SchemaField catDocValues = core.getLatestSchema().getField("cat_docValues");
+ assertTrue("schema no longer satisfies test requirements: cat_docValues no longer multivalued", catDocValues.multiValued());
+ assertTrue("schema no longer satisfies test requirements: cat_docValues fieldtype no longer single valued", !catDocValues.getType().isMultiValued());
+ assertTrue("schema no longer satisfies test requirements: cat_docValues no longer has docValues", catDocValues.hasDocValues());
+
+ List<FldType> types = new ArrayList<>();
+ types.add(new FldType("id", ONE_ONE, new SVal('A', 'Z', 4, 4)));
+ types.add(new FldType("cat_docValues",new IRange(2,2), new SVal('a','z',1, 30)));
+ Doc d1 = createDoc(types);
+ d1.getValues("id").set(0, "1");
+ d1.getValues("cat_docValues").set(0, "test");
+ d1.getValues("cat_docValues").set(1, "testtw");
+ updateJ(toJSON(d1), null);
+ Doc d2 = createDoc(types);
+ d2.getValues("id").set(0, "2");
+ d2.getValues("cat_docValues").set(0, "test");
+ d2.getValues("cat_docValues").set(1, "testtt");
+ updateJ(toJSON(d2), null);
+
+ assertU(commit());
+
+ Map<String, String> args = new HashMap<>();
+ args.put(CommonParams.Q, "*:*");
+ args.put(StatsParams.STATS, "true");
+ args.put(StatsParams.STATS_FIELD, "cat_docValues");
+ args.put("indent", "true");
+ SolrQueryRequest req = new LocalSolrQueryRequest(core, new MapSolrParams(args));
+
+ assertQ("test min/max on docValues and multiValued", req
+ , "//lst[@name='cat_docValues']/str[@name='min'][.='test']"
+ , "//lst[@name='cat_docValues']/str[@name='max'][.='testtw']");
+
+ }
+
+ public void testFieldStatisticsDocValuesAndMultiValuedInteger() throws Exception {
+ SolrCore core = h.getCore();
+ String fieldName = "cat_intDocValues";
+ // precondition for the test
+ SchemaField catDocValues = core.getLatestSchema().getField(fieldName);
+ assertTrue("schema no longer satisfies test requirements: cat_docValues no longer multivalued", catDocValues.multiValued());
+ assertTrue("schema no longer satisfies test requirements: cat_docValues fieldtype no longer single valued", !catDocValues.getType().isMultiValued());
+ assertTrue("schema no longer satisfies test requirements: cat_docValues no longer has docValues", catDocValues.hasDocValues());
+
+ List<FldType> types = new ArrayList<>();
+ types.add(new FldType("id", ONE_ONE, new SVal('A', 'Z', 4, 4)));
+ types.add(new FldType(fieldName, ONE_ONE, new IRange(0, 0)));
+
+ Doc d1 = createDocValuesDocument(types, fieldName, "1", -1, 3, 5);
+ updateJ(toJSON(d1), null);
+
+ Doc d2 = createDocValuesDocument(types, fieldName, "2", 3, -2, 6);
+ updateJ(toJSON(d2), null);
+
+ Doc d3 = createDocValuesDocument(types, fieldName, "3", 16, -3, 11);
+ updateJ(toJSON(d3), null);
+
+ assertU(commit());
+
+ Map<String, String> args = new HashMap<>();
+ args.put(CommonParams.Q, "*:*");
+ args.put(StatsParams.STATS, "true");
+ args.put(StatsParams.STATS_FIELD, fieldName);
+ args.put("indent", "true");
+ args.put(StatsParams.STATS_CALC_DISTINCT, "true");
+
+ SolrQueryRequest req = new LocalSolrQueryRequest(core, new MapSolrParams(args));
+
+ assertQ("test min/max on docValues and multiValued", req
+ , "//lst[@name='" + fieldName + "']/double[@name='min'][.='-3.0']"
+ , "//lst[@name='" + fieldName + "']/double[@name='max'][.='16.0']"
+ , "//lst[@name='" + fieldName + "']/long[@name='count'][.='12']"
+ , "//lst[@name='" + fieldName + "']/long[@name='countDistinct'][.='9']"
+ , "//lst[@name='" + fieldName + "']/double[@name='sum'][.='38.0']"
+ , "//lst[@name='" + fieldName + "']/double[@name='mean'][.='3.1666666666666665']"
+ , "//lst[@name='" + fieldName + "']/double[@name='stddev'][.='5.638074031784151']"
+ , "//lst[@name='" + fieldName + "']/double[@name='sumOfSquares'][.='470.0']"
+ , "//lst[@name='" + fieldName + "']/long[@name='missing'][.='0']");
+
+ }
+
+ public void testFieldStatisticsDocValuesAndMultiValuedIntegerFacetStats() throws Exception {
+ SolrCore core = h.getCore();
+ String fieldName = "cat_intDocValues";
+ // precondition for the test
+ SchemaField catDocValues = core.getLatestSchema().getField(fieldName);
+ assertTrue("schema no longer satisfies test requirements: cat_docValues no longer multivalued", catDocValues.multiValued());
+ assertTrue("schema no longer satisfies test requirements: cat_docValues fieldtype no longer single valued", !catDocValues.getType().isMultiValued());
+ assertTrue("schema no longer satisfies test requirements: cat_docValues no longer has docValues", catDocValues.hasDocValues());
+
+ List<FldType> types = new ArrayList<>();
+ types.add(new FldType("id", ONE_ONE, new SVal('A', 'Z', 4, 4)));
+ types.add(new FldType(fieldName, ONE_ONE, new IRange(0, 0)));
+
+ Doc d1 = createDocValuesDocument(types, fieldName, "1", -1, 3, 5);
+ updateJ(toJSON(d1), null);
+
+ Doc d2 = createDocValuesDocument(types, fieldName, "2", 3, -2, 6);
+ updateJ(toJSON(d2), null);
+
+ Doc d3 = createDocValuesDocument(types, fieldName, "3", 16, -3, 11);
+ updateJ(toJSON(d3), null);
+
+ assertU(commit());
+
+ Map<String, String> args = new HashMap<>();
+ args.put(CommonParams.Q, "*:*");
+ args.put(StatsParams.STATS, "true");
+ args.put(StatsParams.STATS_FIELD, fieldName);
+ args.put(StatsParams.STATS_FACET, fieldName);
+ args.put("indent", "true");
+ args.put(StatsParams.STATS_CALC_DISTINCT, "true");
+
+ SolrQueryRequest req = new LocalSolrQueryRequest(core, new MapSolrParams(args));
+
+ assertQEx("can not use FieldCache on multivalued field: cat_intDocValues", req, 400);
+
+ }
+
+
+
+ public void testFieldStatisticsDocValuesAndMultiValuedDouble() throws Exception {
+ SolrCore core = h.getCore();
+ String fieldName = "cat_floatDocValues";
+ // precondition for the test
+ SchemaField catDocValues = core.getLatestSchema().getField(fieldName);
+ assertTrue("schema no longer satisfies test requirements: cat_docValues no longer multivalued", catDocValues.multiValued());
+ assertTrue("schema no longer satisfies test requirements: cat_docValues fieldtype no longer single valued", !catDocValues.getType().isMultiValued());
+ assertTrue("schema no longer satisfies test requirements: cat_docValues no longer has docValues", catDocValues.hasDocValues());
+
+ List<FldType> types = new ArrayList<>();
+ types.add(new FldType("id", ONE_ONE, new SVal('A', 'Z', 4, 4)));
+ types.add(new FldType(fieldName, ONE_ONE, new FVal(0, 0)));
+
+ Doc d1 = createDocValuesDocument(types, fieldName, "1", -1, 3, 5);
+ updateJ(toJSON(d1), null);
+
+ Doc d2 = createDocValuesDocument(types, fieldName, "2", 3, -2, 6);
+ updateJ(toJSON(d2), null);
+
+ Doc d3 = createDocValuesDocument(types, fieldName, "3", 16, -3, 11);
+ updateJ(toJSON(d3), null);
+
+ assertU(commit());
+
+ Map<String, String> args = new HashMap<>();
+ args.put(CommonParams.Q, "*:*");
+ args.put(StatsParams.STATS, "true");
+ args.put(StatsParams.STATS_FIELD, fieldName);
+ args.put(StatsParams.STATS_CALC_DISTINCT, "true");
+ args.put("indent", "true");
+ SolrQueryRequest req = new LocalSolrQueryRequest(core, new MapSolrParams(args));
+
+ assertQ("test min/max on docValues and multiValued", req
+ , "//lst[@name='" + fieldName + "']/double[@name='min'][.='-3.0']"
+ , "//lst[@name='" + fieldName + "']/double[@name='max'][.='16.0']"
+ , "//lst[@name='" + fieldName + "']/long[@name='count'][.='12']"
+ , "//lst[@name='" + fieldName + "']/double[@name='sum'][.='38.0']"
+ , "//lst[@name='" + fieldName + "']/long[@name='countDistinct'][.='9']"
+ , "//lst[@name='" + fieldName + "']/double[@name='mean'][.='3.1666666666666665']"
+ , "//lst[@name='" + fieldName + "']/double[@name='stddev'][.='5.638074031784151']"
+ , "//lst[@name='" + fieldName + "']/double[@name='sumOfSquares'][.='470.0']"
+ , "//lst[@name='" + fieldName + "']/long[@name='missing'][.='0']");
+
+ }
+
+ private Doc createDocValuesDocument(List<FldType> types, String fieldName, String id, Comparable... values) throws Exception {
+ Doc doc = createDoc(types);
+ doc.getValues("id").set(0, id);
+ initMultyValued(doc.getValues(fieldName), values);
+ return doc;
+ }
+
+ private List<Comparable> initMultyValued(List<Comparable> cat_docValues, Comparable... comparables) {
+ Collections.addAll(cat_docValues, comparables);
+ return cat_docValues;
+ }
}