mirror of https://github.com/apache/lucene.git
LUCENE-7089, LUCENE-7075: add points to flexible queryparser to replace legacy numerics support
This commit is contained in:
parent
f24810bdf1
commit
89cc676f2b
|
@ -52,14 +52,14 @@
|
|||
* <li>FuzzyQueryNode - fuzzy node</li>
|
||||
* <li>TermRangeQueryNode - used for parametric field:[low_value TO high_value]</li>
|
||||
* <li>ProximityQueryNode - used for proximity search</li>
|
||||
* <li>NumericRangeQueryNode - used for numeric range search</li>
|
||||
* <li>LegacyNumericRangeQueryNode - used for numeric range search</li>
|
||||
* <li>TokenizedPhraseQueryNode - used by tokenizers/lemmatizers/analyzers for phrases/autophrases</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Leaf Nodes:
|
||||
* <ul>
|
||||
* <li>FieldQueryNode - field/value node</li>
|
||||
* <li>NumericQueryNode - used for numeric search</li>
|
||||
* <li>LegacyNumericQueryNode - used for numeric search</li>
|
||||
* <li>PathQueryNode - {@link org.apache.lucene.queryparser.flexible.core.nodes.QueryNode} object used with path-like queries</li>
|
||||
* <li>OpaqueQueryNode - Used as for part of the query that can be parsed by other parsers. schema/value</li>
|
||||
* <li>PrefixWildcardQueryNode - non-phrase wildcard query</li>
|
||||
|
|
|
@ -29,7 +29,8 @@ import org.apache.lucene.queryparser.flexible.core.QueryParserHelper;
|
|||
import org.apache.lucene.queryparser.flexible.core.config.QueryConfigHandler;
|
||||
import org.apache.lucene.queryparser.flexible.standard.builders.StandardQueryTreeBuilder;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.FuzzyConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.NumericConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.LegacyNumericConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.PointsConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.Operator;
|
||||
|
@ -322,12 +323,30 @@ public class StandardQueryParser extends QueryParserHelper implements CommonQuer
|
|||
|
||||
}
|
||||
|
||||
public void setNumericConfigMap(Map<String,NumericConfig> numericConfigMap) {
|
||||
getQueryConfigHandler().set(ConfigurationKeys.NUMERIC_CONFIG_MAP, numericConfigMap);
|
||||
/**
|
||||
* Sets field configuration for legacy numeric fields
|
||||
* @deprecated Index with points instead and use {@link #setPointsConfigMap(Map)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void setLegacyNumericConfigMap(Map<String,LegacyNumericConfig> legacyNumericConfigMap) {
|
||||
getQueryConfigHandler().set(ConfigurationKeys.LEGACY_NUMERIC_CONFIG_MAP, legacyNumericConfigMap);
|
||||
}
|
||||
|
||||
public Map<String,NumericConfig> getNumericConfigMap() {
|
||||
return getQueryConfigHandler().get(ConfigurationKeys.NUMERIC_CONFIG_MAP);
|
||||
/**
|
||||
* Gets field configuration for legacy numeric fields
|
||||
* @deprecated Index with points instead and use {@link #getPointsConfigMap()}
|
||||
*/
|
||||
@Deprecated
|
||||
public Map<String,LegacyNumericConfig> getLegacyNumericConfigMap() {
|
||||
return getQueryConfigHandler().get(ConfigurationKeys.LEGACY_NUMERIC_CONFIG_MAP);
|
||||
}
|
||||
|
||||
public void setPointsConfigMap(Map<String,PointsConfig> pointsConfigMap) {
|
||||
getQueryConfigHandler().set(ConfigurationKeys.POINTS_CONFIG_MAP, pointsConfigMap);
|
||||
}
|
||||
|
||||
public Map<String,PointsConfig> getPointsConfigMap() {
|
||||
return getQueryConfigHandler().get(ConfigurationKeys.POINTS_CONFIG_MAP);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,38 +22,40 @@ import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages;
|
|||
import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.core.util.StringUtils;
|
||||
import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.NumericConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.NumericQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.NumericRangeQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.LegacyNumericConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.LegacyNumericQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.LegacyNumericRangeQueryNode;
|
||||
import org.apache.lucene.search.LegacyNumericRangeQuery;
|
||||
|
||||
/**
|
||||
* Builds {@link org.apache.lucene.search.LegacyNumericRangeQuery}s out of {@link NumericRangeQueryNode}s.
|
||||
* Builds {@link org.apache.lucene.search.LegacyNumericRangeQuery}s out of {@link LegacyNumericRangeQueryNode}s.
|
||||
*
|
||||
* @see org.apache.lucene.search.LegacyNumericRangeQuery
|
||||
* @see NumericRangeQueryNode
|
||||
* @see LegacyNumericRangeQueryNode
|
||||
* @deprecated Index with points and use {@link PointRangeQueryNodeBuilder} instead.
|
||||
*/
|
||||
public class NumericRangeQueryNodeBuilder implements StandardQueryBuilder {
|
||||
@Deprecated
|
||||
public class LegacyNumericRangeQueryNodeBuilder implements StandardQueryBuilder {
|
||||
|
||||
/**
|
||||
* Constructs a {@link NumericRangeQueryNodeBuilder} object.
|
||||
* Constructs a {@link LegacyNumericRangeQueryNodeBuilder} object.
|
||||
*/
|
||||
public NumericRangeQueryNodeBuilder() {
|
||||
public LegacyNumericRangeQueryNodeBuilder() {
|
||||
// empty constructor
|
||||
}
|
||||
|
||||
@Override
|
||||
public LegacyNumericRangeQuery<? extends Number> build(QueryNode queryNode)
|
||||
throws QueryNodeException {
|
||||
NumericRangeQueryNode numericRangeNode = (NumericRangeQueryNode) queryNode;
|
||||
LegacyNumericRangeQueryNode numericRangeNode = (LegacyNumericRangeQueryNode) queryNode;
|
||||
|
||||
NumericQueryNode lowerNumericNode = numericRangeNode.getLowerBound();
|
||||
NumericQueryNode upperNumericNode = numericRangeNode.getUpperBound();
|
||||
LegacyNumericQueryNode lowerNumericNode = numericRangeNode.getLowerBound();
|
||||
LegacyNumericQueryNode upperNumericNode = numericRangeNode.getUpperBound();
|
||||
|
||||
Number lowerNumber = lowerNumericNode.getValue();
|
||||
Number upperNumber = upperNumericNode.getValue();
|
||||
|
||||
NumericConfig numericConfig = numericRangeNode.getNumericConfig();
|
||||
LegacyNumericConfig numericConfig = numericRangeNode.getNumericConfig();
|
||||
FieldType.LegacyNumericType numberType = numericConfig.getType();
|
||||
String field = StringUtils.toString(numericRangeNode.getField());
|
||||
boolean minInclusive = numericRangeNode.isLowerInclusive();
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.lucene.queryparser.flexible.standard.builders;
|
||||
|
||||
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.PointValues;
|
||||
import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
|
||||
import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages;
|
||||
import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.core.util.StringUtils;
|
||||
import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.PointsConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.PointQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.PointRangeQueryNode;
|
||||
import org.apache.lucene.search.Query;
|
||||
|
||||
/**
|
||||
* Builds {@link PointValues} range queries out of {@link PointRangeQueryNode}s.
|
||||
*
|
||||
* @see PointRangeQueryNode
|
||||
*/
|
||||
public class PointRangeQueryNodeBuilder implements StandardQueryBuilder {
|
||||
|
||||
/**
|
||||
* Constructs a {@link PointRangeQueryNodeBuilder} object.
|
||||
*/
|
||||
public PointRangeQueryNodeBuilder() {
|
||||
// empty constructor
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query build(QueryNode queryNode) throws QueryNodeException {
|
||||
PointRangeQueryNode numericRangeNode = (PointRangeQueryNode) queryNode;
|
||||
|
||||
PointQueryNode lowerNumericNode = numericRangeNode.getLowerBound();
|
||||
PointQueryNode upperNumericNode = numericRangeNode.getUpperBound();
|
||||
|
||||
Number lowerNumber = lowerNumericNode.getValue();
|
||||
Number upperNumber = upperNumericNode.getValue();
|
||||
|
||||
PointsConfig pointsConfig = numericRangeNode.getPointsConfig();
|
||||
Class<? extends Number> numberType = pointsConfig.getType();
|
||||
String field = StringUtils.toString(numericRangeNode.getField());
|
||||
boolean minInclusive = numericRangeNode.isLowerInclusive();
|
||||
boolean maxInclusive = numericRangeNode.isUpperInclusive();
|
||||
|
||||
// TODO: push down cleaning up of crazy nulls and inclusive/exclusive elsewhere
|
||||
if (Integer.class.equals(numberType)) {
|
||||
Integer lower = (Integer) lowerNumber;
|
||||
if (lower == null) {
|
||||
lower = Integer.MIN_VALUE;
|
||||
}
|
||||
if (minInclusive == false) {
|
||||
lower = lower + 1;
|
||||
}
|
||||
|
||||
Integer upper = (Integer) upperNumber;
|
||||
if (upper == null) {
|
||||
upper = Integer.MAX_VALUE;
|
||||
}
|
||||
if (maxInclusive == false) {
|
||||
upper = upper - 1;
|
||||
}
|
||||
return IntPoint.newRangeQuery(field, lower, upper);
|
||||
} else if (Long.class.equals(numberType)) {
|
||||
Long lower = (Long) lowerNumber;
|
||||
if (lower == null) {
|
||||
lower = Long.MIN_VALUE;
|
||||
}
|
||||
if (minInclusive == false) {
|
||||
lower = lower + 1;
|
||||
}
|
||||
|
||||
Long upper = (Long) upperNumber;
|
||||
if (upper == null) {
|
||||
upper = Long.MAX_VALUE;
|
||||
}
|
||||
if (maxInclusive == false) {
|
||||
upper = upper - 1;
|
||||
}
|
||||
return LongPoint.newRangeQuery(field, lower, upper);
|
||||
} else if (Float.class.equals(numberType)) {
|
||||
Float lower = (Float) lowerNumber;
|
||||
if (lower == null) {
|
||||
lower = Float.NEGATIVE_INFINITY;
|
||||
}
|
||||
if (minInclusive == false) {
|
||||
lower = Math.nextUp(lower);
|
||||
}
|
||||
|
||||
Float upper = (Float) upperNumber;
|
||||
if (upper == null) {
|
||||
upper = Float.POSITIVE_INFINITY;
|
||||
}
|
||||
if (maxInclusive == false) {
|
||||
upper = Math.nextDown(upper);
|
||||
}
|
||||
return FloatPoint.newRangeQuery(field, lower, upper);
|
||||
} else if (Double.class.equals(numberType)) {
|
||||
Double lower = (Double) lowerNumber;
|
||||
if (lower == null) {
|
||||
lower = Double.NEGATIVE_INFINITY;
|
||||
}
|
||||
if (minInclusive == false) {
|
||||
lower = Math.nextUp(lower);
|
||||
}
|
||||
|
||||
Double upper = (Double) upperNumber;
|
||||
if (upper == null) {
|
||||
upper = Double.POSITIVE_INFINITY;
|
||||
}
|
||||
if (maxInclusive == false) {
|
||||
upper = Math.nextDown(upper);
|
||||
}
|
||||
return DoublePoint.newRangeQuery(field, lower, upper);
|
||||
} else {
|
||||
throw new QueryNodeException(new MessageImpl(QueryParserMessages.UNSUPPORTED_NUMERIC_DATA_TYPE, numberType));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,8 +30,10 @@ import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
|
|||
import org.apache.lucene.queryparser.flexible.core.nodes.SlopQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.core.nodes.TokenizedPhraseQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.MultiPhraseQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.NumericQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.NumericRangeQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.PointQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.PointRangeQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.LegacyNumericQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.LegacyNumericRangeQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.PrefixWildcardQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.TermRangeQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.RegexpQueryNode;
|
||||
|
@ -57,8 +59,10 @@ public class StandardQueryTreeBuilder extends QueryTreeBuilder implements
|
|||
setBuilder(FieldQueryNode.class, new FieldQueryNodeBuilder());
|
||||
setBuilder(BooleanQueryNode.class, new BooleanQueryNodeBuilder());
|
||||
setBuilder(FuzzyQueryNode.class, new FuzzyQueryNodeBuilder());
|
||||
setBuilder(NumericQueryNode.class, new DummyQueryNodeBuilder());
|
||||
setBuilder(NumericRangeQueryNode.class, new NumericRangeQueryNodeBuilder());
|
||||
setBuilder(LegacyNumericQueryNode.class, new DummyQueryNodeBuilder());
|
||||
setBuilder(LegacyNumericRangeQueryNode.class, new LegacyNumericRangeQueryNodeBuilder());
|
||||
setBuilder(PointQueryNode.class, new DummyQueryNodeBuilder());
|
||||
setBuilder(PointRangeQueryNode.class, new PointRangeQueryNodeBuilder());
|
||||
setBuilder(BoostQueryNode.class, new BoostQueryNodeBuilder());
|
||||
setBuilder(ModifierQueryNode.class, new ModifierQueryNodeBuilder());
|
||||
setBuilder(WildcardQueryNode.class, new WildcardQueryNodeBuilder());
|
||||
|
|
|
@ -28,8 +28,10 @@ import org.apache.lucene.document.FieldType.LegacyNumericType;
|
|||
*
|
||||
* @see org.apache.lucene.search.LegacyNumericRangeQuery
|
||||
* @see NumberFormat
|
||||
* @deprecated Index with Points instead and use {@link PointsConfig}
|
||||
*/
|
||||
public class NumericConfig {
|
||||
@Deprecated
|
||||
public class LegacyNumericConfig {
|
||||
|
||||
private int precisionStep;
|
||||
|
||||
|
@ -38,7 +40,7 @@ public class NumericConfig {
|
|||
private FieldType.LegacyNumericType type;
|
||||
|
||||
/**
|
||||
* Constructs a {@link NumericConfig} object.
|
||||
* Constructs a {@link LegacyNumericConfig} object.
|
||||
*
|
||||
* @param precisionStep
|
||||
* the precision used to index the numeric values
|
||||
|
@ -48,11 +50,11 @@ public class NumericConfig {
|
|||
* @param type
|
||||
* the numeric type used to index the numeric values
|
||||
*
|
||||
* @see NumericConfig#setPrecisionStep(int)
|
||||
* @see NumericConfig#setNumberFormat(NumberFormat)
|
||||
* @see LegacyNumericConfig#setPrecisionStep(int)
|
||||
* @see LegacyNumericConfig#setNumberFormat(NumberFormat)
|
||||
* @see #setType(org.apache.lucene.document.FieldType.LegacyNumericType)
|
||||
*/
|
||||
public NumericConfig(int precisionStep, NumberFormat format,
|
||||
public LegacyNumericConfig(int precisionStep, NumberFormat format,
|
||||
LegacyNumericType type) {
|
||||
setPrecisionStep(precisionStep);
|
||||
setNumberFormat(format);
|
||||
|
@ -141,8 +143,8 @@ public class NumericConfig {
|
|||
|
||||
if (obj == this) return true;
|
||||
|
||||
if (obj instanceof NumericConfig) {
|
||||
NumericConfig other = (NumericConfig) obj;
|
||||
if (obj instanceof LegacyNumericConfig) {
|
||||
LegacyNumericConfig other = (LegacyNumericConfig) obj;
|
||||
|
||||
if (this.precisionStep == other.precisionStep
|
||||
&& this.type == other.type
|
|
@ -25,25 +25,27 @@ import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfi
|
|||
|
||||
/**
|
||||
* This listener is used to listen to {@link FieldConfig} requests in
|
||||
* {@link QueryConfigHandler} and add {@link ConfigurationKeys#NUMERIC_CONFIG}
|
||||
* based on the {@link ConfigurationKeys#NUMERIC_CONFIG_MAP} set in the
|
||||
* {@link QueryConfigHandler} and add {@link ConfigurationKeys#LEGACY_NUMERIC_CONFIG}
|
||||
* based on the {@link ConfigurationKeys#LEGACY_NUMERIC_CONFIG_MAP} set in the
|
||||
* {@link QueryConfigHandler}.
|
||||
*
|
||||
* @see NumericConfig
|
||||
* @see LegacyNumericConfig
|
||||
* @see QueryConfigHandler
|
||||
* @see ConfigurationKeys#NUMERIC_CONFIG
|
||||
* @see ConfigurationKeys#NUMERIC_CONFIG_MAP
|
||||
* @see ConfigurationKeys#LEGACY_NUMERIC_CONFIG
|
||||
* @see ConfigurationKeys#LEGACY_NUMERIC_CONFIG_MAP
|
||||
* @deprecated Index with Points instead and use {@link PointsConfigListener}
|
||||
*/
|
||||
public class NumericFieldConfigListener implements FieldConfigListener {
|
||||
@Deprecated
|
||||
public class LegacyNumericFieldConfigListener implements FieldConfigListener {
|
||||
|
||||
final private QueryConfigHandler config;
|
||||
|
||||
/**
|
||||
* Construcs a {@link NumericFieldConfigListener} object using the given {@link QueryConfigHandler}.
|
||||
* Constructs a {@link LegacyNumericFieldConfigListener} object using the given {@link QueryConfigHandler}.
|
||||
*
|
||||
* @param config the {@link QueryConfigHandler} it will listen too
|
||||
*/
|
||||
public NumericFieldConfigListener(QueryConfigHandler config) {
|
||||
public LegacyNumericFieldConfigListener(QueryConfigHandler config) {
|
||||
|
||||
if (config == null) {
|
||||
throw new IllegalArgumentException("config cannot be null!");
|
||||
|
@ -55,15 +57,15 @@ public class NumericFieldConfigListener implements FieldConfigListener {
|
|||
|
||||
@Override
|
||||
public void buildFieldConfig(FieldConfig fieldConfig) {
|
||||
Map<String,NumericConfig> numericConfigMap = config
|
||||
.get(ConfigurationKeys.NUMERIC_CONFIG_MAP);
|
||||
Map<String,LegacyNumericConfig> numericConfigMap = config
|
||||
.get(ConfigurationKeys.LEGACY_NUMERIC_CONFIG_MAP);
|
||||
|
||||
if (numericConfigMap != null) {
|
||||
NumericConfig numericConfig = numericConfigMap
|
||||
LegacyNumericConfig numericConfig = numericConfigMap
|
||||
.get(fieldConfig.getField());
|
||||
|
||||
if (numericConfig != null) {
|
||||
fieldConfig.set(ConfigurationKeys.NUMERIC_CONFIG, numericConfig);
|
||||
fieldConfig.set(ConfigurationKeys.LEGACY_NUMERIC_CONFIG, numericConfig);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.lucene.queryparser.flexible.standard.config;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
|
||||
import org.apache.lucene.index.PointValues;
|
||||
|
||||
/**
|
||||
* This class holds the configuration used to parse numeric queries and create
|
||||
* {@link PointValues} queries.
|
||||
*
|
||||
* @see PointValues
|
||||
* @see NumberFormat
|
||||
*/
|
||||
public class PointsConfig {
|
||||
|
||||
private NumberFormat format;
|
||||
|
||||
private Class<? extends Number> type;
|
||||
|
||||
/**
|
||||
* Constructs a {@link PointsConfig} object.
|
||||
*
|
||||
* @param format
|
||||
* the {@link NumberFormat} used to parse a {@link String} to
|
||||
* {@link Number}
|
||||
* @param type
|
||||
* the numeric type used to index the numeric values
|
||||
*
|
||||
* @see PointsConfig#setNumberFormat(NumberFormat)
|
||||
*/
|
||||
public PointsConfig(NumberFormat format, Class<? extends Number> type) {
|
||||
setNumberFormat(format);
|
||||
setType(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link NumberFormat} used to parse a {@link String} to
|
||||
* {@link Number}
|
||||
*
|
||||
* @return the {@link NumberFormat} used to parse a {@link String} to
|
||||
* {@link Number}
|
||||
*/
|
||||
public NumberFormat getNumberFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the numeric type used to index the numeric values
|
||||
*
|
||||
* @return the numeric type used to index the numeric values
|
||||
*/
|
||||
public Class<? extends Number> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the numeric type used to index the numeric values
|
||||
*
|
||||
* @param type the numeric type used to index the numeric values
|
||||
*/
|
||||
public void setType(Class<? extends Number> type) {
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("type cannot be null!");
|
||||
}
|
||||
if (Integer.class.equals(type) == false &&
|
||||
Long.class.equals(type) == false &&
|
||||
Float.class.equals(type) == false &&
|
||||
Double.class.equals(type) == false) {
|
||||
throw new IllegalArgumentException("unsupported numeric type: " + type);
|
||||
}
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link NumberFormat} used to parse a {@link String} to
|
||||
* {@link Number}
|
||||
*
|
||||
* @param format
|
||||
* the {@link NumberFormat} used to parse a {@link String} to
|
||||
* {@link Number}, cannot be <code>null</code>
|
||||
*/
|
||||
public void setNumberFormat(NumberFormat format) {
|
||||
if (format == null) {
|
||||
throw new IllegalArgumentException("format cannot be null!");
|
||||
}
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + format.hashCode();
|
||||
result = prime * result + type.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
if (getClass() != obj.getClass()) return false;
|
||||
PointsConfig other = (PointsConfig) obj;
|
||||
if (!format.equals(other.format)) return false;
|
||||
if (!type.equals(other.type)) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.lucene.queryparser.flexible.standard.config;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.lucene.queryparser.flexible.core.config.FieldConfig;
|
||||
import org.apache.lucene.queryparser.flexible.core.config.FieldConfigListener;
|
||||
import org.apache.lucene.queryparser.flexible.core.config.QueryConfigHandler;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
|
||||
|
||||
/**
|
||||
* This listener is used to listen to {@link FieldConfig} requests in
|
||||
* {@link QueryConfigHandler} and add {@link ConfigurationKeys#POINTS_CONFIG}
|
||||
* based on the {@link ConfigurationKeys#POINTS_CONFIG_MAP} set in the
|
||||
* {@link QueryConfigHandler}.
|
||||
*
|
||||
* @see PointsConfig
|
||||
* @see QueryConfigHandler
|
||||
* @see ConfigurationKeys#POINTS_CONFIG
|
||||
* @see ConfigurationKeys#POINTS_CONFIG_MAP
|
||||
*/
|
||||
public class PointsConfigListener implements FieldConfigListener {
|
||||
|
||||
final private QueryConfigHandler config;
|
||||
|
||||
/**
|
||||
* Constructs a {@link PointsConfigListener} object using the given {@link QueryConfigHandler}.
|
||||
*
|
||||
* @param config the {@link QueryConfigHandler} it will listen too
|
||||
*/
|
||||
public PointsConfigListener(QueryConfigHandler config) {
|
||||
if (config == null) {
|
||||
throw new IllegalArgumentException("config cannot be null!");
|
||||
}
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildFieldConfig(FieldConfig fieldConfig) {
|
||||
Map<String,PointsConfig> pointsConfigMap = config.get(ConfigurationKeys.POINTS_CONFIG_MAP);
|
||||
|
||||
if (pointsConfigMap != null) {
|
||||
PointsConfig pointsConfig = pointsConfigMap.get(fieldConfig.getField());
|
||||
|
||||
if (pointsConfig != null) {
|
||||
fieldConfig.set(ConfigurationKeys.POINTS_CONFIG, pointsConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -167,21 +167,41 @@ public class StandardQueryConfigHandler extends QueryConfigHandler {
|
|||
final public static ConfigurationKey<Float> BOOST = ConfigurationKey.newInstance();
|
||||
|
||||
/**
|
||||
* Key used to set a field to its {@link NumericConfig}.
|
||||
* Key used to set a field to its {@link LegacyNumericConfig}.
|
||||
*
|
||||
* @see StandardQueryParser#setNumericConfigMap(Map)
|
||||
* @see StandardQueryParser#getNumericConfigMap()
|
||||
* @see StandardQueryParser#setLegacyNumericConfigMap(Map)
|
||||
* @see StandardQueryParser#getLegacyNumericConfigMap()
|
||||
* @deprecated Index with Points instead and use {@link #POINTS_CONFIG}
|
||||
*/
|
||||
final public static ConfigurationKey<NumericConfig> NUMERIC_CONFIG = ConfigurationKey.newInstance();
|
||||
@Deprecated
|
||||
final public static ConfigurationKey<LegacyNumericConfig> LEGACY_NUMERIC_CONFIG = ConfigurationKey.newInstance();
|
||||
|
||||
/**
|
||||
* Key used to set the {@link NumericConfig} in {@link FieldConfig} for numeric fields.
|
||||
* Key used to set the {@link LegacyNumericConfig} in {@link FieldConfig} for numeric fields.
|
||||
*
|
||||
* @see StandardQueryParser#setNumericConfigMap(Map)
|
||||
* @see StandardQueryParser#getNumericConfigMap()
|
||||
* @see StandardQueryParser#setLegacyNumericConfigMap(Map)
|
||||
* @see StandardQueryParser#getLegacyNumericConfigMap()
|
||||
* @deprecated Index with Points instead and use {@link #POINTS_CONFIG_MAP}
|
||||
*/
|
||||
final public static ConfigurationKey<Map<String,NumericConfig>> NUMERIC_CONFIG_MAP = ConfigurationKey.newInstance();
|
||||
@Deprecated
|
||||
final public static ConfigurationKey<Map<String,LegacyNumericConfig>> LEGACY_NUMERIC_CONFIG_MAP = ConfigurationKey.newInstance();
|
||||
|
||||
/**
|
||||
* Key used to set a field to its {@link PointsConfig}.
|
||||
*
|
||||
* @see StandardQueryParser#setLegacyNumericConfigMap(Map)
|
||||
* @see StandardQueryParser#getLegacyNumericConfigMap()
|
||||
*/
|
||||
final public static ConfigurationKey<PointsConfig> POINTS_CONFIG = ConfigurationKey.newInstance();
|
||||
|
||||
/**
|
||||
* Key used to set the {@link PointsConfig} in {@link FieldConfig} for point fields.
|
||||
*
|
||||
* @see StandardQueryParser#setLegacyNumericConfigMap(Map)
|
||||
* @see StandardQueryParser#getLegacyNumericConfigMap()
|
||||
*/
|
||||
final public static ConfigurationKey<Map<String,PointsConfig>> POINTS_CONFIG_MAP = ConfigurationKey.newInstance();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -195,7 +215,8 @@ public class StandardQueryConfigHandler extends QueryConfigHandler {
|
|||
// Add listener that will build the FieldConfig.
|
||||
addFieldConfigListener(new FieldBoostMapFCListener(this));
|
||||
addFieldConfigListener(new FieldDateResolutionFCListener(this));
|
||||
addFieldConfigListener(new NumericFieldConfigListener(this));
|
||||
addFieldConfigListener(new LegacyNumericFieldConfigListener(this));
|
||||
addFieldConfigListener(new PointsConfigListener(this));
|
||||
|
||||
// Default Values
|
||||
set(ConfigurationKeys.ALLOW_LEADING_WILDCARD, false); // default in 2.9
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.lucene.queryparser.flexible.standard.nodes;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.core.nodes.FieldValuePairQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.core.nodes.QueryNodeImpl;
|
||||
import org.apache.lucene.queryparser.flexible.core.parser.EscapeQuerySyntax;
|
||||
import org.apache.lucene.queryparser.flexible.core.parser.EscapeQuerySyntax.Type;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.LegacyNumericConfig;
|
||||
|
||||
/**
|
||||
* This query node represents a field query that holds a numeric value. It is
|
||||
* similar to {@link FieldQueryNode}, however the {@link #getValue()} returns a
|
||||
* {@link Number}.
|
||||
*
|
||||
* @see LegacyNumericConfig
|
||||
* @deprecated Index with Points instead and use {@link PointQueryNode} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public class LegacyNumericQueryNode extends QueryNodeImpl implements
|
||||
FieldValuePairQueryNode<Number> {
|
||||
|
||||
private NumberFormat numberFormat;
|
||||
|
||||
private CharSequence field;
|
||||
|
||||
private Number value;
|
||||
|
||||
/**
|
||||
* Creates a {@link LegacyNumericQueryNode} object using the given field,
|
||||
* {@link Number} value and {@link NumberFormat} used to convert the value to
|
||||
* {@link String}.
|
||||
*
|
||||
* @param field the field associated with this query node
|
||||
* @param value the value hold by this node
|
||||
* @param numberFormat the {@link NumberFormat} used to convert the value to {@link String}
|
||||
*/
|
||||
public LegacyNumericQueryNode(CharSequence field, Number value,
|
||||
NumberFormat numberFormat) {
|
||||
|
||||
super();
|
||||
|
||||
setNumberFormat(numberFormat);
|
||||
setField(field);
|
||||
setValue(value);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field associated with this node.
|
||||
*
|
||||
* @return the field associated with this node
|
||||
*/
|
||||
@Override
|
||||
public CharSequence getField() {
|
||||
return this.field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the field associated with this node.
|
||||
*
|
||||
* @param fieldName the field associated with this node
|
||||
*/
|
||||
@Override
|
||||
public void setField(CharSequence fieldName) {
|
||||
this.field = fieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to get the value converted to {@link String} and
|
||||
* escaped using the given {@link EscapeQuerySyntax}.
|
||||
*
|
||||
* @param escaper the {@link EscapeQuerySyntax} used to escape the value {@link String}
|
||||
*
|
||||
* @return the value converte to {@link String} and escaped
|
||||
*/
|
||||
protected CharSequence getTermEscaped(EscapeQuerySyntax escaper) {
|
||||
return escaper.escape(numberFormat.format(this.value),
|
||||
Locale.ROOT, Type.NORMAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
|
||||
if (isDefaultField(this.field)) {
|
||||
return getTermEscaped(escapeSyntaxParser);
|
||||
} else {
|
||||
return this.field + ":" + getTermEscaped(escapeSyntaxParser);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link NumberFormat} used to convert the value to {@link String}.
|
||||
*
|
||||
* @param format the {@link NumberFormat} used to convert the value to {@link String}
|
||||
*/
|
||||
public void setNumberFormat(NumberFormat format) {
|
||||
this.numberFormat = format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link NumberFormat} used to convert the value to {@link String}.
|
||||
*
|
||||
* @return the {@link NumberFormat} used to convert the value to {@link String}
|
||||
*/
|
||||
public NumberFormat getNumberFormat() {
|
||||
return this.numberFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the numeric value as {@link Number}.
|
||||
*
|
||||
* @return the numeric value
|
||||
*/
|
||||
@Override
|
||||
public Number getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the numeric value.
|
||||
*
|
||||
* @param value the numeric value
|
||||
*/
|
||||
@Override
|
||||
public void setValue(Number value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "<numeric field='" + this.field + "' number='"
|
||||
+ numberFormat.format(value) + "'/>";
|
||||
}
|
||||
|
||||
}
|
|
@ -21,34 +21,36 @@ import org.apache.lucene.document.FieldType.LegacyNumericType;
|
|||
import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
|
||||
import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages;
|
||||
import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.NumericConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.LegacyNumericConfig;
|
||||
|
||||
/**
|
||||
* This query node represents a range query composed by {@link NumericQueryNode}
|
||||
* This query node represents a range query composed by {@link LegacyNumericQueryNode}
|
||||
* bounds, which means the bound values are {@link Number}s.
|
||||
*
|
||||
* @see NumericQueryNode
|
||||
* @see LegacyNumericQueryNode
|
||||
* @see AbstractRangeQueryNode
|
||||
* @deprecated Index with Points instead and use {@link PointRangeQueryNode} instead.
|
||||
*/
|
||||
public class NumericRangeQueryNode extends
|
||||
AbstractRangeQueryNode<NumericQueryNode> {
|
||||
@Deprecated
|
||||
public class LegacyNumericRangeQueryNode extends
|
||||
AbstractRangeQueryNode<LegacyNumericQueryNode> {
|
||||
|
||||
public NumericConfig numericConfig;
|
||||
public LegacyNumericConfig numericConfig;
|
||||
|
||||
/**
|
||||
* Constructs a {@link NumericRangeQueryNode} object using the given
|
||||
* {@link NumericQueryNode} as its bounds and {@link NumericConfig}.
|
||||
* Constructs a {@link LegacyNumericRangeQueryNode} object using the given
|
||||
* {@link LegacyNumericQueryNode} as its bounds and {@link LegacyNumericConfig}.
|
||||
*
|
||||
* @param lower the lower bound
|
||||
* @param upper the upper bound
|
||||
* @param lowerInclusive <code>true</code> if the lower bound is inclusive, otherwise, <code>false</code>
|
||||
* @param upperInclusive <code>true</code> if the upper bound is inclusive, otherwise, <code>false</code>
|
||||
* @param numericConfig the {@link NumericConfig} that represents associated with the upper and lower bounds
|
||||
* @param numericConfig the {@link LegacyNumericConfig} that represents associated with the upper and lower bounds
|
||||
*
|
||||
* @see #setBounds(NumericQueryNode, NumericQueryNode, boolean, boolean, NumericConfig)
|
||||
* @see #setBounds(LegacyNumericQueryNode, LegacyNumericQueryNode, boolean, boolean, LegacyNumericConfig)
|
||||
*/
|
||||
public NumericRangeQueryNode(NumericQueryNode lower, NumericQueryNode upper,
|
||||
boolean lowerInclusive, boolean upperInclusive, NumericConfig numericConfig) throws QueryNodeException {
|
||||
public LegacyNumericRangeQueryNode(LegacyNumericQueryNode lower, LegacyNumericQueryNode upper,
|
||||
boolean lowerInclusive, boolean upperInclusive, LegacyNumericConfig numericConfig) throws QueryNodeException {
|
||||
setBounds(lower, upper, lowerInclusive, upperInclusive, numericConfig);
|
||||
}
|
||||
|
||||
|
@ -73,17 +75,17 @@ public class NumericRangeQueryNode extends
|
|||
|
||||
/**
|
||||
* Sets the upper and lower bounds of this range query node and the
|
||||
* {@link NumericConfig} associated with these bounds.
|
||||
* {@link LegacyNumericConfig} associated with these bounds.
|
||||
*
|
||||
* @param lower the lower bound
|
||||
* @param upper the upper bound
|
||||
* @param lowerInclusive <code>true</code> if the lower bound is inclusive, otherwise, <code>false</code>
|
||||
* @param upperInclusive <code>true</code> if the upper bound is inclusive, otherwise, <code>false</code>
|
||||
* @param numericConfig the {@link NumericConfig} that represents associated with the upper and lower bounds
|
||||
* @param numericConfig the {@link LegacyNumericConfig} that represents associated with the upper and lower bounds
|
||||
*
|
||||
*/
|
||||
public void setBounds(NumericQueryNode lower, NumericQueryNode upper,
|
||||
boolean lowerInclusive, boolean upperInclusive, NumericConfig numericConfig) throws QueryNodeException {
|
||||
public void setBounds(LegacyNumericQueryNode lower, LegacyNumericQueryNode upper,
|
||||
boolean lowerInclusive, boolean upperInclusive, LegacyNumericConfig numericConfig) throws QueryNodeException {
|
||||
|
||||
if (numericConfig == null) {
|
||||
throw new IllegalArgumentException("numericConfig cannot be null!");
|
||||
|
@ -123,11 +125,11 @@ public class NumericRangeQueryNode extends
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link NumericConfig} associated with the lower and upper bounds.
|
||||
* Returns the {@link LegacyNumericConfig} associated with the lower and upper bounds.
|
||||
*
|
||||
* @return the {@link NumericConfig} associated with the lower and upper bounds
|
||||
* @return the {@link LegacyNumericConfig} associated with the lower and upper bounds
|
||||
*/
|
||||
public NumericConfig getNumericConfig() {
|
||||
public LegacyNumericConfig getNumericConfig() {
|
||||
return this.numericConfig;
|
||||
}
|
||||
|
|
@ -24,16 +24,16 @@ import org.apache.lucene.queryparser.flexible.core.nodes.FieldValuePairQueryNode
|
|||
import org.apache.lucene.queryparser.flexible.core.nodes.QueryNodeImpl;
|
||||
import org.apache.lucene.queryparser.flexible.core.parser.EscapeQuerySyntax;
|
||||
import org.apache.lucene.queryparser.flexible.core.parser.EscapeQuerySyntax.Type;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.NumericConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.PointsConfig;
|
||||
|
||||
/**
|
||||
* This query node represents a field query that holds a numeric value. It is
|
||||
* This query node represents a field query that holds a point value. It is
|
||||
* similar to {@link FieldQueryNode}, however the {@link #getValue()} returns a
|
||||
* {@link Number}.
|
||||
*
|
||||
* @see NumericConfig
|
||||
* @see PointsConfig
|
||||
*/
|
||||
public class NumericQueryNode extends QueryNodeImpl implements
|
||||
public class PointQueryNode extends QueryNodeImpl implements
|
||||
FieldValuePairQueryNode<Number> {
|
||||
|
||||
private NumberFormat numberFormat;
|
||||
|
@ -43,7 +43,7 @@ public class NumericQueryNode extends QueryNodeImpl implements
|
|||
private Number value;
|
||||
|
||||
/**
|
||||
* Creates a {@link NumericQueryNode} object using the given field,
|
||||
* Creates a {@link PointQueryNode} object using the given field,
|
||||
* {@link Number} value and {@link NumberFormat} used to convert the value to
|
||||
* {@link String}.
|
||||
*
|
||||
|
@ -51,7 +51,7 @@ public class NumericQueryNode extends QueryNodeImpl implements
|
|||
* @param value the value hold by this node
|
||||
* @param numberFormat the {@link NumberFormat} used to convert the value to {@link String}
|
||||
*/
|
||||
public NumericQueryNode(CharSequence field, Number value,
|
||||
public PointQueryNode(CharSequence field, Number value,
|
||||
NumberFormat numberFormat) {
|
||||
|
||||
super();
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.lucene.queryparser.flexible.standard.nodes;
|
||||
|
||||
import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.PointsConfig;
|
||||
|
||||
/**
|
||||
* This query node represents a range query composed by {@link PointQueryNode}
|
||||
* bounds, which means the bound values are {@link Number}s.
|
||||
*
|
||||
* @see PointQueryNode
|
||||
* @see AbstractRangeQueryNode
|
||||
*/
|
||||
public class PointRangeQueryNode extends AbstractRangeQueryNode<PointQueryNode> {
|
||||
|
||||
public PointsConfig numericConfig;
|
||||
|
||||
/**
|
||||
* Constructs a {@link PointRangeQueryNode} object using the given
|
||||
* {@link PointQueryNode} as its bounds and {@link PointsConfig}.
|
||||
*
|
||||
* @param lower the lower bound
|
||||
* @param upper the upper bound
|
||||
* @param lowerInclusive <code>true</code> if the lower bound is inclusive, otherwise, <code>false</code>
|
||||
* @param upperInclusive <code>true</code> if the upper bound is inclusive, otherwise, <code>false</code>
|
||||
* @param numericConfig the {@link PointsConfig} that represents associated with the upper and lower bounds
|
||||
*
|
||||
* @see #setBounds(PointQueryNode, PointQueryNode, boolean, boolean, PointsConfig)
|
||||
*/
|
||||
public PointRangeQueryNode(PointQueryNode lower, PointQueryNode upper,
|
||||
boolean lowerInclusive, boolean upperInclusive, PointsConfig numericConfig) throws QueryNodeException {
|
||||
setBounds(lower, upper, lowerInclusive, upperInclusive, numericConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the upper and lower bounds of this range query node and the
|
||||
* {@link PointsConfig} associated with these bounds.
|
||||
*
|
||||
* @param lower the lower bound
|
||||
* @param upper the upper bound
|
||||
* @param lowerInclusive <code>true</code> if the lower bound is inclusive, otherwise, <code>false</code>
|
||||
* @param upperInclusive <code>true</code> if the upper bound is inclusive, otherwise, <code>false</code>
|
||||
* @param pointsConfig the {@link PointsConfig} that represents associated with the upper and lower bounds
|
||||
*
|
||||
*/
|
||||
public void setBounds(PointQueryNode lower, PointQueryNode upper,
|
||||
boolean lowerInclusive, boolean upperInclusive, PointsConfig pointsConfig) throws QueryNodeException {
|
||||
|
||||
if (pointsConfig == null) {
|
||||
throw new IllegalArgumentException("pointsConfig cannot be null!");
|
||||
}
|
||||
|
||||
Class<? extends Number> lowerNumberType, upperNumberType;
|
||||
|
||||
if (lower != null && lower.getValue() != null) {
|
||||
lowerNumberType = lower.getValue().getClass();
|
||||
} else {
|
||||
lowerNumberType = null;
|
||||
}
|
||||
|
||||
if (upper != null && upper.getValue() != null) {
|
||||
upperNumberType = upper.getValue().getClass();
|
||||
} else {
|
||||
upperNumberType = null;
|
||||
}
|
||||
|
||||
if (lowerNumberType != null
|
||||
&& !lowerNumberType.equals(pointsConfig.getType())) {
|
||||
throw new IllegalArgumentException(
|
||||
"lower value's type should be the same as numericConfig type: "
|
||||
+ lowerNumberType + " != " + pointsConfig.getType());
|
||||
}
|
||||
|
||||
if (upperNumberType != null
|
||||
&& !upperNumberType.equals(pointsConfig.getType())) {
|
||||
throw new IllegalArgumentException(
|
||||
"upper value's type should be the same as numericConfig type: "
|
||||
+ upperNumberType + " != " + pointsConfig.getType());
|
||||
}
|
||||
|
||||
super.setBounds(lower, upper, lowerInclusive, upperInclusive);
|
||||
this.numericConfig = pointsConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link PointsConfig} associated with the lower and upper bounds.
|
||||
*
|
||||
* @return the {@link PointsConfig} associated with the lower and upper bounds
|
||||
*/
|
||||
public PointsConfig getPointsConfig() {
|
||||
return this.numericConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<pointRange lowerInclusive='");
|
||||
sb.append(isLowerInclusive());
|
||||
sb.append("' upperInclusive='");
|
||||
sb.append(isUpperInclusive());
|
||||
sb.append("' type='");
|
||||
sb.append(numericConfig.getType().getSimpleName());
|
||||
sb.append("'>\n");
|
||||
sb.append(getLowerBound()).append('\n');
|
||||
sb.append(getUpperBound()).append('\n');
|
||||
sb.append("</pointRange>");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
|
@ -30,19 +30,19 @@ import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode;
|
|||
import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.core.nodes.RangeQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessorImpl;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.NumericConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.LegacyNumericConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.NumericQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.NumericRangeQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.LegacyNumericQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.LegacyNumericRangeQueryNode;
|
||||
|
||||
/**
|
||||
* This processor is used to convert {@link FieldQueryNode}s to
|
||||
* {@link NumericRangeQueryNode}s. It looks for
|
||||
* {@link ConfigurationKeys#NUMERIC_CONFIG} set in the {@link FieldConfig} of
|
||||
* {@link LegacyNumericRangeQueryNode}s. It looks for
|
||||
* {@link ConfigurationKeys#LEGACY_NUMERIC_CONFIG} set in the {@link FieldConfig} of
|
||||
* every {@link FieldQueryNode} found. If
|
||||
* {@link ConfigurationKeys#NUMERIC_CONFIG} is found, it considers that
|
||||
* {@link ConfigurationKeys#LEGACY_NUMERIC_CONFIG} is found, it considers that
|
||||
* {@link FieldQueryNode} to be a numeric query and convert it to
|
||||
* {@link NumericRangeQueryNode} with upper and lower inclusive and lower and
|
||||
* {@link LegacyNumericRangeQueryNode} with upper and lower inclusive and lower and
|
||||
* upper equals to the value represented by the {@link FieldQueryNode} converted
|
||||
* to {@link Number}. It means that <b>field:1</b> is converted to <b>field:[1
|
||||
* TO 1]</b>. <br>
|
||||
|
@ -50,17 +50,19 @@ import org.apache.lucene.queryparser.flexible.standard.nodes.NumericRangeQueryNo
|
|||
* Note that {@link FieldQueryNode}s children of a
|
||||
* {@link RangeQueryNode} are ignored.
|
||||
*
|
||||
* @see ConfigurationKeys#NUMERIC_CONFIG
|
||||
* @see ConfigurationKeys#LEGACY_NUMERIC_CONFIG
|
||||
* @see FieldQueryNode
|
||||
* @see NumericConfig
|
||||
* @see NumericQueryNode
|
||||
* @see LegacyNumericConfig
|
||||
* @see LegacyNumericQueryNode
|
||||
* @deprecated Index with points and use {@link PointQueryNodeProcessor} instead.
|
||||
*/
|
||||
public class NumericQueryNodeProcessor extends QueryNodeProcessorImpl {
|
||||
@Deprecated
|
||||
public class LegacyNumericQueryNodeProcessor extends QueryNodeProcessorImpl {
|
||||
|
||||
/**
|
||||
* Constructs a {@link NumericQueryNodeProcessor} object.
|
||||
* Constructs a {@link LegacyNumericQueryNodeProcessor} object.
|
||||
*/
|
||||
public NumericQueryNodeProcessor() {
|
||||
public LegacyNumericQueryNodeProcessor() {
|
||||
// empty constructor
|
||||
}
|
||||
|
||||
|
@ -78,8 +80,8 @@ public class NumericQueryNodeProcessor extends QueryNodeProcessorImpl {
|
|||
.getFieldAsString());
|
||||
|
||||
if (fieldConfig != null) {
|
||||
NumericConfig numericConfig = fieldConfig
|
||||
.get(ConfigurationKeys.NUMERIC_CONFIG);
|
||||
LegacyNumericConfig numericConfig = fieldConfig
|
||||
.get(ConfigurationKeys.LEGACY_NUMERIC_CONFIG);
|
||||
|
||||
if (numericConfig != null) {
|
||||
|
||||
|
@ -118,12 +120,12 @@ public class NumericQueryNodeProcessor extends QueryNodeProcessorImpl {
|
|||
QueryParserMessages.NUMERIC_CANNOT_BE_EMPTY, fieldNode.getFieldAsString()));
|
||||
}
|
||||
|
||||
NumericQueryNode lowerNode = new NumericQueryNode(fieldNode
|
||||
LegacyNumericQueryNode lowerNode = new LegacyNumericQueryNode(fieldNode
|
||||
.getField(), number, numberFormat);
|
||||
NumericQueryNode upperNode = new NumericQueryNode(fieldNode
|
||||
LegacyNumericQueryNode upperNode = new LegacyNumericQueryNode(fieldNode
|
||||
.getField(), number, numberFormat);
|
||||
|
||||
return new NumericRangeQueryNode(lowerNode, upperNode, true, true,
|
||||
return new LegacyNumericRangeQueryNode(lowerNode, upperNode, true, true,
|
||||
numericConfig);
|
||||
|
||||
}
|
|
@ -30,32 +30,34 @@ import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode;
|
|||
import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessorImpl;
|
||||
import org.apache.lucene.queryparser.flexible.core.util.StringUtils;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.NumericConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.LegacyNumericConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.NumericQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.NumericRangeQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.LegacyNumericQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.LegacyNumericRangeQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.TermRangeQueryNode;
|
||||
|
||||
/**
|
||||
* This processor is used to convert {@link TermRangeQueryNode}s to
|
||||
* {@link NumericRangeQueryNode}s. It looks for
|
||||
* {@link ConfigurationKeys#NUMERIC_CONFIG} set in the {@link FieldConfig} of
|
||||
* {@link LegacyNumericRangeQueryNode}s. It looks for
|
||||
* {@link ConfigurationKeys#LEGACY_NUMERIC_CONFIG} set in the {@link FieldConfig} of
|
||||
* every {@link TermRangeQueryNode} found. If
|
||||
* {@link ConfigurationKeys#NUMERIC_CONFIG} is found, it considers that
|
||||
* {@link ConfigurationKeys#LEGACY_NUMERIC_CONFIG} is found, it considers that
|
||||
* {@link TermRangeQueryNode} to be a numeric range query and convert it to
|
||||
* {@link NumericRangeQueryNode}.
|
||||
* {@link LegacyNumericRangeQueryNode}.
|
||||
*
|
||||
* @see ConfigurationKeys#NUMERIC_CONFIG
|
||||
* @see ConfigurationKeys#LEGACY_NUMERIC_CONFIG
|
||||
* @see TermRangeQueryNode
|
||||
* @see NumericConfig
|
||||
* @see NumericRangeQueryNode
|
||||
* @see LegacyNumericConfig
|
||||
* @see LegacyNumericRangeQueryNode
|
||||
* @deprecated Index with points and use {@link PointRangeQueryNodeProcessor} instead.
|
||||
*/
|
||||
public class NumericRangeQueryNodeProcessor extends QueryNodeProcessorImpl {
|
||||
@Deprecated
|
||||
public class LegacyNumericRangeQueryNodeProcessor extends QueryNodeProcessorImpl {
|
||||
|
||||
/**
|
||||
* Constructs an empty {@link NumericRangeQueryNode} object.
|
||||
* Constructs an empty {@link LegacyNumericRangeQueryNode} object.
|
||||
*/
|
||||
public NumericRangeQueryNodeProcessor() {
|
||||
public LegacyNumericRangeQueryNodeProcessor() {
|
||||
// empty constructor
|
||||
}
|
||||
|
||||
|
@ -72,8 +74,8 @@ public class NumericRangeQueryNodeProcessor extends QueryNodeProcessorImpl {
|
|||
|
||||
if (fieldConfig != null) {
|
||||
|
||||
NumericConfig numericConfig = fieldConfig
|
||||
.get(ConfigurationKeys.NUMERIC_CONFIG);
|
||||
LegacyNumericConfig numericConfig = fieldConfig
|
||||
.get(ConfigurationKeys.LEGACY_NUMERIC_CONFIG);
|
||||
|
||||
if (numericConfig != null) {
|
||||
|
||||
|
@ -131,15 +133,15 @@ public class NumericRangeQueryNodeProcessor extends QueryNodeProcessorImpl {
|
|||
if (lowerNumber != null) lowerNumber = lowerNumber.floatValue();
|
||||
}
|
||||
|
||||
NumericQueryNode lowerNode = new NumericQueryNode(
|
||||
LegacyNumericQueryNode lowerNode = new LegacyNumericQueryNode(
|
||||
termRangeNode.getField(), lowerNumber, numberFormat);
|
||||
NumericQueryNode upperNode = new NumericQueryNode(
|
||||
LegacyNumericQueryNode upperNode = new LegacyNumericQueryNode(
|
||||
termRangeNode.getField(), upperNumber, numberFormat);
|
||||
|
||||
boolean lowerInclusive = termRangeNode.isLowerInclusive();
|
||||
boolean upperInclusive = termRangeNode.isUpperInclusive();
|
||||
|
||||
return new NumericRangeQueryNode(lowerNode, upperNode,
|
||||
return new LegacyNumericRangeQueryNode(lowerNode, upperNode,
|
||||
lowerInclusive, upperInclusive, numericConfig);
|
||||
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.lucene.queryparser.flexible.standard.processors;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
|
||||
import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
|
||||
import org.apache.lucene.queryparser.flexible.core.QueryNodeParseException;
|
||||
import org.apache.lucene.queryparser.flexible.core.config.FieldConfig;
|
||||
import org.apache.lucene.queryparser.flexible.core.config.QueryConfigHandler;
|
||||
import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages;
|
||||
import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.core.nodes.RangeQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessorImpl;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.PointsConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.PointQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.PointRangeQueryNode;
|
||||
|
||||
/**
|
||||
* This processor is used to convert {@link FieldQueryNode}s to
|
||||
* {@link PointRangeQueryNode}s. It looks for
|
||||
* {@link ConfigurationKeys#POINTS_CONFIG} set in the {@link FieldConfig} of
|
||||
* every {@link FieldQueryNode} found. If
|
||||
* {@link ConfigurationKeys#POINTS_CONFIG} is found, it considers that
|
||||
* {@link FieldQueryNode} to be a numeric query and convert it to
|
||||
* {@link PointRangeQueryNode} with upper and lower inclusive and lower and
|
||||
* upper equals to the value represented by the {@link FieldQueryNode} converted
|
||||
* to {@link Number}. It means that <b>field:1</b> is converted to <b>field:[1
|
||||
* TO 1]</b>. <br>
|
||||
* <br>
|
||||
* Note that {@link FieldQueryNode}s children of a
|
||||
* {@link RangeQueryNode} are ignored.
|
||||
*
|
||||
* @see ConfigurationKeys#POINTS_CONFIG
|
||||
* @see FieldQueryNode
|
||||
* @see PointsConfig
|
||||
* @see PointQueryNode
|
||||
*/
|
||||
public class PointQueryNodeProcessor extends QueryNodeProcessorImpl {
|
||||
|
||||
/**
|
||||
* Constructs a {@link PointQueryNodeProcessor} object.
|
||||
*/
|
||||
public PointQueryNodeProcessor() {
|
||||
// empty constructor
|
||||
}
|
||||
|
||||
@Override
|
||||
protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
|
||||
|
||||
if (node instanceof FieldQueryNode
|
||||
&& !(node.getParent() instanceof RangeQueryNode)) {
|
||||
|
||||
QueryConfigHandler config = getQueryConfigHandler();
|
||||
|
||||
if (config != null) {
|
||||
FieldQueryNode fieldNode = (FieldQueryNode) node;
|
||||
FieldConfig fieldConfig = config.getFieldConfig(fieldNode
|
||||
.getFieldAsString());
|
||||
|
||||
if (fieldConfig != null) {
|
||||
PointsConfig numericConfig = fieldConfig.get(ConfigurationKeys.POINTS_CONFIG);
|
||||
|
||||
if (numericConfig != null) {
|
||||
|
||||
NumberFormat numberFormat = numericConfig.getNumberFormat();
|
||||
String text = fieldNode.getTextAsString();
|
||||
Number number = null;
|
||||
|
||||
if (text.length() > 0) {
|
||||
|
||||
try {
|
||||
number = numberFormat.parse(text);
|
||||
|
||||
} catch (ParseException e) {
|
||||
throw new QueryNodeParseException(new MessageImpl(
|
||||
QueryParserMessages.COULD_NOT_PARSE_NUMBER, fieldNode
|
||||
.getTextAsString(), numberFormat.getClass()
|
||||
.getCanonicalName()), e);
|
||||
}
|
||||
|
||||
if (Integer.class.equals(numericConfig.getType())) {
|
||||
number = number.intValue();
|
||||
} else if (Long.class.equals(numericConfig.getType())) {
|
||||
number = number.longValue();
|
||||
} else if (Double.class.equals(numericConfig.getType())) {
|
||||
number = number.doubleValue();
|
||||
} else if (Float.class.equals(numericConfig.getType())) {
|
||||
number = number.floatValue();
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new QueryNodeParseException(new MessageImpl(
|
||||
QueryParserMessages.NUMERIC_CANNOT_BE_EMPTY, fieldNode.getFieldAsString()));
|
||||
}
|
||||
|
||||
PointQueryNode lowerNode = new PointQueryNode(fieldNode.getField(), number, numberFormat);
|
||||
PointQueryNode upperNode = new PointQueryNode(fieldNode.getField(), number, numberFormat);
|
||||
|
||||
return new PointRangeQueryNode(lowerNode, upperNode, true, true, numericConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
|
||||
return node;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<QueryNode> setChildrenOrder(List<QueryNode> children) throws QueryNodeException {
|
||||
return children;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.lucene.queryparser.flexible.standard.processors;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
|
||||
import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
|
||||
import org.apache.lucene.queryparser.flexible.core.QueryNodeParseException;
|
||||
import org.apache.lucene.queryparser.flexible.core.config.FieldConfig;
|
||||
import org.apache.lucene.queryparser.flexible.core.config.QueryConfigHandler;
|
||||
import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages;
|
||||
import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessorImpl;
|
||||
import org.apache.lucene.queryparser.flexible.core.util.StringUtils;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.PointsConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.PointQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.PointRangeQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.TermRangeQueryNode;
|
||||
|
||||
/**
|
||||
* This processor is used to convert {@link TermRangeQueryNode}s to
|
||||
* {@link PointRangeQueryNode}s. It looks for
|
||||
* {@link ConfigurationKeys#POINTS_CONFIG} set in the {@link FieldConfig} of
|
||||
* every {@link TermRangeQueryNode} found. If
|
||||
* {@link ConfigurationKeys#POINTS_CONFIG} is found, it considers that
|
||||
* {@link TermRangeQueryNode} to be a numeric range query and convert it to
|
||||
* {@link PointRangeQueryNode}.
|
||||
*
|
||||
* @see ConfigurationKeys#POINTS_CONFIG
|
||||
* @see TermRangeQueryNode
|
||||
* @see PointsConfig
|
||||
* @see PointRangeQueryNode
|
||||
*/
|
||||
public class PointRangeQueryNodeProcessor extends QueryNodeProcessorImpl {
|
||||
|
||||
/**
|
||||
* Constructs an empty {@link PointRangeQueryNodeProcessor} object.
|
||||
*/
|
||||
public PointRangeQueryNodeProcessor() {
|
||||
// empty constructor
|
||||
}
|
||||
|
||||
@Override
|
||||
protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
|
||||
|
||||
if (node instanceof TermRangeQueryNode) {
|
||||
QueryConfigHandler config = getQueryConfigHandler();
|
||||
|
||||
if (config != null) {
|
||||
TermRangeQueryNode termRangeNode = (TermRangeQueryNode) node;
|
||||
FieldConfig fieldConfig = config.getFieldConfig(StringUtils.toString(termRangeNode.getField()));
|
||||
|
||||
if (fieldConfig != null) {
|
||||
PointsConfig numericConfig = fieldConfig.get(ConfigurationKeys.POINTS_CONFIG);
|
||||
|
||||
if (numericConfig != null) {
|
||||
FieldQueryNode lower = termRangeNode.getLowerBound();
|
||||
FieldQueryNode upper = termRangeNode.getUpperBound();
|
||||
|
||||
String lowerText = lower.getTextAsString();
|
||||
String upperText = upper.getTextAsString();
|
||||
NumberFormat numberFormat = numericConfig.getNumberFormat();
|
||||
Number lowerNumber = null, upperNumber = null;
|
||||
|
||||
if (lowerText.length() > 0) {
|
||||
|
||||
try {
|
||||
lowerNumber = numberFormat.parse(lowerText);
|
||||
|
||||
} catch (ParseException e) {
|
||||
throw new QueryNodeParseException(new MessageImpl(
|
||||
QueryParserMessages.COULD_NOT_PARSE_NUMBER, lower
|
||||
.getTextAsString(), numberFormat.getClass()
|
||||
.getCanonicalName()), e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (upperText.length() > 0) {
|
||||
|
||||
try {
|
||||
upperNumber = numberFormat.parse(upperText);
|
||||
|
||||
} catch (ParseException e) {
|
||||
throw new QueryNodeParseException(new MessageImpl(
|
||||
QueryParserMessages.COULD_NOT_PARSE_NUMBER, upper
|
||||
.getTextAsString(), numberFormat.getClass()
|
||||
.getCanonicalName()), e);
|
||||
}
|
||||
}
|
||||
|
||||
if (Integer.class.equals(numericConfig.getType())) {
|
||||
if (upperNumber != null) upperNumber = upperNumber.intValue();
|
||||
if (lowerNumber != null) lowerNumber = lowerNumber.intValue();
|
||||
} else if (Long.class.equals(numericConfig.getType())) {
|
||||
if (upperNumber != null) upperNumber = upperNumber.longValue();
|
||||
if (lowerNumber != null) lowerNumber = lowerNumber.longValue();
|
||||
} else if (Double.class.equals(numericConfig.getType())) {
|
||||
if (upperNumber != null) upperNumber = upperNumber.doubleValue();
|
||||
if (lowerNumber != null) lowerNumber = lowerNumber.doubleValue();
|
||||
} else if (Float.class.equals(numericConfig.getType())) {
|
||||
if (upperNumber != null) upperNumber = upperNumber.floatValue();
|
||||
if (lowerNumber != null) lowerNumber = lowerNumber.floatValue();
|
||||
}
|
||||
|
||||
PointQueryNode lowerNode = new PointQueryNode(termRangeNode.getField(), lowerNumber, numberFormat);
|
||||
PointQueryNode upperNode = new PointQueryNode(termRangeNode.getField(), upperNumber, numberFormat);
|
||||
|
||||
boolean lowerInclusive = termRangeNode.isLowerInclusive();
|
||||
boolean upperInclusive = termRangeNode.isUpperInclusive();
|
||||
|
||||
return new PointRangeQueryNode(lowerNode, upperNode, lowerInclusive, upperInclusive, numericConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
|
||||
return node;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<QueryNode> setChildrenOrder(List<QueryNode> children) throws QueryNodeException {
|
||||
return children;
|
||||
}
|
||||
}
|
|
@ -55,8 +55,10 @@ public class StandardQueryNodeProcessorPipeline extends
|
|||
add(new FuzzyQueryNodeProcessor());
|
||||
add(new MatchAllDocsQueryNodeProcessor());
|
||||
add(new OpenRangeQueryNodeProcessor());
|
||||
add(new NumericQueryNodeProcessor());
|
||||
add(new NumericRangeQueryNodeProcessor());
|
||||
add(new LegacyNumericQueryNodeProcessor());
|
||||
add(new LegacyNumericRangeQueryNodeProcessor());
|
||||
add(new PointQueryNodeProcessor());
|
||||
add(new PointRangeQueryNodeProcessor());
|
||||
add(new LowercaseExpandedTermsQueryNodeProcessor());
|
||||
add(new TermRangeQueryNodeProcessor());
|
||||
add(new AllowLeadingWildcardProcessor());
|
||||
|
|
|
@ -44,7 +44,7 @@ import org.apache.lucene.index.RandomIndexWriter;
|
|||
import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
|
||||
import org.apache.lucene.queryparser.flexible.core.parser.EscapeQuerySyntax;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.NumberDateFormat;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.NumericConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.LegacyNumericConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.parser.EscapeQuerySyntaxImpl;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.Query;
|
||||
|
@ -56,7 +56,7 @@ import org.junit.AfterClass;
|
|||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestNumericQueryParser extends LuceneTestCase {
|
||||
public class TestLegacyNumericQueryParser extends LuceneTestCase {
|
||||
|
||||
private static enum NumberType {
|
||||
NEGATIVE, ZERO, POSITIVE;
|
||||
|
@ -193,12 +193,12 @@ public class TestNumericQueryParser extends LuceneTestCase {
|
|||
.setMergePolicy(newLogMergePolicy()));
|
||||
|
||||
Document doc = new Document();
|
||||
HashMap<String,NumericConfig> numericConfigMap = new HashMap<>();
|
||||
HashMap<String,LegacyNumericConfig> numericConfigMap = new HashMap<>();
|
||||
HashMap<String,Field> numericFieldMap = new HashMap<>();
|
||||
qp.setNumericConfigMap(numericConfigMap);
|
||||
qp.setLegacyNumericConfigMap(numericConfigMap);
|
||||
|
||||
for (LegacyNumericType type : LegacyNumericType.values()) {
|
||||
numericConfigMap.put(type.name(), new NumericConfig(PRECISION_STEP,
|
||||
numericConfigMap.put(type.name(), new LegacyNumericConfig(PRECISION_STEP,
|
||||
NUMBER_FORMAT, type));
|
||||
|
||||
FieldType ft = new FieldType(LegacyIntField.TYPE_NOT_STORED);
|
||||
|
@ -229,7 +229,7 @@ public class TestNumericQueryParser extends LuceneTestCase {
|
|||
doc.add(field);
|
||||
}
|
||||
|
||||
numericConfigMap.put(DATE_FIELD_NAME, new NumericConfig(PRECISION_STEP,
|
||||
numericConfigMap.put(DATE_FIELD_NAME, new LegacyNumericConfig(PRECISION_STEP,
|
||||
DATE_FORMAT, LegacyNumericType.LONG));
|
||||
FieldType ft = new FieldType(LegacyLongField.TYPE_NOT_STORED);
|
||||
ft.setStored(true);
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.lucene.queryparser.flexible.standard;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
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.queryparser.flexible.standard.config.PointsConfig;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
|
||||
/** Simple test for point field integration into the flexible QP */
|
||||
public class TestPointQueryParser extends LuceneTestCase {
|
||||
|
||||
public void testIntegers() throws Exception {
|
||||
StandardQueryParser parser = new StandardQueryParser();
|
||||
Map<String,PointsConfig> pointsConfig = new HashMap<>();
|
||||
pointsConfig.put("intField", new PointsConfig(NumberFormat.getIntegerInstance(Locale.ROOT), Integer.class));
|
||||
parser.setPointsConfigMap(pointsConfig);
|
||||
|
||||
assertEquals(IntPoint.newRangeQuery("intField", 1, 3),
|
||||
parser.parse("intField:[1 TO 3]", "body"));
|
||||
assertEquals(IntPoint.newRangeQuery("intField", 1, 1),
|
||||
parser.parse("intField:1", "body"));
|
||||
}
|
||||
|
||||
public void testLongs() throws Exception {
|
||||
StandardQueryParser parser = new StandardQueryParser();
|
||||
Map<String,PointsConfig> pointsConfig = new HashMap<>();
|
||||
pointsConfig.put("longField", new PointsConfig(NumberFormat.getIntegerInstance(Locale.ROOT), Long.class));
|
||||
parser.setPointsConfigMap(pointsConfig);
|
||||
|
||||
assertEquals(LongPoint.newRangeQuery("longField", 1, 3),
|
||||
parser.parse("longField:[1 TO 3]", "body"));
|
||||
assertEquals(LongPoint.newRangeQuery("longField", 1, 1),
|
||||
parser.parse("longField:1", "body"));
|
||||
}
|
||||
|
||||
public void testFloats() throws Exception {
|
||||
StandardQueryParser parser = new StandardQueryParser();
|
||||
Map<String,PointsConfig> pointsConfig = new HashMap<>();
|
||||
pointsConfig.put("floatField", new PointsConfig(NumberFormat.getNumberInstance(Locale.ROOT), Float.class));
|
||||
parser.setPointsConfigMap(pointsConfig);
|
||||
|
||||
assertEquals(FloatPoint.newRangeQuery("floatField", 1.5F, 3.6F),
|
||||
parser.parse("floatField:[1.5 TO 3.6]", "body"));
|
||||
assertEquals(FloatPoint.newRangeQuery("floatField", 1.5F, 1.5F),
|
||||
parser.parse("floatField:1.5", "body"));
|
||||
}
|
||||
|
||||
public void testDoubles() throws Exception {
|
||||
StandardQueryParser parser = new StandardQueryParser();
|
||||
Map<String,PointsConfig> pointsConfig = new HashMap<>();
|
||||
pointsConfig.put("doubleField", new PointsConfig(NumberFormat.getNumberInstance(Locale.ROOT), Double.class));
|
||||
parser.setPointsConfigMap(pointsConfig);
|
||||
|
||||
assertEquals(DoublePoint.newRangeQuery("doubleField", 1.5D, 3.6D),
|
||||
parser.parse("doubleField:[1.5 TO 3.6]", "body"));
|
||||
assertEquals(DoublePoint.newRangeQuery("floatField", 1.5D, 1.5D),
|
||||
parser.parse("doubleField:1.5", "body"));
|
||||
}
|
||||
|
||||
}
|
|
@ -548,7 +548,7 @@ org.apache.lucene.queryparser.flexible.spans.TestSpanQueryParser=711,339,113,55,
|
|||
org.apache.lucene.queryparser.flexible.spans.TestSpanQueryParserSimpleSample=51,644,92,32,129,60,21
|
||||
org.apache.lucene.queryparser.flexible.standard.TestMultiAnalyzerQPHelper=44,84,87,34,260,35,229
|
||||
org.apache.lucene.queryparser.flexible.standard.TestMultiFieldQPHelper=1152,1779,1888,384,179,1665,445
|
||||
org.apache.lucene.queryparser.flexible.standard.TestNumericQueryParser=344,496,451,1373,733,1420,367
|
||||
org.apache.lucene.queryparser.flexible.standard.TestLegacyNumericQueryParser=344,496,451,1373,733,1420,367
|
||||
org.apache.lucene.queryparser.flexible.standard.TestQPHelper=287,676,989,2137,860,586,612
|
||||
org.apache.lucene.queryparser.flexible.standard.TestStandardQP=1643,430,2182,2193,600,1506,741
|
||||
org.apache.lucene.queryparser.surround.query.SrndQueryTest=1062,92,92,212,65,95,113
|
||||
|
|
Loading…
Reference in New Issue