You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by is...@apache.org on 2017/07/29 22:00:03 UTC
[26/28] lucene-solr:jira/solr-6630: Merging master
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/core/NodeConfig.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/core/NodeConfig.java b/solr/core/src/java/org/apache/solr/core/NodeConfig.java
index 2b70130..5b4debe 100644
--- a/solr/core/src/java/org/apache/solr/core/NodeConfig.java
+++ b/solr/core/src/java/org/apache/solr/core/NodeConfig.java
@@ -33,6 +33,8 @@ public class NodeConfig {
private final Path coreRootDirectory;
+ private final Path solrDataHome;
+
private final Path configSetBaseDirectory;
private final String sharedLibDirectory;
@@ -69,7 +71,7 @@ public class NodeConfig {
private final PluginInfo transientCacheConfig;
- private NodeConfig(String nodeName, Path coreRootDirectory, Path configSetBaseDirectory, String sharedLibDirectory,
+ private NodeConfig(String nodeName, Path coreRootDirectory, Path solrDataHome, Path configSetBaseDirectory, String sharedLibDirectory,
PluginInfo shardHandlerFactoryConfig, UpdateShardHandlerConfig updateShardHandlerConfig,
String coreAdminHandlerClass, String collectionsAdminHandlerClass,
String infoHandlerClass, String configSetsHandlerClass,
@@ -79,6 +81,7 @@ public class NodeConfig {
MetricsConfig metricsConfig, PluginInfo transientCacheConfig) {
this.nodeName = nodeName;
this.coreRootDirectory = coreRootDirectory;
+ this.solrDataHome = solrDataHome;
this.configSetBaseDirectory = configSetBaseDirectory;
this.sharedLibDirectory = sharedLibDirectory;
this.shardHandlerFactoryConfig = shardHandlerFactoryConfig;
@@ -113,6 +116,10 @@ public class NodeConfig {
return coreRootDirectory;
}
+ public Path getSolrDataHome() {
+ return solrDataHome;
+ }
+
public PluginInfo getShardHandlerFactoryPluginInfo() {
return shardHandlerFactoryConfig;
}
@@ -195,6 +202,7 @@ public class NodeConfig {
public static class NodeConfigBuilder {
private Path coreRootDirectory;
+ private Path solrDataHome;
private Path configSetBaseDirectory;
private String sharedLibDirectory = "lib";
private PluginInfo shardHandlerFactoryConfig;
@@ -242,6 +250,11 @@ public class NodeConfig {
this.nodeName = nodeName;
this.loader = loader;
this.coreRootDirectory = loader.getInstancePath();
+ // always init from sysprop because <solrDataHome> config element may be missing
+ String dataHomeProperty = System.getProperty(SolrXmlConfig.SOLR_DATA_HOME);
+ if (dataHomeProperty != null && !dataHomeProperty.isEmpty()) {
+ solrDataHome = loader.getInstancePath().resolve(dataHomeProperty);
+ }
this.configSetBaseDirectory = loader.getInstancePath().resolve("configsets");
this.metricsConfig = new MetricsConfig.MetricsConfigBuilder().build();
}
@@ -251,6 +264,14 @@ public class NodeConfig {
return this;
}
+ public NodeConfigBuilder setSolrDataHome(String solrDataHomeString) {
+ // keep it null unless explicitly set to non-empty value
+ if (solrDataHomeString != null && !solrDataHomeString.isEmpty()) {
+ this.solrDataHome = loader.getInstancePath().resolve(solrDataHomeString);
+ }
+ return this;
+ }
+
public NodeConfigBuilder setConfigSetBaseDirectory(String configSetBaseDirectory) {
this.configSetBaseDirectory = loader.getInstancePath().resolve(configSetBaseDirectory);
return this;
@@ -344,7 +365,7 @@ public class NodeConfig {
}
public NodeConfig build() {
- return new NodeConfig(nodeName, coreRootDirectory, configSetBaseDirectory, sharedLibDirectory, shardHandlerFactoryConfig,
+ return new NodeConfig(nodeName, coreRootDirectory, solrDataHome, configSetBaseDirectory, sharedLibDirectory, shardHandlerFactoryConfig,
updateShardHandlerConfig, coreAdminHandlerClass, collectionsAdminHandlerClass, infoHandlerClass, configSetsHandlerClass,
logWatcherConfig, cloudConfig, coreLoadThreads, transientCacheSize, useSchemaCache, managementPath, loader, solrProperties,
backupRepositoryPlugins, metricsConfig, transientCacheConfig);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/core/SolrCore.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/core/SolrCore.java b/solr/core/src/java/org/apache/solr/core/SolrCore.java
index 5319881..cc6a9c2 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrCore.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java
@@ -2565,8 +2565,8 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
static{
HashMap<String, QueryResponseWriter> m= new HashMap<>(15, 1);
m.put("xml", new XMLResponseWriter());
- m.put("standard", m.get("xml"));
m.put(CommonParams.JSON, new JSONResponseWriter());
+ m.put("standard", m.get(CommonParams.JSON));
m.put("geojson", new GeoJSONResponseWriter());
m.put("graphml", new GraphMLResponseWriter());
m.put("python", new PythonResponseWriter());
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java b/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
index e783a89..8cdf947 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
@@ -59,6 +59,7 @@ import static org.apache.solr.common.params.CommonParams.NAME;
public class SolrXmlConfig {
public final static String SOLR_XML_FILE = "solr.xml";
+ public final static String SOLR_DATA_HOME = "solr.data.home";
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -249,6 +250,9 @@ public class SolrXmlConfig {
case "coreRootDirectory":
builder.setCoreRootDirectory(value);
break;
+ case "solrDataHome":
+ builder.setSolrDataHome(value);
+ break;
case "managementPath":
builder.setManagementPath(value);
break;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/handler/AnalysisRequestHandlerBase.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/AnalysisRequestHandlerBase.java b/solr/core/src/java/org/apache/solr/handler/AnalysisRequestHandlerBase.java
index 0770bd4..579e5ef 100644
--- a/solr/core/src/java/org/apache/solr/handler/AnalysisRequestHandlerBase.java
+++ b/solr/core/src/java/org/apache/solr/handler/AnalysisRequestHandlerBase.java
@@ -33,6 +33,7 @@ import org.apache.commons.lang.ArrayUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.tokenattributes.BytesTermAttribute;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
@@ -248,8 +249,14 @@ public abstract class AnalysisRequestHandlerBase extends RequestHandlerBase {
for (int i = 0; i < tokens.length; i++) {
AttributeSource token = tokens[i];
final NamedList<Object> tokenNamedList = new SimpleOrderedMap<>();
- final TermToBytesRefAttribute termAtt = token.getAttribute(TermToBytesRefAttribute.class);
- BytesRef rawBytes = termAtt.getBytesRef();
+ final BytesRef rawBytes;
+ if (token.hasAttribute(BytesTermAttribute.class)) {
+ final BytesTermAttribute bytesAtt = token.getAttribute(BytesTermAttribute.class);
+ rawBytes = bytesAtt.getBytesRef();
+ } else {
+ final TermToBytesRefAttribute termAtt = token.getAttribute(TermToBytesRefAttribute.class);
+ rawBytes = termAtt.getBytesRef();
+ }
final String text = fieldType.indexedToReadable(rawBytes, new CharsRefBuilder()).toString();
tokenNamedList.add("text", text);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/handler/ExportWriter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/ExportWriter.java b/solr/core/src/java/org/apache/solr/handler/ExportWriter.java
index 61f937c..f618eef 100644
--- a/solr/core/src/java/org/apache/solr/handler/ExportWriter.java
+++ b/solr/core/src/java/org/apache/solr/handler/ExportWriter.java
@@ -17,10 +17,6 @@
package org.apache.solr.handler;
-import static java.util.Collections.singletonList;
-import static java.util.Collections.singletonMap;
-import static org.apache.solr.common.util.Utils.makeMap;
-
import java.io.Closeable;
import java.io.IOException;
import java.io.OutputStream;
@@ -38,6 +34,7 @@ import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.MultiDocValues;
import org.apache.lucene.index.NumericDocValues;
+import org.apache.lucene.index.OrdinalMap;
import org.apache.lucene.index.SortedDocValues;
import org.apache.lucene.index.SortedNumericDocValues;
import org.apache.lucene.index.SortedSetDocValues;
@@ -53,8 +50,8 @@ import org.apache.lucene.util.LongValues;
import org.apache.lucene.util.NumericUtils;
import org.apache.solr.client.solrj.impl.BinaryResponseParser;
import org.apache.solr.common.IteratorWriter;
-import org.apache.solr.common.MapWriter;
import org.apache.solr.common.MapWriter.EntryWriter;
+import org.apache.solr.common.MapWriter;
import org.apache.solr.common.PushWriter;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.SolrParams;
@@ -82,6 +79,10 @@ import org.apache.solr.search.SyntaxError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static java.util.Collections.singletonList;
+import static java.util.Collections.singletonMap;
+import static org.apache.solr.common.util.Utils.makeMap;
+
public class ExportWriter implements SolrCore.RawWriter, Closeable {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private OutputStreamWriter respWriter;
@@ -1257,7 +1258,7 @@ public class ExportWriter implements SolrCore.RawWriter, Closeable {
protected SortedDocValues vals;
- protected MultiDocValues.OrdinalMap ordinalMap;
+ protected OrdinalMap ordinalMap;
protected LongValues globalOrds;
protected SortedDocValues currentVals;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
index 2d545ba..1da8f85 100644
--- a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
@@ -205,7 +205,7 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
private final Map<String, FileInfo> confFileInfoCache = new HashMap<>();
- private Integer reserveCommitDuration = readIntervalMs("00:00:10");
+ private Long reserveCommitDuration = readIntervalMs("00:00:10");
volatile IndexCommit indexCommitPoint;
@@ -1695,8 +1695,8 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
}
- private static Integer readIntervalMs(String interval) {
- return (int) TimeUnit.MILLISECONDS.convert(readIntervalNs(interval), TimeUnit.NANOSECONDS);
+ private static Long readIntervalMs(String interval) {
+ return TimeUnit.MILLISECONDS.convert(readIntervalNs(interval), TimeUnit.NANOSECONDS);
}
private static Long readIntervalNs(String interval) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/StreamHandler.java b/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
index 3901c61..d52972d 100644
--- a/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
@@ -217,8 +217,9 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
.withFunctionName("scale", ScaleEvaluator.class)
.withFunctionName("sequence", SequenceEvaluator.class)
.withFunctionName("addAll", AddAllEvaluator.class)
+ .withFunctionName("residuals", ResidualsEvaluator.class)
+ .withFunctionName("plot", PlotStream.class)
-
// Boolean Stream Evaluators
.withFunctionName("and", AndEvaluator.class)
.withFunctionName("eor", ExclusiveOrEvaluator.class)
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
index 1b72c92..cbaa4ef 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
@@ -126,6 +126,7 @@ import static org.apache.solr.common.params.CoreAdminParams.DELETE_DATA_DIR;
import static org.apache.solr.common.params.CoreAdminParams.DELETE_INDEX;
import static org.apache.solr.common.params.CoreAdminParams.DELETE_INSTANCE_DIR;
import static org.apache.solr.common.params.CoreAdminParams.INSTANCE_DIR;
+import static org.apache.solr.common.params.CoreAdminParams.ULOG_DIR;
import static org.apache.solr.common.params.ShardParams._ROUTE_;
import static org.apache.solr.common.util.StrUtils.formatString;
@@ -633,6 +634,7 @@ public class CollectionsHandler extends RequestHandlerBase implements Permission
CoreAdminParams.NAME,
INSTANCE_DIR,
DATA_DIR,
+ ULOG_DIR,
REPLICA_TYPE);
return copyPropertiesWithPrefix(req.getParams(), props, COLL_PROP_PREFIX);
}),
@@ -880,14 +882,26 @@ public class CollectionsHandler extends RequestHandlerBase implements Permission
rsp.add(SolrSnapshotManager.SNAPSHOTS_INFO, snapshots);
return null;
}),
- REPLACENODE_OP(REPLACENODE, (req, rsp, h) -> req.getParams().required().getAll(req.getParams().getAll(null, "parallel"), "source", "target")),
+ REPLACENODE_OP(REPLACENODE, (req, rsp, h) -> {
+ SolrParams params = req.getParams();
+ String sourceNode = params.get(CollectionParams.SOURCE_NODE, params.get("source"));
+ if (sourceNode == null) {
+ throw new SolrException(ErrorCode.BAD_REQUEST, CollectionParams.SOURCE_NODE + " is a require parameter");
+ }
+ String targetNode = params.get(CollectionParams.TARGET_NODE, params.get("target"));
+ if (targetNode == null) {
+ throw new SolrException(ErrorCode.BAD_REQUEST, CollectionParams.TARGET_NODE + " is a require parameter");
+ }
+ return params.getAll(null, "source", "target", CollectionParams.SOURCE_NODE, CollectionParams.TARGET_NODE);
+ }),
MOVEREPLICA_OP(MOVEREPLICA, (req, rsp, h) -> {
Map<String, Object> map = req.getParams().required().getAll(null,
COLLECTION_PROP);
return req.getParams().getAll(map,
- "fromNode",
- "targetNode",
+ CollectionParams.FROM_NODE,
+ CollectionParams.SOURCE_NODE,
+ CollectionParams.TARGET_NODE,
"replica",
"shard");
}),
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/handler/admin/SolrInfoMBeanHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/SolrInfoMBeanHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/SolrInfoMBeanHandler.java
index 4faa466..f9a3c05 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/SolrInfoMBeanHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/SolrInfoMBeanHandler.java
@@ -209,14 +209,16 @@ public class SolrInfoMBeanHandler extends RequestHandlerBase {
for(int i=0; i<ref.size(); i++) {
String name = ref.getName(i);
Object r = ref.getVal(i);
- Object n = now.remove(name);
- if(n == null) {
- if(r!=null) {
- out.add("REMOVE "+name, r);
+ Object n = now.get(name);
+ if (n == null) {
+ if (r != null) {
+ out.add("REMOVE " + name, r);
+ now.remove(name);
}
}
- else {
- out.add(name, diffObject(r,n));
+ else if (r != null) {
+ out.add(name, diffObject(r, n));
+ now.remove(name);
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/handler/component/ExpandComponent.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/component/ExpandComponent.java b/solr/core/src/java/org/apache/solr/handler/component/ExpandComponent.java
index 10c5b13..e2bcef8 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/ExpandComponent.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/ExpandComponent.java
@@ -24,15 +24,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import com.carrotsearch.hppc.IntHashSet;
-import com.carrotsearch.hppc.IntObjectHashMap;
-import com.carrotsearch.hppc.LongHashSet;
-import com.carrotsearch.hppc.LongObjectHashMap;
-import com.carrotsearch.hppc.LongObjectMap;
-import com.carrotsearch.hppc.cursors.IntObjectCursor;
-import com.carrotsearch.hppc.cursors.LongCursor;
-import com.carrotsearch.hppc.cursors.LongObjectCursor;
-import com.carrotsearch.hppc.cursors.ObjectCursor;
import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.DocValuesType;
import org.apache.lucene.index.FieldInfo;
@@ -42,6 +33,7 @@ import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.MultiDocValues;
import org.apache.lucene.index.NumericDocValues;
+import org.apache.lucene.index.OrdinalMap;
import org.apache.lucene.index.SortedDocValues;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
@@ -88,6 +80,16 @@ import org.apache.solr.uninverting.UninvertingReader;
import org.apache.solr.util.plugin.PluginInfoInitialized;
import org.apache.solr.util.plugin.SolrCoreAware;
+import com.carrotsearch.hppc.IntHashSet;
+import com.carrotsearch.hppc.IntObjectHashMap;
+import com.carrotsearch.hppc.LongHashSet;
+import com.carrotsearch.hppc.LongObjectHashMap;
+import com.carrotsearch.hppc.LongObjectMap;
+import com.carrotsearch.hppc.cursors.IntObjectCursor;
+import com.carrotsearch.hppc.cursors.LongCursor;
+import com.carrotsearch.hppc.cursors.LongObjectCursor;
+import com.carrotsearch.hppc.cursors.ObjectCursor;
+
/**
* The ExpandComponent is designed to work with the CollapsingPostFilter.
* The CollapsingPostFilter collapses a result set on a field.
@@ -274,7 +276,7 @@ public class ExpandComponent extends SearchComponent implements PluginInfoInitia
IntObjectHashMap<BytesRef> ordBytes = null;
if(values != null) {
groupBits = new FixedBitSet(values.getValueCount());
- MultiDocValues.OrdinalMap ordinalMap = null;
+ OrdinalMap ordinalMap = null;
SortedDocValues[] sortedDocValues = null;
LongValues segmentOrdinalMap = null;
SortedDocValues currentValues = null;
@@ -520,7 +522,7 @@ public class ExpandComponent extends SearchComponent implements PluginInfoInitia
private static class GroupExpandCollector implements Collector, GroupCollector {
private SortedDocValues docValues;
- private MultiDocValues.OrdinalMap ordinalMap;
+ private OrdinalMap ordinalMap;
private SortedDocValues segmentValues;
private LongValues segmentOrdinalMap;
private MultiDocValues.MultiSortedDocValues multiSortedDocValues;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java b/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java
index ad1e81f..2d612e9 100644
--- a/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java
+++ b/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java
@@ -22,7 +22,7 @@ import java.util.Map;
import org.apache.lucene.index.*;
import org.apache.lucene.index.MultiDocValues.MultiSortedDocValues;
-import org.apache.lucene.index.MultiDocValues.OrdinalMap;
+import org.apache.lucene.index.OrdinalMap;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.Version;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/request/DocValuesFacets.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/request/DocValuesFacets.java b/solr/core/src/java/org/apache/solr/request/DocValuesFacets.java
index e9498f8..d77c73d 100644
--- a/solr/core/src/java/org/apache/solr/request/DocValuesFacets.java
+++ b/solr/core/src/java/org/apache/solr/request/DocValuesFacets.java
@@ -22,9 +22,9 @@ import java.util.function.Predicate;
import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.MultiDocValues;
import org.apache.lucene.index.MultiDocValues.MultiSortedSetDocValues;
-import org.apache.lucene.index.MultiDocValues.OrdinalMap;
+import org.apache.lucene.index.MultiDocValues;
+import org.apache.lucene.index.OrdinalMap;
import org.apache.lucene.index.SortedDocValues;
import org.apache.lucene.index.SortedSetDocValues;
import org.apache.lucene.search.DocIdSet;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/request/DocValuesStats.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/request/DocValuesStats.java b/solr/core/src/java/org/apache/solr/request/DocValuesStats.java
index 4b1fe84..dae9943 100644
--- a/solr/core/src/java/org/apache/solr/request/DocValuesStats.java
+++ b/solr/core/src/java/org/apache/solr/request/DocValuesStats.java
@@ -22,9 +22,9 @@ import java.util.Map;
import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.MultiDocValues;
import org.apache.lucene.index.MultiDocValues.MultiSortedSetDocValues;
-import org.apache.lucene.index.MultiDocValues.OrdinalMap;
+import org.apache.lucene.index.MultiDocValues;
+import org.apache.lucene.index.OrdinalMap;
import org.apache.lucene.index.SortedDocValues;
import org.apache.lucene.index.SortedSetDocValues;
import org.apache.lucene.search.DocIdSet;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/request/IntervalFacets.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/request/IntervalFacets.java b/solr/core/src/java/org/apache/solr/request/IntervalFacets.java
index 9a23a83..c2d6ab0 100644
--- a/solr/core/src/java/org/apache/solr/request/IntervalFacets.java
+++ b/solr/core/src/java/org/apache/solr/request/IntervalFacets.java
@@ -216,9 +216,7 @@ public class IntervalFacets implements Iterable<FacetInterval> {
longs = new FilterNumericDocValues(DocValues.getNumeric(ctx.reader(), fieldName)) {
@Override
public long longValue() throws IOException {
- long bits = super.longValue();
- if (bits < 0) bits ^= 0x7fffffffffffffffL;
- return bits;
+ return NumericUtils.sortableFloatBits((int)super.longValue());
}
};
break;
@@ -227,9 +225,7 @@ public class IntervalFacets implements Iterable<FacetInterval> {
longs = new FilterNumericDocValues(DocValues.getNumeric(ctx.reader(), fieldName)) {
@Override
public long longValue() throws IOException {
- long bits = super.longValue();
- if (bits < 0) bits ^= 0x7fffffffffffffffL;
- return bits;
+ return NumericUtils.sortableDoubleBits(super.longValue());
}
};
break;
@@ -443,12 +439,12 @@ public class IntervalFacets implements Iterable<FacetInterval> {
INCLUDED,
GREATER_THAN_END,
}
-
+
/**
* Helper class to match and count of documents in specified intervals
*/
public static class FacetInterval {
-
+
/**
* Key to represent this interval
*/
@@ -508,6 +504,11 @@ public class IntervalFacets implements Iterable<FacetInterval> {
* The current count of documents in that match this interval
*/
private int count;
+
+ /**
+ * If this field is set to true, this interval {@code #getCount()} will always return 0.
+ */
+ private boolean includeNoDocs = false;
/**
*
@@ -650,7 +651,14 @@ public class IntervalFacets implements Iterable<FacetInterval> {
throw new AssertionError();
}
if (startOpen) {
- startLimit++;
+ if (startLimit == Long.MAX_VALUE) {
+ /*
+ * This interval can match no docs
+ */
+ includeNoDocs = true;
+ } else {
+ startLimit++;
+ }
}
}
@@ -678,7 +686,14 @@ public class IntervalFacets implements Iterable<FacetInterval> {
throw new AssertionError();
}
if (endOpen) {
- endLimit--;
+ if (endLimit == Long.MIN_VALUE) {
+ /*
+ * This interval can match no docs
+ */
+ includeNoDocs = true;
+ } else {
+ endLimit--;
+ }
}
}
}
@@ -886,6 +901,9 @@ public class IntervalFacets implements Iterable<FacetInterval> {
* @return The count of document that matched this interval
*/
public int getCount() {
+ if (includeNoDocs) {
+ return 0;
+ }
return this.count;
}
@@ -910,7 +928,6 @@ public class IntervalFacets implements Iterable<FacetInterval> {
*/
@Override
public Iterator<FacetInterval> iterator() {
-
return new ArrayList<FacetInterval>(Arrays.asList(intervals)).iterator();
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/response/TextResponseWriter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/response/TextResponseWriter.java b/solr/core/src/java/org/apache/solr/response/TextResponseWriter.java
index 261daee..4d052ae 100644
--- a/solr/core/src/java/org/apache/solr/response/TextResponseWriter.java
+++ b/solr/core/src/java/org/apache/solr/response/TextResponseWriter.java
@@ -84,7 +84,7 @@ public abstract class TextResponseWriter implements PushWriter {
this.req = req;
this.rsp = rsp;
String indent = req.getParams().get("indent");
- if (indent != null && !"".equals(indent) && !"off".equals(indent)) {
+ if (null == indent || !("off".equals(indent) || "false".equals(indent))){
doIndent=true;
}
returnFields = rsp.getReturnFields();
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/response/transform/ChildDocTransformerFactory.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/response/transform/ChildDocTransformerFactory.java b/solr/core/src/java/org/apache/solr/response/transform/ChildDocTransformerFactory.java
index 45b0efc..ff7c061 100644
--- a/solr/core/src/java/org/apache/solr/response/transform/ChildDocTransformerFactory.java
+++ b/solr/core/src/java/org/apache/solr/response/transform/ChildDocTransformerFactory.java
@@ -17,6 +17,7 @@
package org.apache.solr.response.transform;
import java.io.IOException;
+import java.util.Set;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexableField;
@@ -39,6 +40,7 @@ import org.apache.solr.search.DocList;
import org.apache.solr.search.QParser;
import org.apache.solr.search.QueryWrapperFilter;
import org.apache.solr.search.SyntaxError;
+import org.apache.solr.search.SolrDocumentFetcher;
/**
*
@@ -135,12 +137,21 @@ class ChildDocTransformer extends DocTransformer {
Query query = new ToChildBlockJoinQuery(parentQuery, parentsFilter);
DocList children = context.getSearcher().getDocList(query, childFilterQuery, new Sort(), 0, limit);
if(children.matches() > 0) {
+ SolrDocumentFetcher docFetcher = context.getSearcher().getDocFetcher();
+
+ Set<String> dvFieldsToReturn = docFetcher.getNonStoredDVs(true);
+ boolean shouldDecorateWithDVs = dvFieldsToReturn.size() > 0;
DocIterator i = children.iterator();
+
while(i.hasNext()) {
Integer childDocNum = i.next();
Document childDoc = context.getSearcher().doc(childDocNum);
SolrDocument solrChildDoc = DocsStreamer.convertLuceneDocToSolrDoc(childDoc, schema);
+ if (shouldDecorateWithDVs) {
+ docFetcher.decorateDocValueFields(solrChildDoc, childDocNum, dvFieldsToReturn);
+ }
+
// TODO: future enhancement...
// support an fl local param in the transformer, which is used to build
// a private ReturnFields instance that we use to prune unwanted field
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/schema/CollationField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/CollationField.java b/solr/core/src/java/org/apache/solr/schema/CollationField.java
index c6a4f81..b8285aa 100644
--- a/solr/core/src/java/org/apache/solr/schema/CollationField.java
+++ b/solr/core/src/java/org/apache/solr/schema/CollationField.java
@@ -241,7 +241,7 @@ public class CollationField extends FieldType {
BytesRef low = part1 == null ? null : getCollationKey(f, part1);
BytesRef high = part2 == null ? null : getCollationKey(f, part2);
if (!field.indexed() && field.hasDocValues()) {
- return SortedSetDocValuesField.newRangeQuery(
+ return SortedSetDocValuesField.newSlowRangeQuery(
field.getName(), low, high, minInclusive, maxInclusive);
} else {
return new TermRangeQuery(field.getName(), low, high, minInclusive, maxInclusive);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/schema/DatePointField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/DatePointField.java b/solr/core/src/java/org/apache/solr/schema/DatePointField.java
index ea81ea3..e43f706 100644
--- a/solr/core/src/java/org/apache/solr/schema/DatePointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/DatePointField.java
@@ -27,6 +27,7 @@ import org.apache.lucene.index.IndexableField;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.valuesource.LongFieldSource;
import org.apache.lucene.queries.function.valuesource.MultiValuedLongFieldSource;
+import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.SortedNumericSelector;
@@ -123,6 +124,7 @@ public class DatePointField extends PointField implements DateValueFieldType {
} else {
actualMin = DateMathParser.parseMath(null, min).getTime();
if (!minInclusive) {
+ if (actualMin == Long.MAX_VALUE) return new MatchNoDocsQuery();
actualMin++;
}
}
@@ -131,6 +133,7 @@ public class DatePointField extends PointField implements DateValueFieldType {
} else {
actualMax = DateMathParser.parseMath(null, max).getTime();
if (!maxInclusive) {
+ if (actualMax == Long.MIN_VALUE) return new MatchNoDocsQuery();
actualMax--;
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/schema/DoublePointField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/DoublePointField.java b/solr/core/src/java/org/apache/solr/schema/DoublePointField.java
index d2cf6ed..edc7c38 100644
--- a/solr/core/src/java/org/apache/solr/schema/DoublePointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/DoublePointField.java
@@ -18,7 +18,6 @@
package org.apache.solr.schema;
import java.util.Collection;
-
import org.apache.lucene.document.DoublePoint;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.index.DocValuesType;
@@ -26,6 +25,7 @@ import org.apache.lucene.index.IndexableField;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.valuesource.DoubleFieldSource;
import org.apache.lucene.queries.function.valuesource.MultiValuedDoubleFieldSource;
+import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.SortedNumericSelector;
@@ -63,6 +63,7 @@ public class DoublePointField extends PointField implements DoubleValueFieldType
} else {
actualMin = parseDoubleFromUser(field.getName(), min);
if (!minInclusive) {
+ if (actualMin == Double.POSITIVE_INFINITY) return new MatchNoDocsQuery();
actualMin = DoublePoint.nextUp(actualMin);
}
}
@@ -71,6 +72,7 @@ public class DoublePointField extends PointField implements DoubleValueFieldType
} else {
actualMax = parseDoubleFromUser(field.getName(), max);
if (!maxInclusive) {
+ if (actualMax == Double.NEGATIVE_INFINITY) return new MatchNoDocsQuery();
actualMax = DoublePoint.nextDown(actualMax);
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/schema/EnumField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/EnumField.java b/solr/core/src/java/org/apache/solr/schema/EnumField.java
index 60e65d5..a60cd80 100644
--- a/solr/core/src/java/org/apache/solr/schema/EnumField.java
+++ b/solr/core/src/java/org/apache/solr/schema/EnumField.java
@@ -386,8 +386,11 @@ public class EnumField extends PrimitiveFieldType {
return null;
}
final Integer intValue = stringValueToIntValue(value.toString());
- if (intValue == null || intValue.equals(DEFAULT_VALUE))
- throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown value for enum field: " + value.toString());
+ if (intValue == null || intValue.equals(DEFAULT_VALUE)) {
+ String exceptionMessage = String.format(Locale.ENGLISH, "Unknown value for enum field: %s, value: %s",
+ field.getName(), value.toString());
+ throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, exceptionMessage);
+ }
final LegacyFieldType newType = new LegacyFieldType();
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/schema/ExternalFileField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/ExternalFileField.java b/solr/core/src/java/org/apache/solr/schema/ExternalFileField.java
index da4b4db..db2d11b 100644
--- a/solr/core/src/java/org/apache/solr/schema/ExternalFileField.java
+++ b/solr/core/src/java/org/apache/solr/schema/ExternalFileField.java
@@ -22,6 +22,7 @@ import java.util.Map;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.search.SortField;
+import org.apache.solr.common.SolrException;
import org.apache.solr.response.TextResponseWriter;
import org.apache.solr.search.QParser;
import org.apache.solr.search.function.FileFloatSource;
@@ -122,5 +123,10 @@ public class ExternalFileField extends FieldType implements SchemaAware {
@Override
public void inform(IndexSchema schema) {
this.schema = schema;
+
+ if (keyFieldName != null && schema.getFieldType(keyFieldName).isPointField()) {
+ throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
+ "keyField '" + keyFieldName + "' has a Point field type, which is not supported.");
+ }
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/schema/FieldType.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/FieldType.java b/solr/core/src/java/org/apache/solr/schema/FieldType.java
index 388b659..3d38844 100644
--- a/solr/core/src/java/org/apache/solr/schema/FieldType.java
+++ b/solr/core/src/java/org/apache/solr/schema/FieldType.java
@@ -30,6 +30,7 @@ import java.util.Set;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.tokenattributes.BytesTermAttribute;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.analysis.util.CharFilterFactory;
@@ -479,14 +480,20 @@ public abstract class FieldType extends FieldProperties {
Tokenizer ts = new Tokenizer() {
final char[] cbuf = new char[maxChars];
final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
+ final BytesTermAttribute bytesAtt = isPointField() ? addAttribute(BytesTermAttribute.class) : null;
final OffsetAttribute offsetAtt = addAttribute(OffsetAttribute.class);
@Override
public boolean incrementToken() throws IOException {
clearAttributes();
int n = input.read(cbuf,0,maxChars);
if (n<=0) return false;
- String s = toInternal(new String(cbuf,0,n));
- termAtt.setEmpty().append(s);
+ if (isPointField()) {
+ BytesRef b = ((PointField)FieldType.this).toInternalByteRef(new String(cbuf, 0, n));
+ bytesAtt.setBytesRef(b);
+ } else {
+ String s = toInternal(new String(cbuf, 0, n));
+ termAtt.setEmpty().append(s);
+ }
offsetAtt.setOffset(correctOffset(0),correctOffset(n));
return true;
}
@@ -720,7 +727,7 @@ public abstract class FieldType extends FieldProperties {
final BytesRef miValue = part1 == null ? null : new BytesRef(toInternal(part1));
final BytesRef maxValue = part2 == null ? null : new BytesRef(toInternal(part2));
if (field.hasDocValues() && !field.indexed()) {
- return SortedSetDocValuesField.newRangeQuery(
+ return SortedSetDocValuesField.newSlowRangeQuery(
field.getName(),
miValue, maxValue,
minInclusive, maxInclusive);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/schema/FloatPointField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/FloatPointField.java b/solr/core/src/java/org/apache/solr/schema/FloatPointField.java
index e1a9741..c70655a 100644
--- a/solr/core/src/java/org/apache/solr/schema/FloatPointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/FloatPointField.java
@@ -18,7 +18,6 @@
package org.apache.solr.schema;
import java.util.Collection;
-
import org.apache.lucene.document.FloatPoint;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.index.DocValuesType;
@@ -26,6 +25,7 @@ import org.apache.lucene.index.IndexableField;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.valuesource.FloatFieldSource;
import org.apache.lucene.queries.function.valuesource.MultiValuedFloatFieldSource;
+import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.SortedNumericSelector;
@@ -63,6 +63,7 @@ public class FloatPointField extends PointField implements FloatValueFieldType {
} else {
actualMin = parseFloatFromUser(field.getName(), min);
if (!minInclusive) {
+ if (actualMin == Float.POSITIVE_INFINITY) return new MatchNoDocsQuery();
actualMin = FloatPoint.nextUp(actualMin);
}
}
@@ -71,6 +72,7 @@ public class FloatPointField extends PointField implements FloatValueFieldType {
} else {
actualMax = parseFloatFromUser(field.getName(), max);
if (!maxInclusive) {
+ if (actualMax == Float.NEGATIVE_INFINITY) return new MatchNoDocsQuery();
actualMax = FloatPoint.nextDown(actualMax);
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/schema/IntPointField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/IntPointField.java b/solr/core/src/java/org/apache/solr/schema/IntPointField.java
index 7d36612..d5e4aec 100644
--- a/solr/core/src/java/org/apache/solr/schema/IntPointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/IntPointField.java
@@ -25,6 +25,7 @@ import org.apache.lucene.index.IndexableField;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.valuesource.IntFieldSource;
import org.apache.lucene.queries.function.valuesource.MultiValuedIntFieldSource;
+import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.SortedNumericSelector;
@@ -66,6 +67,7 @@ public class IntPointField extends PointField implements IntValueFieldType {
} else {
actualMin = parseIntFromUser(field.getName(), min);
if (!minInclusive) {
+ if (actualMin == Integer.MAX_VALUE) return new MatchNoDocsQuery();
actualMin++;
}
}
@@ -74,6 +76,7 @@ public class IntPointField extends PointField implements IntValueFieldType {
} else {
actualMax = parseIntFromUser(field.getName(), max);
if (!maxInclusive) {
+ if (actualMax == Integer.MIN_VALUE) return new MatchNoDocsQuery();
actualMax--;
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/schema/LongPointField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/LongPointField.java b/solr/core/src/java/org/apache/solr/schema/LongPointField.java
index b2d8a3a..7e3f5e1 100644
--- a/solr/core/src/java/org/apache/solr/schema/LongPointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/LongPointField.java
@@ -25,6 +25,7 @@ import org.apache.lucene.index.IndexableField;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.valuesource.LongFieldSource;
import org.apache.lucene.queries.function.valuesource.MultiValuedLongFieldSource;
+import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortField;
import org.apache.lucene.util.BytesRef;
@@ -65,6 +66,7 @@ public class LongPointField extends PointField implements LongValueFieldType {
} else {
actualMin = parseLongFromUser(field.getName(), min);
if (!minInclusive) {
+ if (actualMin == Long.MAX_VALUE) return new MatchNoDocsQuery();
actualMin++;
}
}
@@ -73,6 +75,7 @@ public class LongPointField extends PointField implements LongValueFieldType {
} else {
actualMax = parseLongFromUser(field.getName(), max);
if (!maxInclusive) {
+ if (actualMax == Long.MIN_VALUE) return new MatchNoDocsQuery();
actualMax--;
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/schema/NumericFieldType.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/NumericFieldType.java b/solr/core/src/java/org/apache/solr/schema/NumericFieldType.java
index c79f465..86697e5 100644
--- a/solr/core/src/java/org/apache/solr/schema/NumericFieldType.java
+++ b/solr/core/src/java/org/apache/solr/schema/NumericFieldType.java
@@ -16,6 +16,8 @@
*/
package org.apache.solr.schema;
+import org.apache.lucene.document.DoublePoint;
+import org.apache.lucene.document.FloatPoint;
import org.apache.lucene.document.NumericDocValuesField;
import org.apache.lucene.document.SortedNumericDocValuesField;
import org.apache.lucene.queries.function.ValueSource;
@@ -40,14 +42,8 @@ public abstract class NumericFieldType extends PrimitiveFieldType {
return type;
}
- private static long FLOAT_NEGATIVE_INFINITY_BITS = (long)Float.floatToIntBits(Float.NEGATIVE_INFINITY);
- private static long DOUBLE_NEGATIVE_INFINITY_BITS = Double.doubleToLongBits(Double.NEGATIVE_INFINITY);
- private static long FLOAT_POSITIVE_INFINITY_BITS = (long)Float.floatToIntBits(Float.POSITIVE_INFINITY);
- private static long DOUBLE_POSITIVE_INFINITY_BITS = Double.doubleToLongBits(Double.POSITIVE_INFINITY);
private static long FLOAT_MINUS_ZERO_BITS = (long)Float.floatToIntBits(-0f);
private static long DOUBLE_MINUS_ZERO_BITS = Double.doubleToLongBits(-0d);
- private static long FLOAT_ZERO_BITS = (long)Float.floatToIntBits(0f);
- private static long DOUBLE_ZERO_BITS = Double.doubleToLongBits(0d);
protected Query getDocValuesRangeQuery(QParser parser, SchemaField field, String min, String max,
boolean minInclusive, boolean maxInclusive) {
@@ -89,50 +85,119 @@ public abstract class NumericFieldType extends PrimitiveFieldType {
protected Query getRangeQueryForFloatDoubleDocValues(SchemaField sf, String min, String max, boolean minInclusive, boolean maxInclusive) {
Query query;
String fieldName = sf.getName();
-
- Number minVal = min == null ? null : getNumberType() == NumberType.FLOAT ? parseFloatFromUser(sf.getName(), min): parseDoubleFromUser(sf.getName(), min);
- Number maxVal = max == null ? null : getNumberType() == NumberType.FLOAT ? parseFloatFromUser(sf.getName(), max): parseDoubleFromUser(sf.getName(), max);
-
- Long minBits =
- min == null ? null : getNumberType() == NumberType.FLOAT ? (long) Float.floatToIntBits(minVal.floatValue()): Double.doubleToLongBits(minVal.doubleValue());
- Long maxBits =
- max == null ? null : getNumberType() == NumberType.FLOAT ? (long) Float.floatToIntBits(maxVal.floatValue()): Double.doubleToLongBits(maxVal.doubleValue());
-
- long negativeInfinityBits = getNumberType() == NumberType.FLOAT ? FLOAT_NEGATIVE_INFINITY_BITS : DOUBLE_NEGATIVE_INFINITY_BITS;
- long positiveInfinityBits = getNumberType() == NumberType.FLOAT ? FLOAT_POSITIVE_INFINITY_BITS : DOUBLE_POSITIVE_INFINITY_BITS;
- long minusZeroBits = getNumberType() == NumberType.FLOAT ? FLOAT_MINUS_ZERO_BITS : DOUBLE_MINUS_ZERO_BITS;
- long zeroBits = getNumberType() == NumberType.FLOAT ? FLOAT_ZERO_BITS : DOUBLE_ZERO_BITS;
-
+ long minBits, maxBits;
+ boolean minNegative, maxNegative;
+ Number minVal, maxVal;
+ if (getNumberType() == NumberType.FLOAT) {
+ if (min == null) {
+ minVal = Float.NEGATIVE_INFINITY;
+ } else {
+ minVal = parseFloatFromUser(sf.getName(), min);
+ if (!minInclusive) {
+ if (minVal.floatValue() == Float.POSITIVE_INFINITY) return new MatchNoDocsQuery();
+ minVal = FloatPoint.nextUp(minVal.floatValue());
+ }
+ }
+ if (max == null) {
+ maxVal = Float.POSITIVE_INFINITY;
+ } else {
+ maxVal = parseFloatFromUser(sf.getName(), max);
+ if (!maxInclusive) {
+ if (maxVal.floatValue() == Float.NEGATIVE_INFINITY) return new MatchNoDocsQuery();
+ maxVal = FloatPoint.nextDown(maxVal.floatValue());
+ }
+ }
+ minBits = Float.floatToIntBits(minVal.floatValue());
+ maxBits = Float.floatToIntBits(maxVal.floatValue());
+ minNegative = minVal.floatValue() < 0f || minBits == FLOAT_MINUS_ZERO_BITS;
+ maxNegative = maxVal.floatValue() < 0f || maxBits == FLOAT_MINUS_ZERO_BITS;
+ } else {
+ assert getNumberType() == NumberType.DOUBLE;
+ if (min == null) {
+ minVal = Double.NEGATIVE_INFINITY;
+ } else {
+ minVal = parseDoubleFromUser(sf.getName(), min);
+ if (!minInclusive) {
+ if (minVal.doubleValue() == Double.POSITIVE_INFINITY) return new MatchNoDocsQuery();
+ minVal = DoublePoint.nextUp(minVal.doubleValue());
+ }
+ }
+ if (max == null) {
+ maxVal = Double.POSITIVE_INFINITY;
+ } else {
+ maxVal = parseDoubleFromUser(sf.getName(), max);
+ if (!maxInclusive) {
+ if (maxVal.doubleValue() == Double.NEGATIVE_INFINITY) return new MatchNoDocsQuery();
+ maxVal = DoublePoint.nextDown(maxVal.doubleValue());
+ }
+ }
+ minBits = Double.doubleToLongBits(minVal.doubleValue());
+ maxBits = Double.doubleToLongBits(maxVal.doubleValue());
+ minNegative = minVal.doubleValue() < 0d || minBits == DOUBLE_MINUS_ZERO_BITS;
+ maxNegative = maxVal.doubleValue() < 0d || maxBits == DOUBLE_MINUS_ZERO_BITS;
+ }
// If min is negative (or -0d) and max is positive (or +0d), then issue a FunctionRangeQuery
- if ((minVal == null || minVal.doubleValue() < 0d || minBits == minusZeroBits) &&
- (maxVal == null || (maxVal.doubleValue() > 0d || maxBits == zeroBits))) {
-
+ if (minNegative && !maxNegative) {
ValueSource vs = getValueSource(sf, null);
- query = new FunctionRangeQuery(new ValueSourceRangeFilter(vs, min, max, minInclusive, maxInclusive));
-
- } else { // If both max and min are negative (or -0d), then issue range query with max and min reversed
- if ((minVal == null || minVal.doubleValue() < 0d || minBits == minusZeroBits) &&
- (maxVal != null && (maxVal.doubleValue() < 0d || maxBits == minusZeroBits))) {
- query = numericDocValuesRangeQuery
- (fieldName, maxBits, (min == null ? Long.valueOf(negativeInfinityBits) : minBits), maxInclusive, minInclusive, false);
- } else { // If both max and min are positive, then issue range query
- query = numericDocValuesRangeQuery
- (fieldName, minBits, (max == null ? Long.valueOf(positiveInfinityBits) : maxBits), minInclusive, maxInclusive, false);
- }
+ query = new FunctionRangeQuery(new ValueSourceRangeFilter(vs, minVal.toString(), maxVal.toString(), true, true));
+ } else if (minNegative && maxNegative) {// If both max and min are negative (or -0d), then issue range query with max and min reversed
+ query = numericDocValuesRangeQuery
+ (fieldName, maxBits, minBits, true, true, false);
+ } else { // If both max and min are positive, then issue range query
+ query = numericDocValuesRangeQuery
+ (fieldName, minBits, maxBits, true, true, false);
}
return query;
}
-
+
protected Query getRangeQueryForMultiValuedDoubleDocValues(SchemaField sf, String min, String max, boolean minInclusive, boolean maxInclusive) {
- Long minBits = min == null ? NumericUtils.doubleToSortableLong(Double.NEGATIVE_INFINITY): NumericUtils.doubleToSortableLong(parseDoubleFromUser(sf.getName(), min));
- Long maxBits = max == null ? NumericUtils.doubleToSortableLong(Double.POSITIVE_INFINITY): NumericUtils.doubleToSortableLong(parseDoubleFromUser(sf.getName(), max));
- return numericDocValuesRangeQuery(sf.getName(), minBits, maxBits, minInclusive, maxInclusive, true);
+ double minVal,maxVal;
+ if (min == null) {
+ minVal = Double.NEGATIVE_INFINITY;
+ } else {
+ minVal = parseDoubleFromUser(sf.getName(), min);
+ if (!minInclusive) {
+ if (minVal == Double.POSITIVE_INFINITY) return new MatchNoDocsQuery();
+ minVal = DoublePoint.nextUp(minVal);
+ }
+ }
+ if (max == null) {
+ maxVal = Double.POSITIVE_INFINITY;
+ } else {
+ maxVal = parseDoubleFromUser(sf.getName(), max);
+ if (!maxInclusive) {
+ if (maxVal == Double.NEGATIVE_INFINITY) return new MatchNoDocsQuery();
+ maxVal = DoublePoint.nextDown(maxVal);
+ }
+ }
+ Long minBits = NumericUtils.doubleToSortableLong(minVal);
+ Long maxBits = NumericUtils.doubleToSortableLong(maxVal);
+ return numericDocValuesRangeQuery(sf.getName(), minBits, maxBits, true, true, true);
}
-
+
protected Query getRangeQueryForMultiValuedFloatDocValues(SchemaField sf, String min, String max, boolean minInclusive, boolean maxInclusive) {
- Long minBits = (long)(min == null ? NumericUtils.floatToSortableInt(Float.NEGATIVE_INFINITY): NumericUtils.floatToSortableInt(parseFloatFromUser(sf.getName(), min)));
- Long maxBits = (long)(max == null ? NumericUtils.floatToSortableInt(Float.POSITIVE_INFINITY): NumericUtils.floatToSortableInt(parseFloatFromUser(sf.getName(), max)));
- return numericDocValuesRangeQuery(sf.getName(), minBits, maxBits, minInclusive, maxInclusive, true);
+ float minVal,maxVal;
+ if (min == null) {
+ minVal = Float.NEGATIVE_INFINITY;
+ } else {
+ minVal = parseFloatFromUser(sf.getName(), min);
+ if (!minInclusive) {
+ if (minVal == Float.POSITIVE_INFINITY) return new MatchNoDocsQuery();
+ minVal = FloatPoint.nextUp(minVal);
+ }
+ }
+ if (max == null) {
+ maxVal = Float.POSITIVE_INFINITY;
+ } else {
+ maxVal = parseFloatFromUser(sf.getName(), max);
+ if (!maxInclusive) {
+ if (maxVal == Float.NEGATIVE_INFINITY) return new MatchNoDocsQuery();
+ maxVal = FloatPoint.nextDown(maxVal);
+ }
+ }
+ Long minBits = (long)NumericUtils.floatToSortableInt(minVal);
+ Long maxBits = (long)NumericUtils.floatToSortableInt(maxVal);
+ return numericDocValuesRangeQuery(sf.getName(), minBits, maxBits, true, true, true);
}
public static Query numericDocValuesRangeQuery(
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java
index 2a60343..8c93b52 100644
--- a/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java
+++ b/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java
@@ -25,12 +25,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import com.carrotsearch.hppc.FloatArrayList;
-import com.carrotsearch.hppc.IntArrayList;
-import com.carrotsearch.hppc.IntIntHashMap;
-import com.carrotsearch.hppc.IntLongHashMap;
-import com.carrotsearch.hppc.cursors.IntIntCursor;
-import com.carrotsearch.hppc.cursors.IntLongCursor;
import org.apache.commons.lang.StringUtils;
import org.apache.lucene.codecs.DocValuesProducer;
import org.apache.lucene.index.DocValues;
@@ -43,6 +37,7 @@ import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.MultiDocValues;
import org.apache.lucene.index.NumericDocValues;
+import org.apache.lucene.index.OrdinalMap;
import org.apache.lucene.index.SortedDocValues;
import org.apache.lucene.queries.function.FunctionQuery;
import org.apache.lucene.queries.function.FunctionValues;
@@ -69,10 +64,17 @@ import org.apache.solr.request.LocalSolrQueryRequest;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestInfo;
import org.apache.solr.schema.FieldType;
-import org.apache.solr.schema.StrField;
import org.apache.solr.schema.NumberType;
+import org.apache.solr.schema.StrField;
import org.apache.solr.uninverting.UninvertingReader;
+import com.carrotsearch.hppc.FloatArrayList;
+import com.carrotsearch.hppc.IntArrayList;
+import com.carrotsearch.hppc.IntIntHashMap;
+import com.carrotsearch.hppc.IntLongHashMap;
+import com.carrotsearch.hppc.cursors.IntIntCursor;
+import com.carrotsearch.hppc.cursors.IntLongCursor;
+
import static org.apache.solr.common.params.CommonParams.SORT;
/**
@@ -474,7 +476,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
private final DocValuesProducer collapseValuesProducer;
private FixedBitSet collapsedSet;
private SortedDocValues collapseValues;
- private MultiDocValues.OrdinalMap ordinalMap;
+ private OrdinalMap ordinalMap;
private SortedDocValues segmentValues;
private LongValues segmentOrdinalMap;
private MultiDocValues.MultiSortedDocValues multiSortedDocValues;
@@ -920,7 +922,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
private LeafReaderContext[] contexts;
private DocValuesProducer collapseValuesProducer;
private SortedDocValues collapseValues;
- protected MultiDocValues.OrdinalMap ordinalMap;
+ protected OrdinalMap ordinalMap;
protected SortedDocValues segmentValues;
protected LongValues segmentOrdinalMap;
protected MultiDocValues.MultiSortedDocValues multiSortedDocValues;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/search/facet/FacetFieldProcessorByArrayDV.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/facet/FacetFieldProcessorByArrayDV.java b/solr/core/src/java/org/apache/solr/search/facet/FacetFieldProcessorByArrayDV.java
index 1481f18..fe7a3f2 100644
--- a/solr/core/src/java/org/apache/solr/search/facet/FacetFieldProcessorByArrayDV.java
+++ b/solr/core/src/java/org/apache/solr/search/facet/FacetFieldProcessorByArrayDV.java
@@ -23,6 +23,7 @@ import java.util.List;
import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.MultiDocValues;
+import org.apache.lucene.index.OrdinalMap;
import org.apache.lucene.index.SortedDocValues;
import org.apache.lucene.index.SortedSetDocValues;
import org.apache.lucene.search.DocIdSet;
@@ -43,7 +44,7 @@ class FacetFieldProcessorByArrayDV extends FacetFieldProcessorByArray {
boolean multiValuedField;
SortedSetDocValues si; // only used for term lookups (for both single and multi-valued)
- MultiDocValues.OrdinalMap ordinalMap = null; // maps per-segment ords to global ords
+ OrdinalMap ordinalMap = null; // maps per-segment ords to global ords
FacetFieldProcessorByArrayDV(FacetContext fcontext, FacetField freq, SchemaField sf) {
super(fcontext, freq, sf);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/search/facet/MinMaxAgg.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/facet/MinMaxAgg.java b/solr/core/src/java/org/apache/solr/search/facet/MinMaxAgg.java
index 2c37863..a6d6b97 100644
--- a/solr/core/src/java/org/apache/solr/search/facet/MinMaxAgg.java
+++ b/solr/core/src/java/org/apache/solr/search/facet/MinMaxAgg.java
@@ -21,6 +21,7 @@ import java.util.Arrays;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.MultiDocValues;
+import org.apache.lucene.index.OrdinalMap;
import org.apache.lucene.index.SortedDocValues;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.util.BytesRef;
@@ -176,7 +177,7 @@ public class MinMaxAgg extends SimpleAggValueSource {
class SingleValuedOrdAcc extends OrdAcc {
SortedDocValues topLevel;
SortedDocValues[] subDvs;
- MultiDocValues.OrdinalMap ordMap;
+ OrdinalMap ordMap;
LongValues toGlobal;
SortedDocValues subDv;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/search/facet/UniqueAgg.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/facet/UniqueAgg.java b/solr/core/src/java/org/apache/solr/search/facet/UniqueAgg.java
index dba410a..4541975 100644
--- a/solr/core/src/java/org/apache/solr/search/facet/UniqueAgg.java
+++ b/solr/core/src/java/org/apache/solr/search/facet/UniqueAgg.java
@@ -29,6 +29,8 @@ import org.apache.lucene.index.SortedNumericDocValues;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.schema.SchemaField;
+import org.apache.solr.util.LongIterator;
+import org.apache.solr.util.LongSet;
public class UniqueAgg extends StrAggValueSource {
public static String UNIQUE = "unique";
@@ -122,75 +124,6 @@ public class UniqueAgg extends StrAggValueSource {
}
-
- static class LongSet {
-
- static final float LOAD_FACTOR = 0.7f;
-
- long[] vals;
- int cardinality;
- int mask;
- int threshold;
- int zeroCount; // 1 if a 0 was collected
-
- /** sz must be a power of two */
- LongSet(int sz) {
- vals = new long[sz];
- mask = sz - 1;
- threshold = (int) (sz * LOAD_FACTOR);
- }
-
- void add(long val) {
- if (val == 0) {
- zeroCount = 1;
- return;
- }
- if (cardinality >= threshold) {
- rehash();
- }
-
- // For floats: exponent bits start at bit 23 for single precision,
- // and bit 52 for double precision.
- // Many values will only have significant bits just to the right of that,
- // and the leftmost bits will all be zero.
-
- // For now, lets just settle to get first 8 significant mantissa bits of double or float in the lowest bits of our hash
- // The upper bits of our hash will be irrelevant.
- int h = (int) (val + (val >>> 44) + (val >>> 15));
- for (int slot = h & mask; ;slot = (slot + 1) & mask) {
- long v = vals[slot];
- if (v == 0) {
- vals[slot] = val;
- cardinality++;
- break;
- } else if (v == val) {
- // val is already in the set
- break;
- }
- }
- }
-
- private void rehash() {
- long[] oldVals = vals;
- int newCapacity = vals.length << 1;
- vals = new long[newCapacity];
- mask = newCapacity - 1;
- threshold = (int) (newCapacity * LOAD_FACTOR);
- cardinality = 0;
-
- for (long val : oldVals) {
- if (val != 0) {
- add(val);
- }
- }
- }
-
- int cardinality() {
- return cardinality + zeroCount;
- }
- }
-
-
static abstract class BaseNumericAcc extends SlotAcc {
SchemaField sf;
LongSet[] sets;
@@ -259,16 +192,11 @@ public class UniqueAgg extends StrAggValueSource {
if (unique <= maxExplicit) {
List lst = new ArrayList( Math.min(unique, maxExplicit) );
if (set != null) {
- if (set.zeroCount > 0) {
- lst.add(0);
- }
- for (long val : set.vals) {
- if (val != 0) {
- lst.add(val);
- }
+ LongIterator iter = set.iterator();
+ while (iter.hasNext()) {
+ lst.add( iter.next() );
}
}
-
map.add("vals", lst);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/search/facet/UniqueMultiDvSlotAcc.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/facet/UniqueMultiDvSlotAcc.java b/solr/core/src/java/org/apache/solr/search/facet/UniqueMultiDvSlotAcc.java
index 65fa81a..0a6eb22 100644
--- a/solr/core/src/java/org/apache/solr/search/facet/UniqueMultiDvSlotAcc.java
+++ b/solr/core/src/java/org/apache/solr/search/facet/UniqueMultiDvSlotAcc.java
@@ -21,6 +21,7 @@ import java.io.IOException;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.MultiDocValues;
+import org.apache.lucene.index.OrdinalMap;
import org.apache.lucene.index.SortedSetDocValues;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.FixedBitSet;
@@ -30,7 +31,7 @@ import org.apache.solr.schema.SchemaField;
class UniqueMultiDvSlotAcc extends UniqueSlotAcc {
SortedSetDocValues topLevel;
SortedSetDocValues[] subDvs;
- MultiDocValues.OrdinalMap ordMap;
+ OrdinalMap ordMap;
LongValues toGlobal;
SortedSetDocValues subDv;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/search/facet/UniqueSinglevaluedSlotAcc.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/facet/UniqueSinglevaluedSlotAcc.java b/solr/core/src/java/org/apache/solr/search/facet/UniqueSinglevaluedSlotAcc.java
index b39f282..434e680 100644
--- a/solr/core/src/java/org/apache/solr/search/facet/UniqueSinglevaluedSlotAcc.java
+++ b/solr/core/src/java/org/apache/solr/search/facet/UniqueSinglevaluedSlotAcc.java
@@ -21,6 +21,7 @@ import java.io.IOException;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.MultiDocValues;
+import org.apache.lucene.index.OrdinalMap;
import org.apache.lucene.index.SortedDocValues;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.FixedBitSet;
@@ -31,7 +32,7 @@ import org.apache.solr.search.SolrIndexSearcher;
class UniqueSinglevaluedSlotAcc extends UniqueSlotAcc {
SortedDocValues topLevel;
SortedDocValues[] subDvs;
- MultiDocValues.OrdinalMap ordMap;
+ OrdinalMap ordMap;
LongValues toGlobal;
SortedDocValues subDv;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/search/join/BlockJoinFieldFacetAccumulator.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/join/BlockJoinFieldFacetAccumulator.java b/solr/core/src/java/org/apache/solr/search/join/BlockJoinFieldFacetAccumulator.java
index 141b095..703307c 100644
--- a/solr/core/src/java/org/apache/solr/search/join/BlockJoinFieldFacetAccumulator.java
+++ b/solr/core/src/java/org/apache/solr/search/join/BlockJoinFieldFacetAccumulator.java
@@ -21,8 +21,8 @@ import java.util.Arrays;
import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.MultiDocValues.OrdinalMap;
import org.apache.lucene.index.MultiDocValues;
+import org.apache.lucene.index.OrdinalMap;
import org.apache.lucene.index.SortedDocValues;
import org.apache.lucene.index.SortedSetDocValues;
import org.apache.lucene.util.ArrayUtil;
@@ -50,7 +50,7 @@ class BlockJoinFieldFacetAccumulator {
// elems are : facet value counter<<32 | last parent doc num
private long[] segmentAccums = new long[0];
// for mapping per-segment ords to global ones
- private MultiDocValues.OrdinalMap ordinalMap;
+ private OrdinalMap ordinalMap;
private SchemaField schemaField;
private SortedDocValues segmentSDV;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/search/join/GraphQuery.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/join/GraphQuery.java b/solr/core/src/java/org/apache/solr/search/join/GraphQuery.java
index db41651..7e52f0c 100644
--- a/solr/core/src/java/org/apache/solr/search/join/GraphQuery.java
+++ b/solr/core/src/java/org/apache/solr/search/join/GraphQuery.java
@@ -25,16 +25,15 @@ import java.util.TreeSet;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.Term;
-import org.apache.lucene.search.AutomatonQuery;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.DocValuesFieldExistsQuery;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Scorer;
-import org.apache.lucene.search.TermInSetQuery;
import org.apache.lucene.search.Weight;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.util.BytesRef;
@@ -42,6 +41,7 @@ import org.apache.lucene.util.BytesRefHash;
import org.apache.lucene.util.FixedBitSet;
import org.apache.lucene.util.automaton.Automaton;
import org.apache.lucene.util.automaton.DaciukMihovAutomatonBuilder;
+import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.BitDocSet;
import org.apache.solr.search.DocSet;
import org.apache.solr.search.Filter;
@@ -130,17 +130,22 @@ public class GraphQuery extends Query {
protected class GraphQueryWeight extends Weight {
final SolrIndexSearcher fromSearcher;
- private final float boost;
- private int frontierSize = 0;
private int currentDepth = -1;
private Filter filter;
private DocSet resultSet;
-
+ SchemaField fromSchemaField;
+ SchemaField toSchemaField;
+
public GraphQueryWeight(SolrIndexSearcher searcher, float boost) {
// Grab the searcher so we can run additional searches.
super(null);
this.fromSearcher = searcher;
- this.boost = boost;
+ this.fromSchemaField = searcher.getSchema().getField(fromField);
+ this.toSchemaField = searcher.getSchema().getField(toField);
+ }
+
+ GraphQuery getGraphQuery() {
+ return GraphQuery.this;
}
@Override
@@ -175,7 +180,7 @@ public class GraphQuery extends Query {
// the initial query for the frontier for the first query
Query frontierQuery = q;
// Find all documents in this graph that are leaf nodes to speed traversal
- DocSet leafNodes = resolveLeafNodes(toField);
+ DocSet leafNodes = resolveLeafNodes();
// Start the breadth first graph traversal.
do {
@@ -187,25 +192,17 @@ public class GraphQuery extends Query {
// if we've reached the max depth, don't worry about collecting edges.
fromSet = fromSearcher.getDocSetBits(frontierQuery);
// explicitly the frontier size is zero now so we can break
- frontierSize = 0;
+ frontierQuery = null;
} else {
// when we're not at the max depth level, we need to collect edges
// Create the graph result collector for this level
- GraphTermsCollector graphResultCollector = new GraphTermsCollector(toField,capacity, resultBits, leafNodes);
+ GraphEdgeCollector graphResultCollector = toSchemaField.getType().isPointField()
+ ? new GraphPointsCollector(this, capacity, resultBits, leafNodes)
+ : new GraphTermsCollector(this, capacity, resultBits, leafNodes);
+
fromSearcher.search(frontierQuery, graphResultCollector);
fromSet = graphResultCollector.getDocSet();
- // All edge ids on the frontier.
- BytesRefHash collectorTerms = graphResultCollector.getCollectorTerms();
- frontierSize = collectorTerms.size();
- // The resulting doc set from the frontier.
- FrontierQuery fq = buildFrontierQuery(collectorTerms, frontierSize);
- if (fq == null) {
- // in case we get null back, make sure we know we're done at this level.
- frontierSize = 0;
- } else {
- frontierQuery = fq.getQuery();
- frontierSize = fq.getFrontierSize();
- }
+ frontierQuery = graphResultCollector.getFrontierQuery();
}
if (currentDepth == 0 && !returnRoot) {
// grab a copy of the root bits but only if we need it.
@@ -217,7 +214,7 @@ public class GraphQuery extends Query {
if ((maxDepth != -1 && currentDepth >= maxDepth)) {
break;
}
- } while (frontierSize > 0);
+ } while (frontierQuery != null);
// helper bit set operations on the final result set
if (!returnRoot) {
resultBits.andNot(rootBits);
@@ -232,9 +229,10 @@ public class GraphQuery extends Query {
}
}
- private DocSet resolveLeafNodes(String field) throws IOException {
+ private DocSet resolveLeafNodes() throws IOException {
+ String field = toSchemaField.getName();
BooleanQuery.Builder leafNodeQuery = new BooleanQuery.Builder();
- WildcardQuery edgeQuery = new WildcardQuery(new Term(field, "*"));
+ Query edgeQuery = toSchemaField.hasDocValues() ? new DocValuesFieldExistsQuery(field) : new WildcardQuery(new Term(field, "*"));
leafNodeQuery.add(edgeQuery, Occur.MUST_NOT);
DocSet leafNodes = fromSearcher.getDocSet(leafNodeQuery.build());
return leafNodes;
@@ -252,50 +250,7 @@ public class GraphQuery extends Query {
final Automaton a = DaciukMihovAutomatonBuilder.build(terms);
return a;
}
-
- /**
- * This return a query that represents the documents that match the next hop in the query.
- *
- * collectorTerms - the terms that represent the edge ids for the current frontier.
- * frontierSize - the size of the frontier query (number of unique edges)
- *
- */
- public FrontierQuery buildFrontierQuery(BytesRefHash collectorTerms, Integer frontierSize) {
- if (collectorTerms == null || collectorTerms.size() == 0) {
- // return null if there are no terms (edges) to traverse.
- return null;
- } else {
- // Create a query
- Query q = null;
- // TODO: see if we should dynamically select this based on the frontier size.
- if (useAutn) {
- // build an automaton based query for the frontier.
- Automaton autn = buildAutomaton(collectorTerms);
- AutomatonQuery autnQuery = new AutomatonQuery(new Term(fromField), autn);
- q = autnQuery;
- } else {
- List<BytesRef> termList = new ArrayList<>(collectorTerms.size());
- for (int i = 0 ; i < collectorTerms.size(); i++) {
- BytesRef ref = new BytesRef();
- collectorTerms.get(i, ref);
- termList.add(ref);
- }
- q = new TermInSetQuery(fromField, termList);
- }
-
- // If there is a filter to be used while crawling the graph, add that.
- if (traversalFilter != null) {
- BooleanQuery.Builder builder = new BooleanQuery.Builder();
- builder.add(q, Occur.MUST);
- builder.add(traversalFilter, Occur.MUST);
- q = builder.build();
- }
- // return the new query.
- FrontierQuery frontier = new FrontierQuery(q, frontierSize);
- return frontier;
- }
- }
@Override
public Scorer scorer(LeafReaderContext context) throws IOException {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/search/join/GraphQueryParser.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/join/GraphQueryParser.java b/solr/core/src/java/org/apache/solr/search/join/GraphQueryParser.java
index 0ef9e6c..9c9b852 100644
--- a/solr/core/src/java/org/apache/solr/search/join/GraphQueryParser.java
+++ b/solr/core/src/java/org/apache/solr/search/join/GraphQueryParser.java
@@ -41,6 +41,7 @@ public class GraphQueryParser extends QParser {
String traversalFilterS = localParams.get("traversalFilter");
Query traversalFilter = traversalFilterS == null ? null : subQuery(traversalFilterS, null).getQuery();
+ // NOTE: the from/to are reversed from {!join}
String fromField = localParams.get("from", "node_id");
String toField = localParams.get("to", "edge_ids");
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8d00e53b/solr/core/src/java/org/apache/solr/search/join/GraphTermsCollector.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/join/GraphTermsCollector.java b/solr/core/src/java/org/apache/solr/search/join/GraphTermsCollector.java
index 377f71b..f32c83b 100644
--- a/solr/core/src/java/org/apache/solr/search/join/GraphTermsCollector.java
+++ b/solr/core/src/java/org/apache/solr/search/join/GraphTermsCollector.java
@@ -17,19 +17,40 @@
package org.apache.solr.search.join;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.TreeSet;
+import org.apache.lucene.document.DoublePoint;
+import org.apache.lucene.document.FloatPoint;
+import org.apache.lucene.document.IntPoint;
+import org.apache.lucene.document.LongPoint;
import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.SortedNumericDocValues;
import org.apache.lucene.index.SortedSetDocValues;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.AutomatonQuery;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Collector;
+import org.apache.lucene.search.Query;
import org.apache.lucene.search.SimpleCollector;
+import org.apache.lucene.search.TermInSetQuery;
import org.apache.lucene.util.BitSet;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefHash;
import org.apache.lucene.util.FixedBitSet;
+import org.apache.lucene.util.NumericUtils;
+import org.apache.lucene.util.automaton.Automaton;
+import org.apache.lucene.util.automaton.DaciukMihovAutomatonBuilder;
+import org.apache.solr.schema.NumberType;
+import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.BitDocSet;
import org.apache.solr.search.DocSet;
+import org.apache.solr.util.LongIterator;
+import org.apache.solr.util.LongSet;
/**
* A graph hit collector. This accumulates the edges for a given graph traversal.
@@ -37,17 +58,14 @@ import org.apache.solr.search.DocSet;
* already traversed.
* @lucene.internal
*/
-class GraphTermsCollector extends SimpleCollector implements Collector {
-
- // the field to collect edge ids from
- private String field;
- // all the collected terms
- private BytesRefHash collectorTerms;
- private SortedSetDocValues docTermOrds;
+abstract class GraphEdgeCollector extends SimpleCollector implements Collector {
+
+ GraphQuery.GraphQueryWeight weight;
+
// the result set that is being collected.
- private Bits currentResult;
+ Bits currentResult;
// known leaf nodes
- private DocSet leafNodes;
+ DocSet leafNodes;
// number of hits discovered at this level.
int numHits=0;
BitSet bits;
@@ -56,11 +74,10 @@ class GraphTermsCollector extends SimpleCollector implements Collector {
int baseInParent;
// if we care to track this.
boolean hasCycles = false;
-
- GraphTermsCollector(String field,int maxDoc, Bits currentResult, DocSet leafNodes) {
- this.field = field;
+
+ GraphEdgeCollector(GraphQuery.GraphQueryWeight weight, int maxDoc, Bits currentResult, DocSet leafNodes) {
+ this.weight = weight;
this.maxDoc = maxDoc;
- this.collectorTerms = new BytesRefHash();
this.currentResult = currentResult;
this.leafNodes = leafNodes;
if (bits==null) {
@@ -80,29 +97,14 @@ class GraphTermsCollector extends SimpleCollector implements Collector {
// collect the docs
addDocToResult(doc);
// Optimization to not look up edges for a document that is a leaf node
- if (!leafNodes.exists(doc)) {
+ if (leafNodes == null || !leafNodes.exists(doc)) {
addEdgeIdsToResult(doc-base);
}
// Note: tracking links in for each result would be a huge memory hog... so not implementing at this time.
}
- private void addEdgeIdsToResult(int doc) throws IOException {
- // set the doc to pull the edges ids for.
- if (doc > docTermOrds.docID()) {
- docTermOrds.advance(doc);
- }
- if (doc == docTermOrds.docID()) {
- BytesRef edgeValue = new BytesRef();
- long ord;
- while ((ord = docTermOrds.nextOrd()) != SortedSetDocValues.NO_MORE_ORDS) {
- // TODO: handle non string type fields.
- edgeValue = docTermOrds.lookupOrd(ord);
- // add the edge id to the collector terms.
- collectorTerms.add(edgeValue);
- }
- }
- }
+ abstract void addEdgeIdsToResult(int doc) throws IOException;
private void addDocToResult(int docWithBase) {
// this document is part of the traversal. mark it in our bitmap.
@@ -121,14 +123,25 @@ class GraphTermsCollector extends SimpleCollector implements Collector {
@Override
public void doSetNextReader(LeafReaderContext context) throws IOException {
- // Grab the updated doc values.
- docTermOrds = DocValues.getSortedSet(context.reader(), field);
base = context.docBase;
baseInParent = context.docBaseInParent;
}
-
- public BytesRefHash getCollectorTerms() {
- return collectorTerms;
+
+ protected abstract Query getResultQuery();
+
+ public Query getFrontierQuery() {
+ Query q = getResultQuery();
+ if (q == null) return null;
+
+ // If there is a filter to be used while crawling the graph, add that.
+ if (weight.getGraphQuery().getTraversalFilter() != null) {
+ BooleanQuery.Builder builder = new BooleanQuery.Builder();
+ builder.add(q, BooleanClause.Occur.MUST);
+ builder.add(weight.getGraphQuery().getTraversalFilter(), BooleanClause.Occur.MUST);
+ q = builder.build();
+ }
+
+ return q;
}
@Override
@@ -137,3 +150,180 @@ class GraphTermsCollector extends SimpleCollector implements Collector {
}
}
+
+class GraphTermsCollector extends GraphEdgeCollector {
+ // all the collected terms
+ private BytesRefHash collectorTerms;
+ private SortedSetDocValues docTermOrds;
+
+
+ GraphTermsCollector(GraphQuery.GraphQueryWeight weight, int maxDoc, Bits currentResult, DocSet leafNodes) {
+ super(weight, maxDoc, currentResult, leafNodes);
+ this.collectorTerms = new BytesRefHash();
+ }
+
+ @Override
+ public void doSetNextReader(LeafReaderContext context) throws IOException {
+ super.doSetNextReader(context);
+ // Grab the updated doc values.
+ docTermOrds = DocValues.getSortedSet(context.reader(), weight.getGraphQuery().getToField());
+ }
+
+ @Override
+ void addEdgeIdsToResult(int doc) throws IOException {
+ // set the doc to pull the edges ids for.
+ if (doc > docTermOrds.docID()) {
+ docTermOrds.advance(doc);
+ }
+ if (doc == docTermOrds.docID()) {
+ BytesRef edgeValue = new BytesRef();
+ long ord;
+ while ((ord = docTermOrds.nextOrd()) != SortedSetDocValues.NO_MORE_ORDS) {
+ edgeValue = docTermOrds.lookupOrd(ord);
+ // add the edge id to the collector terms.
+ collectorTerms.add(edgeValue);
+ }
+ }
+ }
+
+ @Override
+ protected Query getResultQuery() {
+ if (collectorTerms == null || collectorTerms.size() == 0) {
+ // return null if there are no terms (edges) to traverse.
+ return null;
+ } else {
+ // Create a query
+ Query q = null;
+
+ GraphQuery gq = weight.getGraphQuery();
+ // TODO: see if we should dynamically select this based on the frontier size.
+ if (gq.isUseAutn()) {
+ // build an automaton based query for the frontier.
+ Automaton autn = buildAutomaton(collectorTerms);
+ AutomatonQuery autnQuery = new AutomatonQuery(new Term(gq.getFromField()), autn);
+ q = autnQuery;
+ } else {
+ List<BytesRef> termList = new ArrayList<>(collectorTerms.size());
+ for (int i = 0 ; i < collectorTerms.size(); i++) {
+ BytesRef ref = new BytesRef();
+ collectorTerms.get(i, ref);
+ termList.add(ref);
+ }
+ q = new TermInSetQuery(gq.getFromField(), termList);
+ }
+
+ return q;
+ }
+ }
+
+
+ /** Build an automaton to represent the frontier query */
+ private Automaton buildAutomaton(BytesRefHash termBytesHash) {
+ // need top pass a sorted set of terms to the autn builder (maybe a better way to avoid this?)
+ final TreeSet<BytesRef> terms = new TreeSet<BytesRef>();
+ for (int i = 0 ; i < termBytesHash.size(); i++) {
+ BytesRef ref = new BytesRef();
+ termBytesHash.get(i, ref);
+ terms.add(ref);
+ }
+ final Automaton a = DaciukMihovAutomatonBuilder.build(terms);
+ return a;
+ }
+}
+
+
+class GraphPointsCollector extends GraphEdgeCollector {
+ final LongSet set = new LongSet(256);
+
+ SortedNumericDocValues values = null;
+
+ GraphPointsCollector(GraphQuery.GraphQueryWeight weight, int maxDoc, Bits currentResult, DocSet leafNodes) {
+ super(weight, maxDoc, currentResult, leafNodes);
+ }
+
+ @Override
+ public void doSetNextReader(LeafReaderContext context) throws IOException {
+ super.doSetNextReader(context);
+ values = DocValues.getSortedNumeric(context.reader(), weight.getGraphQuery().getToField());
+ }
+
+ @Override
+ void addEdgeIdsToResult(int doc) throws IOException {
+ // set the doc to pull the edges ids for.
+ int valuesDoc = values.docID();
+ if (valuesDoc < doc) {
+ valuesDoc = values.advance(doc);
+ }
+ if (valuesDoc == doc) {
+ int count = values.docValueCount();
+ for (int i = 0; i < count; i++) {
+ long v = values.nextValue();
+ set.add(v);
+ }
+ }
+ }
+
+ @Override
+ protected Query getResultQuery() {
+ if (set.cardinality() == 0) return null;
+
+ Query q = null;
+ SchemaField sfield = weight.fromSchemaField;
+ NumberType ntype = sfield.getType().getNumberType();
+ boolean multiValued = sfield.multiValued();
+
+ if (ntype == NumberType.LONG || ntype == NumberType.DATE) {
+ long[] vals = new long[set.cardinality()];
+ int i = 0;
+ for (LongIterator iter = set.iterator(); iter.hasNext(); ) {
+ long bits = iter.next();
+ long v = bits;
+ vals[i++] = v;
+ }
+ q = LongPoint.newSetQuery(sfield.getName(), vals);
+ } else if (ntype == NumberType.INTEGER) {
+ int[] vals = new int[set.cardinality()];
+ int i = 0;
+ for (LongIterator iter = set.iterator(); iter.hasNext(); ) {
+ long bits = iter.next();
+ int v = (int)bits;
+ vals[i++] = v;
+ }
+ q = IntPoint.newSetQuery(sfield.getName(), vals);
+ } else if (ntype == NumberType.DOUBLE) {
+ double[] vals = new double[set.cardinality()];
+ int i = 0;
+ for (LongIterator iter = set.iterator(); iter.hasNext(); ) {
+ long bits = iter.next();
+ double v = multiValued ? NumericUtils.sortableLongToDouble(bits) : Double.longBitsToDouble(bits);
+ vals[i++] = v;
+ }
+ q = DoublePoint.newSetQuery(sfield.getName(), vals);
+ } else if (ntype == NumberType.FLOAT) {
+ float[] vals = new float[set.cardinality()];
+ int i = 0;
+ for (LongIterator iter = set.iterator(); iter.hasNext(); ) {
+ long bits = iter.next();
+ float v = multiValued ? NumericUtils.sortableIntToFloat((int) bits) : Float.intBitsToFloat((int) bits);
+ vals[i++] = v;
+ }
+ q = FloatPoint.newSetQuery(sfield.getName(), vals);
+ }
+
+ return q;
+ }
+
+
+ /** Build an automaton to represent the frontier query */
+ private Automaton buildAutomaton(BytesRefHash termBytesHash) {
+ // need top pass a sorted set of terms to the autn builder (maybe a better way to avoid this?)
+ final TreeSet<BytesRef> terms = new TreeSet<BytesRef>();
+ for (int i = 0 ; i < termBytesHash.size(); i++) {
+ BytesRef ref = new BytesRef();
+ termBytesHash.get(i, ref);
+ terms.add(ref);
+ }
+ final Automaton a = DaciukMihovAutomatonBuilder.build(terms);
+ return a;
+ }
+}