mirror of https://github.com/apache/lucene.git
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
488e41d1fc
|
@ -14,7 +14,6 @@
|
|||
<orderEntry type="library" scope="TEST" name="JUnit" level="project" />
|
||||
<orderEntry type="module" scope="TEST" module-name="lucene-test-framework" />
|
||||
<orderEntry type="module" module-name="grouping" />
|
||||
<orderEntry type="module" module-name="backward-codecs" />
|
||||
<orderEntry type="module" module-name="lucene-core" />
|
||||
</component>
|
||||
</module>
|
||||
|
|
|
@ -17,6 +17,5 @@
|
|||
<orderEntry type="module" module-name="lucene-core" />
|
||||
<orderEntry type="module" module-name="queries" />
|
||||
<orderEntry type="module" module-name="sandbox" />
|
||||
<orderEntry type="module" module-name="backward-codecs" />
|
||||
</component>
|
||||
</module>
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
<path id="classpath">
|
||||
<pathelement path="${grouping.jar}"/>
|
||||
<pathelement path="${backward-codecs.jar}"/>
|
||||
<path refid="base.classpath"/>
|
||||
</path>
|
||||
|
||||
|
@ -35,14 +34,13 @@
|
|||
<pathelement location="${build.dir}/classes/java"/>
|
||||
</path>
|
||||
|
||||
<target name="init" depends="module-build.init,jar-grouping,jar-backward-codecs"/>
|
||||
<target name="init" depends="module-build.init,jar-grouping"/>
|
||||
|
||||
<target name="javadocs" depends="javadocs-grouping,javadocs-backward-codecs,compile-core,check-javadocs-uptodate"
|
||||
<target name="javadocs" depends="javadocs-grouping,compile-core,check-javadocs-uptodate"
|
||||
unless="javadocs-uptodate-${name}">
|
||||
<invoke-module-javadoc>
|
||||
<links>
|
||||
<link href="../grouping"/>
|
||||
<link href="../backward-codecs"/>
|
||||
</links>
|
||||
</invoke-module-javadoc>
|
||||
</target>
|
||||
|
|
|
@ -17,20 +17,13 @@
|
|||
package org.apache.lucene.search.join;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.function.LongConsumer;
|
||||
|
||||
import org.apache.lucene.index.BinaryDocValues;
|
||||
import org.apache.lucene.index.DocValues;
|
||||
import org.apache.lucene.index.LeafReader;
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.index.NumericDocValues;
|
||||
import org.apache.lucene.index.SortedNumericDocValues;
|
||||
import org.apache.lucene.index.SortedSetDocValues;
|
||||
import org.apache.lucene.legacy.LegacyNumericType;
|
||||
import org.apache.lucene.legacy.LegacyNumericUtils;
|
||||
import org.apache.lucene.search.SimpleCollector;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.apache.lucene.util.BytesRefBuilder;
|
||||
|
||||
abstract class DocValuesTermsCollector<DV> extends SimpleCollector {
|
||||
|
||||
|
@ -57,79 +50,4 @@ abstract class DocValuesTermsCollector<DV> extends SimpleCollector {
|
|||
static Function<SortedSetDocValues> sortedSetDocValues(String field) {
|
||||
return (ctx) -> DocValues.getSortedSet(ctx, field);
|
||||
}
|
||||
|
||||
static Function<BinaryDocValues> numericAsBinaryDocValues(String field, LegacyNumericType numTyp) {
|
||||
return (ctx) -> {
|
||||
final NumericDocValues numeric = DocValues.getNumeric(ctx, field);
|
||||
final BytesRefBuilder bytes = new BytesRefBuilder();
|
||||
|
||||
final LongConsumer coder = coder(bytes, numTyp, field);
|
||||
|
||||
return new BinaryDocValues() {
|
||||
@Override
|
||||
public BytesRef get(int docID) {
|
||||
final long lVal = numeric.get(docID);
|
||||
coder.accept(lVal);
|
||||
return bytes.get();
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
static LongConsumer coder(BytesRefBuilder bytes, LegacyNumericType type, String fieldName){
|
||||
switch(type){
|
||||
case INT:
|
||||
return (l) -> LegacyNumericUtils.intToPrefixCoded((int) l, 0, bytes);
|
||||
case LONG:
|
||||
return (l) -> LegacyNumericUtils.longToPrefixCoded(l, 0, bytes);
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported "+type+
|
||||
". Only "+ LegacyNumericType.INT+" and "+ LegacyNumericType.LONG+" are supported."
|
||||
+ "Field "+fieldName );
|
||||
}
|
||||
}
|
||||
|
||||
/** this adapter is quite weird. ords are per doc index, don't use ords across different docs*/
|
||||
static Function<SortedSetDocValues> sortedNumericAsSortedSetDocValues(String field, LegacyNumericType numTyp) {
|
||||
return (ctx) -> {
|
||||
final SortedNumericDocValues numerics = DocValues.getSortedNumeric(ctx, field);
|
||||
final BytesRefBuilder bytes = new BytesRefBuilder();
|
||||
|
||||
final LongConsumer coder = coder(bytes, numTyp, field);
|
||||
|
||||
return new SortedSetDocValues() {
|
||||
|
||||
private int index = Integer.MIN_VALUE;
|
||||
|
||||
@Override
|
||||
public long nextOrd() {
|
||||
return index < numerics.count()-1 ? ++index : NO_MORE_ORDS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDocument(int docID) {
|
||||
numerics.setDocument(docID);
|
||||
index=-1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BytesRef lookupOrd(long ord) {
|
||||
assert ord>=0 && ord<numerics.count();
|
||||
final long value = numerics.valueAt((int)ord);
|
||||
coder.accept(value);
|
||||
return bytes.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getValueCount() {
|
||||
throw new UnsupportedOperationException("it's just number encoding wrapper");
|
||||
}
|
||||
|
||||
@Override
|
||||
public long lookupTerm(BytesRef key) {
|
||||
throw new UnsupportedOperationException("it's just number encoding wrapper");
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ import java.util.function.BiConsumer;
|
|||
import java.util.function.LongFunction;
|
||||
|
||||
import org.apache.lucene.document.DoublePoint;
|
||||
import org.apache.lucene.legacy.LegacyNumericType;
|
||||
import org.apache.lucene.document.FloatPoint;
|
||||
import org.apache.lucene.document.IntPoint;
|
||||
import org.apache.lucene.document.LongPoint;
|
||||
|
@ -111,50 +110,6 @@ public final class JoinUtil {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Because {@link LegacyNumericType} is deprecated, instead use {@link #createJoinQuery(String, boolean, String, Class, Query, IndexSearcher, ScoreMode)}
|
||||
*
|
||||
* Method for query time joining for numeric fields. It supports multi- and single- values longs and ints.
|
||||
* All considerations from {@link JoinUtil#createJoinQuery(String, boolean, String, Query, IndexSearcher, ScoreMode)} are applicable here too,
|
||||
* though memory consumption might be higher.
|
||||
* <p>
|
||||
*
|
||||
* @param fromField The from field to join from
|
||||
* @param multipleValuesPerDocument Whether the from field has multiple terms per document
|
||||
* when true fromField might be {@link DocValuesType#SORTED_NUMERIC},
|
||||
* otherwise fromField should be {@link DocValuesType#NUMERIC}
|
||||
* @param toField The to field to join to, should be {@link org.apache.lucene.legacy.LegacyIntField} or {@link org.apache.lucene.legacy.LegacyLongField}
|
||||
* @param numericType either {@link LegacyNumericType#INT} or {@link LegacyNumericType#LONG}, it should correspond to fromField and toField types
|
||||
* @param fromQuery The query to match documents on the from side
|
||||
* @param fromSearcher The searcher that executed the specified fromQuery
|
||||
* @param scoreMode Instructs how scores from the fromQuery are mapped to the returned query
|
||||
* @return a {@link Query} instance that can be used to join documents based on the
|
||||
* terms in the from and to field
|
||||
* @throws IOException If I/O related errors occur
|
||||
*/
|
||||
@Deprecated
|
||||
public static Query createJoinQuery(String fromField,
|
||||
boolean multipleValuesPerDocument,
|
||||
String toField, LegacyNumericType numericType,
|
||||
Query fromQuery,
|
||||
IndexSearcher fromSearcher,
|
||||
ScoreMode scoreMode) throws IOException {
|
||||
|
||||
final GenericTermsCollector termsCollector;
|
||||
|
||||
if (multipleValuesPerDocument) {
|
||||
Function<SortedSetDocValues> mvFunction = DocValuesTermsCollector.sortedNumericAsSortedSetDocValues(fromField,numericType);
|
||||
termsCollector = GenericTermsCollector.createCollectorMV(mvFunction, scoreMode);
|
||||
} else {
|
||||
Function<BinaryDocValues> svFunction = DocValuesTermsCollector.numericAsBinaryDocValues(fromField,numericType);
|
||||
termsCollector = GenericTermsCollector.createCollectorSV(svFunction, scoreMode);
|
||||
}
|
||||
|
||||
return createJoinQuery(multipleValuesPerDocument, toField, fromQuery, fromSearcher, scoreMode,
|
||||
termsCollector);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for query time joining for numeric fields. It supports multi- and single- values longs, ints, floats and longs.
|
||||
* All considerations from {@link JoinUtil#createJoinQuery(String, boolean, String, Query, IndexSearcher, ScoreMode)} are applicable here too,
|
||||
|
|
|
@ -27,7 +27,6 @@ import org.apache.lucene.index.PostingsEnum;
|
|||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.index.Terms;
|
||||
import org.apache.lucene.index.TermsEnum;
|
||||
import org.apache.lucene.legacy.LegacyNumericUtils;
|
||||
import org.apache.lucene.search.DocIdSetIterator;
|
||||
import org.apache.lucene.search.Explanation;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
|
@ -245,14 +244,6 @@ class TermsIncludingScoreQuery extends Query {
|
|||
for (int i = 0; i < terms.size(); i++) {
|
||||
terms.get(ords[i], ref);
|
||||
out.print(ref+" "+ref.utf8ToString()+" ");
|
||||
try {
|
||||
out.print(Long.toHexString(LegacyNumericUtils.prefixCodedToLong(ref))+"L");
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
out.print(Integer.toHexString(LegacyNumericUtils.prefixCodedToInt(ref))+"i");
|
||||
} catch (Exception ee) {
|
||||
}
|
||||
}
|
||||
out.println(" score="+scores[ords[i]]);
|
||||
out.println("");
|
||||
}
|
||||
|
|
|
@ -56,9 +56,6 @@ import org.apache.lucene.index.LeafReader;
|
|||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.index.MultiDocValues;
|
||||
import org.apache.lucene.index.MultiDocValues.OrdinalMap;
|
||||
import org.apache.lucene.legacy.LegacyIntField;
|
||||
import org.apache.lucene.legacy.LegacyLongField;
|
||||
import org.apache.lucene.legacy.LegacyNumericType;
|
||||
import org.apache.lucene.index.MultiFields;
|
||||
import org.apache.lucene.index.NoMergePolicy;
|
||||
import org.apache.lucene.index.NumericDocValues;
|
||||
|
@ -971,7 +968,7 @@ public class TestJoinUtil extends LuceneTestCase {
|
|||
final String fromField = from ? "from":"to";
|
||||
final String toField = from ? "to":"from";
|
||||
|
||||
int surpriseMe = random().nextInt(3);
|
||||
int surpriseMe = random().nextInt(2);
|
||||
switch (surpriseMe) {
|
||||
case 0:
|
||||
Class<? extends Number> numType;
|
||||
|
@ -992,10 +989,6 @@ public class TestJoinUtil extends LuceneTestCase {
|
|||
joinQuery = JoinUtil.createJoinQuery(fromField + suffix, muliValsQuery, toField + suffix, numType, actualQuery, indexSearcher, scoreMode);
|
||||
break;
|
||||
case 1:
|
||||
final LegacyNumericType legacyNumType = random().nextBoolean() ? LegacyNumericType.INT: LegacyNumericType.LONG ;
|
||||
joinQuery = JoinUtil.createJoinQuery(fromField+legacyNumType, muliValsQuery, toField+legacyNumType, legacyNumType, actualQuery, indexSearcher, scoreMode);
|
||||
break;
|
||||
case 2:
|
||||
joinQuery = JoinUtil.createJoinQuery(fromField, muliValsQuery, toField, actualQuery, indexSearcher, scoreMode);
|
||||
break;
|
||||
default:
|
||||
|
@ -1336,26 +1329,24 @@ public class TestJoinUtil extends LuceneTestCase {
|
|||
document.add(newTextField(random, fieldName, linkValue, Field.Store.NO));
|
||||
|
||||
final int linkInt = Integer.parseUnsignedInt(linkValue,16);
|
||||
document.add(new LegacyIntField(fieldName + LegacyNumericType.INT, linkInt, Field.Store.NO));
|
||||
document.add(new IntPoint(fieldName + LegacyNumericType.INT, linkInt));
|
||||
document.add(new IntPoint(fieldName + "INT", linkInt));
|
||||
document.add(new FloatPoint(fieldName + "FLOAT", linkInt));
|
||||
|
||||
final long linkLong = linkInt<<32 | linkInt;
|
||||
document.add(new LegacyLongField(fieldName + LegacyNumericType.LONG, linkLong, Field.Store.NO));
|
||||
document.add(new LongPoint(fieldName + LegacyNumericType.LONG, linkLong));
|
||||
document.add(new LongPoint(fieldName + "LONG", linkLong));
|
||||
document.add(new DoublePoint(fieldName + "DOUBLE", linkLong));
|
||||
|
||||
if (multipleValuesPerDocument) {
|
||||
document.add(new SortedSetDocValuesField(fieldName, new BytesRef(linkValue)));
|
||||
document.add(new SortedNumericDocValuesField(fieldName+ LegacyNumericType.INT, linkInt));
|
||||
document.add(new SortedNumericDocValuesField(fieldName+ "INT", linkInt));
|
||||
document.add(new SortedNumericDocValuesField(fieldName+ "FLOAT", Float.floatToRawIntBits(linkInt)));
|
||||
document.add(new SortedNumericDocValuesField(fieldName+ LegacyNumericType.LONG, linkLong));
|
||||
document.add(new SortedNumericDocValuesField(fieldName+ "LONG", linkLong));
|
||||
document.add(new SortedNumericDocValuesField(fieldName+ "DOUBLE", Double.doubleToRawLongBits(linkLong)));
|
||||
} else {
|
||||
document.add(new SortedDocValuesField(fieldName, new BytesRef(linkValue)));
|
||||
document.add(new NumericDocValuesField(fieldName+ LegacyNumericType.INT, linkInt));
|
||||
document.add(new NumericDocValuesField(fieldName+ "INT", linkInt));
|
||||
document.add(new FloatDocValuesField(fieldName+ "FLOAT", linkInt));
|
||||
document.add(new NumericDocValuesField(fieldName+ LegacyNumericType.LONG, linkLong));
|
||||
document.add(new NumericDocValuesField(fieldName+ "LONG", linkLong));
|
||||
document.add(new DoubleDocValuesField(fieldName+ "DOUBLE", linkLong));
|
||||
}
|
||||
if (globalOrdinalJoin) {
|
||||
|
|
|
@ -25,17 +25,15 @@
|
|||
<path id="classpath">
|
||||
<pathelement path="${queries.jar}"/>
|
||||
<pathelement path="${sandbox.jar}"/>
|
||||
<pathelement path="${backward-codecs.jar}"/>
|
||||
<path refid="base.classpath"/>
|
||||
</path>
|
||||
|
||||
<target name="compile-core" depends="jar-backward-codecs,jar-queries,jar-sandbox,common.compile-core"/>
|
||||
<target name="compile-core" depends="jar-queries,jar-sandbox,common.compile-core"/>
|
||||
|
||||
<target name="javadocs" depends="javadocs-backward-codecs,javadocs-queries,javadocs-sandbox,compile-core,check-javadocs-uptodate"
|
||||
<target name="javadocs" depends="javadocs-queries,javadocs-sandbox,compile-core,check-javadocs-uptodate"
|
||||
unless="javadocs-uptodate-${name}">
|
||||
<invoke-module-javadoc>
|
||||
<links>
|
||||
<link href="../backward-codecs"/>
|
||||
<link href="../queries"/>
|
||||
<link href="../sandbox"/>
|
||||
</links>
|
||||
|
|
|
@ -29,7 +29,6 @@ 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.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;
|
||||
|
@ -293,24 +292,6 @@ public class StandardQueryParser extends QueryParserHelper implements CommonQuer
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
|
|
@ -1,93 +0,0 @@
|
|||
/*
|
||||
* 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.legacy.LegacyNumericRangeQuery;
|
||||
import org.apache.lucene.legacy.LegacyNumericType;
|
||||
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.LegacyNumericConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.LegacyNumericQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.LegacyNumericRangeQueryNode;
|
||||
|
||||
/**
|
||||
* Builds {@link org.apache.lucene.legacy.LegacyNumericRangeQuery}s out of {@link LegacyNumericRangeQueryNode}s.
|
||||
*
|
||||
* @see org.apache.lucene.legacy.LegacyNumericRangeQuery
|
||||
* @see LegacyNumericRangeQueryNode
|
||||
* @deprecated Index with points and use {@link PointRangeQueryNodeBuilder} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public class LegacyNumericRangeQueryNodeBuilder implements StandardQueryBuilder {
|
||||
|
||||
/**
|
||||
* Constructs a {@link LegacyNumericRangeQueryNodeBuilder} object.
|
||||
*/
|
||||
public LegacyNumericRangeQueryNodeBuilder() {
|
||||
// empty constructor
|
||||
}
|
||||
|
||||
@Override
|
||||
public LegacyNumericRangeQuery<? extends Number> build(QueryNode queryNode)
|
||||
throws QueryNodeException {
|
||||
LegacyNumericRangeQueryNode numericRangeNode = (LegacyNumericRangeQueryNode) queryNode;
|
||||
|
||||
LegacyNumericQueryNode lowerNumericNode = numericRangeNode.getLowerBound();
|
||||
LegacyNumericQueryNode upperNumericNode = numericRangeNode.getUpperBound();
|
||||
|
||||
Number lowerNumber = lowerNumericNode.getValue();
|
||||
Number upperNumber = upperNumericNode.getValue();
|
||||
|
||||
LegacyNumericConfig numericConfig = numericRangeNode.getNumericConfig();
|
||||
LegacyNumericType numberType = numericConfig.getType();
|
||||
String field = StringUtils.toString(numericRangeNode.getField());
|
||||
boolean minInclusive = numericRangeNode.isLowerInclusive();
|
||||
boolean maxInclusive = numericRangeNode.isUpperInclusive();
|
||||
int precisionStep = numericConfig.getPrecisionStep();
|
||||
|
||||
switch (numberType) {
|
||||
|
||||
case LONG:
|
||||
return LegacyNumericRangeQuery.newLongRange(field, precisionStep,
|
||||
(Long) lowerNumber, (Long) upperNumber, minInclusive, maxInclusive);
|
||||
|
||||
case INT:
|
||||
return LegacyNumericRangeQuery.newIntRange(field, precisionStep,
|
||||
(Integer) lowerNumber, (Integer) upperNumber, minInclusive,
|
||||
maxInclusive);
|
||||
|
||||
case FLOAT:
|
||||
return LegacyNumericRangeQuery.newFloatRange(field, precisionStep,
|
||||
(Float) lowerNumber, (Float) upperNumber, minInclusive,
|
||||
maxInclusive);
|
||||
|
||||
case DOUBLE:
|
||||
return LegacyNumericRangeQuery.newDoubleRange(field, precisionStep,
|
||||
(Double) lowerNumber, (Double) upperNumber, minInclusive,
|
||||
maxInclusive);
|
||||
|
||||
default :
|
||||
throw new QueryNodeException(new MessageImpl(
|
||||
QueryParserMessages.UNSUPPORTED_NUMERIC_DATA_TYPE, numberType));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -32,8 +32,6 @@ import org.apache.lucene.queryparser.flexible.core.nodes.TokenizedPhraseQueryNod
|
|||
import org.apache.lucene.queryparser.flexible.standard.nodes.MultiPhraseQueryNode;
|
||||
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;
|
||||
|
@ -59,8 +57,6 @@ public class StandardQueryTreeBuilder extends QueryTreeBuilder implements
|
|||
setBuilder(FieldQueryNode.class, new FieldQueryNodeBuilder());
|
||||
setBuilder(BooleanQueryNode.class, new BooleanQueryNodeBuilder());
|
||||
setBuilder(FuzzyQueryNode.class, new FuzzyQueryNodeBuilder());
|
||||
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());
|
||||
|
|
|
@ -1,165 +0,0 @@
|
|||
/*
|
||||
* 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 java.util.Objects;
|
||||
|
||||
import org.apache.lucene.legacy.LegacyNumericType;
|
||||
|
||||
/**
|
||||
* This class holds the configuration used to parse numeric queries and create
|
||||
* {@link org.apache.lucene.legacy.LegacyNumericRangeQuery}s.
|
||||
*
|
||||
* @see org.apache.lucene.legacy.LegacyNumericRangeQuery
|
||||
* @see NumberFormat
|
||||
* @deprecated Index with Points instead and use {@link PointsConfig}
|
||||
*/
|
||||
@Deprecated
|
||||
public class LegacyNumericConfig {
|
||||
|
||||
private int precisionStep;
|
||||
|
||||
private NumberFormat format;
|
||||
|
||||
private LegacyNumericType type;
|
||||
|
||||
/**
|
||||
* Constructs a {@link LegacyNumericConfig} object.
|
||||
*
|
||||
* @param precisionStep
|
||||
* the precision used to index the numeric values
|
||||
* @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 LegacyNumericConfig#setPrecisionStep(int)
|
||||
* @see LegacyNumericConfig#setNumberFormat(NumberFormat)
|
||||
* @see #setType(LegacyNumericType)
|
||||
*/
|
||||
public LegacyNumericConfig(int precisionStep, NumberFormat format,
|
||||
LegacyNumericType type) {
|
||||
setPrecisionStep(precisionStep);
|
||||
setNumberFormat(format);
|
||||
setType(type);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the precision used to index the numeric values
|
||||
*
|
||||
* @return the precision used to index the numeric values
|
||||
*
|
||||
* @see org.apache.lucene.legacy.LegacyNumericRangeQuery#getPrecisionStep()
|
||||
*/
|
||||
public int getPrecisionStep() {
|
||||
return precisionStep;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the precision used to index the numeric values
|
||||
*
|
||||
* @param precisionStep
|
||||
* the precision used to index the numeric values
|
||||
*
|
||||
* @see org.apache.lucene.legacy.LegacyNumericRangeQuery#getPrecisionStep()
|
||||
*/
|
||||
public void setPrecisionStep(int precisionStep) {
|
||||
this.precisionStep = precisionStep;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 LegacyNumericType 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(LegacyNumericType type) {
|
||||
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("type must not be null!");
|
||||
}
|
||||
|
||||
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}, must not be <code>null</code>
|
||||
*/
|
||||
public void setNumberFormat(NumberFormat format) {
|
||||
|
||||
if (format == null) {
|
||||
throw new IllegalArgumentException("format must not be null!");
|
||||
}
|
||||
|
||||
this.format = format;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (obj == this) return true;
|
||||
|
||||
if (obj instanceof LegacyNumericConfig) {
|
||||
LegacyNumericConfig other = (LegacyNumericConfig) obj;
|
||||
|
||||
if (this.precisionStep == other.precisionStep
|
||||
&& this.type == other.type
|
||||
&& (this.format == other.format || (this.format.equals(other.format)))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(precisionStep, type, format);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* 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#LEGACY_NUMERIC_CONFIG}
|
||||
* based on the {@link ConfigurationKeys#LEGACY_NUMERIC_CONFIG_MAP} set in the
|
||||
* {@link QueryConfigHandler}.
|
||||
*
|
||||
* @see LegacyNumericConfig
|
||||
* @see QueryConfigHandler
|
||||
* @see ConfigurationKeys#LEGACY_NUMERIC_CONFIG
|
||||
* @see ConfigurationKeys#LEGACY_NUMERIC_CONFIG_MAP
|
||||
* @deprecated Index with Points instead and use {@link PointsConfigListener}
|
||||
*/
|
||||
@Deprecated
|
||||
public class LegacyNumericFieldConfigListener implements FieldConfigListener {
|
||||
|
||||
final private QueryConfigHandler config;
|
||||
|
||||
/**
|
||||
* Constructs a {@link LegacyNumericFieldConfigListener} object using the given {@link QueryConfigHandler}.
|
||||
*
|
||||
* @param config the {@link QueryConfigHandler} it will listen too
|
||||
*/
|
||||
public LegacyNumericFieldConfigListener(QueryConfigHandler config) {
|
||||
|
||||
if (config == null) {
|
||||
throw new IllegalArgumentException("config must not be null!");
|
||||
}
|
||||
|
||||
this.config = config;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildFieldConfig(FieldConfig fieldConfig) {
|
||||
Map<String,LegacyNumericConfig> numericConfigMap = config
|
||||
.get(ConfigurationKeys.LEGACY_NUMERIC_CONFIG_MAP);
|
||||
|
||||
if (numericConfigMap != null) {
|
||||
LegacyNumericConfig numericConfig = numericConfigMap
|
||||
.get(fieldConfig.getField());
|
||||
|
||||
if (numericConfig != null) {
|
||||
fieldConfig.set(ConfigurationKeys.LEGACY_NUMERIC_CONFIG, numericConfig);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -158,39 +158,19 @@ public class StandardQueryConfigHandler extends QueryConfigHandler {
|
|||
*/
|
||||
final public static ConfigurationKey<Float> BOOST = ConfigurationKey.newInstance();
|
||||
|
||||
/**
|
||||
* Key used to set a field to its {@link LegacyNumericConfig}.
|
||||
*
|
||||
* @see StandardQueryParser#setLegacyNumericConfigMap(Map)
|
||||
* @see StandardQueryParser#getLegacyNumericConfigMap()
|
||||
* @deprecated Index with Points instead and use {@link #POINTS_CONFIG}
|
||||
*/
|
||||
@Deprecated
|
||||
final public static ConfigurationKey<LegacyNumericConfig> LEGACY_NUMERIC_CONFIG = ConfigurationKey.newInstance();
|
||||
|
||||
/**
|
||||
* Key used to set the {@link LegacyNumericConfig} in {@link FieldConfig} for numeric fields.
|
||||
*
|
||||
* @see StandardQueryParser#setLegacyNumericConfigMap(Map)
|
||||
* @see StandardQueryParser#getLegacyNumericConfigMap()
|
||||
* @deprecated Index with Points instead and use {@link #POINTS_CONFIG_MAP}
|
||||
*/
|
||||
@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()
|
||||
* @see StandardQueryParser#setPointsConfigMap(Map)
|
||||
* @see StandardQueryParser#getPointsConfigMap()
|
||||
*/
|
||||
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()
|
||||
* @see StandardQueryParser#setPointsConfigMap(Map)
|
||||
* @see StandardQueryParser#getPointsConfigMap()
|
||||
*/
|
||||
final public static ConfigurationKey<Map<String,PointsConfig>> POINTS_CONFIG_MAP = ConfigurationKey.newInstance();
|
||||
|
||||
|
@ -207,7 +187,6 @@ public class StandardQueryConfigHandler extends QueryConfigHandler {
|
|||
// Add listener that will build the FieldConfig.
|
||||
addFieldConfigListener(new FieldBoostMapFCListener(this));
|
||||
addFieldConfigListener(new FieldDateResolutionFCListener(this));
|
||||
addFieldConfigListener(new LegacyNumericFieldConfigListener(this));
|
||||
addFieldConfigListener(new PointsConfigListener(this));
|
||||
|
||||
// Default Values
|
||||
|
|
|
@ -1,153 +0,0 @@
|
|||
/*
|
||||
* 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) + "'/>";
|
||||
}
|
||||
|
||||
}
|
|
@ -1,152 +0,0 @@
|
|||
/*
|
||||
* 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.legacy.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.LegacyNumericConfig;
|
||||
|
||||
/**
|
||||
* This query node represents a range query composed by {@link LegacyNumericQueryNode}
|
||||
* bounds, which means the bound values are {@link Number}s.
|
||||
*
|
||||
* @see LegacyNumericQueryNode
|
||||
* @see AbstractRangeQueryNode
|
||||
* @deprecated Index with Points instead and use {@link PointRangeQueryNode} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public class LegacyNumericRangeQueryNode extends
|
||||
AbstractRangeQueryNode<LegacyNumericQueryNode> {
|
||||
|
||||
public LegacyNumericConfig 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 LegacyNumericConfig} that represents associated with the upper and lower bounds
|
||||
*
|
||||
* @see #setBounds(LegacyNumericQueryNode, LegacyNumericQueryNode, boolean, boolean, LegacyNumericConfig)
|
||||
*/
|
||||
public LegacyNumericRangeQueryNode(LegacyNumericQueryNode lower, LegacyNumericQueryNode upper,
|
||||
boolean lowerInclusive, boolean upperInclusive, LegacyNumericConfig numericConfig) throws QueryNodeException {
|
||||
setBounds(lower, upper, lowerInclusive, upperInclusive, numericConfig);
|
||||
}
|
||||
|
||||
private static LegacyNumericType getNumericDataType(Number number) throws QueryNodeException {
|
||||
|
||||
if (number instanceof Long) {
|
||||
return LegacyNumericType.LONG;
|
||||
} else if (number instanceof Integer) {
|
||||
return LegacyNumericType.INT;
|
||||
} else if (number instanceof Double) {
|
||||
return LegacyNumericType.DOUBLE;
|
||||
} else if (number instanceof Float) {
|
||||
return LegacyNumericType.FLOAT;
|
||||
} else {
|
||||
throw new QueryNodeException(
|
||||
new MessageImpl(
|
||||
QueryParserMessages.NUMBER_CLASS_NOT_SUPPORTED_BY_NUMERIC_RANGE_QUERY,
|
||||
number.getClass()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the upper and lower bounds of this range query node and the
|
||||
* {@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 LegacyNumericConfig} that represents associated with the upper and lower bounds
|
||||
*
|
||||
*/
|
||||
public void setBounds(LegacyNumericQueryNode lower, LegacyNumericQueryNode upper,
|
||||
boolean lowerInclusive, boolean upperInclusive, LegacyNumericConfig numericConfig) throws QueryNodeException {
|
||||
|
||||
if (numericConfig == null) {
|
||||
throw new IllegalArgumentException("numericConfig must not be null!");
|
||||
}
|
||||
|
||||
LegacyNumericType lowerNumberType, upperNumberType;
|
||||
|
||||
if (lower != null && lower.getValue() != null) {
|
||||
lowerNumberType = getNumericDataType(lower.getValue());
|
||||
} else {
|
||||
lowerNumberType = null;
|
||||
}
|
||||
|
||||
if (upper != null && upper.getValue() != null) {
|
||||
upperNumberType = getNumericDataType(upper.getValue());
|
||||
} else {
|
||||
upperNumberType = null;
|
||||
}
|
||||
|
||||
if (lowerNumberType != null
|
||||
&& !lowerNumberType.equals(numericConfig.getType())) {
|
||||
throw new IllegalArgumentException(
|
||||
"lower value's type should be the same as numericConfig type: "
|
||||
+ lowerNumberType + " != " + numericConfig.getType());
|
||||
}
|
||||
|
||||
if (upperNumberType != null
|
||||
&& !upperNumberType.equals(numericConfig.getType())) {
|
||||
throw new IllegalArgumentException(
|
||||
"upper value's type should be the same as numericConfig type: "
|
||||
+ upperNumberType + " != " + numericConfig.getType());
|
||||
}
|
||||
|
||||
super.setBounds(lower, upper, lowerInclusive, upperInclusive);
|
||||
this.numericConfig = numericConfig;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link LegacyNumericConfig} associated with the lower and upper bounds.
|
||||
*
|
||||
* @return the {@link LegacyNumericConfig} associated with the lower and upper bounds
|
||||
*/
|
||||
public LegacyNumericConfig getNumericConfig() {
|
||||
return this.numericConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder("<numericRange lowerInclusive='");
|
||||
|
||||
sb.append(isLowerInclusive()).append("' upperInclusive='").append(
|
||||
isUpperInclusive()).append(
|
||||
"' precisionStep='" + numericConfig.getPrecisionStep()).append(
|
||||
"' type='" + numericConfig.getType()).append("'>\n");
|
||||
|
||||
sb.append(getLowerBound()).append('\n');
|
||||
sb.append(getUpperBound()).append('\n');
|
||||
sb.append("</numericRange>");
|
||||
|
||||
return sb.toString();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,154 +0,0 @@
|
|||
/*
|
||||
* 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.LegacyNumericConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
|
||||
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 LegacyNumericRangeQueryNode}s. It looks for
|
||||
* {@link ConfigurationKeys#LEGACY_NUMERIC_CONFIG} set in the {@link FieldConfig} of
|
||||
* every {@link FieldQueryNode} found. If
|
||||
* {@link ConfigurationKeys#LEGACY_NUMERIC_CONFIG} is found, it considers that
|
||||
* {@link FieldQueryNode} to be a numeric query and convert it to
|
||||
* {@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>
|
||||
* <br>
|
||||
* Note that {@link FieldQueryNode}s children of a
|
||||
* {@link RangeQueryNode} are ignored.
|
||||
*
|
||||
* @see ConfigurationKeys#LEGACY_NUMERIC_CONFIG
|
||||
* @see FieldQueryNode
|
||||
* @see LegacyNumericConfig
|
||||
* @see LegacyNumericQueryNode
|
||||
* @deprecated Index with points and use {@link PointQueryNodeProcessor} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public class LegacyNumericQueryNodeProcessor extends QueryNodeProcessorImpl {
|
||||
|
||||
/**
|
||||
* Constructs a {@link LegacyNumericQueryNodeProcessor} object.
|
||||
*/
|
||||
public LegacyNumericQueryNodeProcessor() {
|
||||
// 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) {
|
||||
LegacyNumericConfig numericConfig = fieldConfig
|
||||
.get(ConfigurationKeys.LEGACY_NUMERIC_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);
|
||||
}
|
||||
|
||||
switch (numericConfig.getType()) {
|
||||
case LONG:
|
||||
number = number.longValue();
|
||||
break;
|
||||
case INT:
|
||||
number = number.intValue();
|
||||
break;
|
||||
case DOUBLE:
|
||||
number = number.doubleValue();
|
||||
break;
|
||||
case FLOAT:
|
||||
number = number.floatValue();
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new QueryNodeParseException(new MessageImpl(
|
||||
QueryParserMessages.NUMERIC_CANNOT_BE_EMPTY, fieldNode.getFieldAsString()));
|
||||
}
|
||||
|
||||
LegacyNumericQueryNode lowerNode = new LegacyNumericQueryNode(fieldNode
|
||||
.getField(), number, numberFormat);
|
||||
LegacyNumericQueryNode upperNode = new LegacyNumericQueryNode(fieldNode
|
||||
.getField(), number, numberFormat);
|
||||
|
||||
return new LegacyNumericRangeQueryNode(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;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,170 +0,0 @@
|
|||
/*
|
||||
* 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.LegacyNumericConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
|
||||
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 LegacyNumericRangeQueryNode}s. It looks for
|
||||
* {@link ConfigurationKeys#LEGACY_NUMERIC_CONFIG} set in the {@link FieldConfig} of
|
||||
* every {@link TermRangeQueryNode} found. If
|
||||
* {@link ConfigurationKeys#LEGACY_NUMERIC_CONFIG} is found, it considers that
|
||||
* {@link TermRangeQueryNode} to be a numeric range query and convert it to
|
||||
* {@link LegacyNumericRangeQueryNode}.
|
||||
*
|
||||
* @see ConfigurationKeys#LEGACY_NUMERIC_CONFIG
|
||||
* @see TermRangeQueryNode
|
||||
* @see LegacyNumericConfig
|
||||
* @see LegacyNumericRangeQueryNode
|
||||
* @deprecated Index with points and use {@link PointRangeQueryNodeProcessor} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public class LegacyNumericRangeQueryNodeProcessor extends QueryNodeProcessorImpl {
|
||||
|
||||
/**
|
||||
* Constructs an empty {@link LegacyNumericRangeQueryNode} object.
|
||||
*/
|
||||
public LegacyNumericRangeQueryNodeProcessor() {
|
||||
// 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) {
|
||||
|
||||
LegacyNumericConfig numericConfig = fieldConfig
|
||||
.get(ConfigurationKeys.LEGACY_NUMERIC_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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
switch (numericConfig.getType()) {
|
||||
case LONG:
|
||||
if (upperNumber != null) upperNumber = upperNumber.longValue();
|
||||
if (lowerNumber != null) lowerNumber = lowerNumber.longValue();
|
||||
break;
|
||||
case INT:
|
||||
if (upperNumber != null) upperNumber = upperNumber.intValue();
|
||||
if (lowerNumber != null) lowerNumber = lowerNumber.intValue();
|
||||
break;
|
||||
case DOUBLE:
|
||||
if (upperNumber != null) upperNumber = upperNumber.doubleValue();
|
||||
if (lowerNumber != null) lowerNumber = lowerNumber.doubleValue();
|
||||
break;
|
||||
case FLOAT:
|
||||
if (upperNumber != null) upperNumber = upperNumber.floatValue();
|
||||
if (lowerNumber != null) lowerNumber = lowerNumber.floatValue();
|
||||
}
|
||||
|
||||
LegacyNumericQueryNode lowerNode = new LegacyNumericQueryNode(
|
||||
termRangeNode.getField(), lowerNumber, numberFormat);
|
||||
LegacyNumericQueryNode upperNode = new LegacyNumericQueryNode(
|
||||
termRangeNode.getField(), upperNumber, numberFormat);
|
||||
|
||||
boolean lowerInclusive = termRangeNode.isLowerInclusive();
|
||||
boolean upperInclusive = termRangeNode.isUpperInclusive();
|
||||
|
||||
return new LegacyNumericRangeQueryNode(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;
|
||||
}
|
||||
|
||||
}
|
|
@ -53,8 +53,6 @@ public class StandardQueryNodeProcessorPipeline extends
|
|||
add(new RegexpQueryNodeProcessor());
|
||||
add(new MatchAllDocsQueryNodeProcessor());
|
||||
add(new OpenRangeQueryNodeProcessor());
|
||||
add(new LegacyNumericQueryNodeProcessor());
|
||||
add(new LegacyNumericRangeQueryNodeProcessor());
|
||||
add(new PointQueryNodeProcessor());
|
||||
add(new PointRangeQueryNodeProcessor());
|
||||
add(new TermRangeQueryNodeProcessor());
|
||||
|
|
|
@ -71,7 +71,6 @@ public class CoreParser implements QueryBuilder {
|
|||
queryFactory.addBuilder("TermsQuery", new TermsQueryBuilder(analyzer));
|
||||
queryFactory.addBuilder("MatchAllDocsQuery", new MatchAllDocsQueryBuilder());
|
||||
queryFactory.addBuilder("BooleanQuery", new BooleanQueryBuilder(queryFactory));
|
||||
queryFactory.addBuilder("LegacyNumericRangeQuery", new LegacyNumericRangeQueryBuilder());
|
||||
queryFactory.addBuilder("PointRangeQuery", new PointRangeQueryBuilder());
|
||||
queryFactory.addBuilder("RangeQuery", new RangeQueryBuilder());
|
||||
queryFactory.addBuilder("DisjunctionMaxQuery", new DisjunctionMaxQueryBuilder(queryFactory));
|
||||
|
|
|
@ -1,535 +0,0 @@
|
|||
/*
|
||||
* 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.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.analysis.MockAnalyzer;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.RandomIndexWriter;
|
||||
import org.apache.lucene.legacy.LegacyDoubleField;
|
||||
import org.apache.lucene.legacy.LegacyFieldType;
|
||||
import org.apache.lucene.legacy.LegacyFloatField;
|
||||
import org.apache.lucene.legacy.LegacyIntField;
|
||||
import org.apache.lucene.legacy.LegacyLongField;
|
||||
import org.apache.lucene.legacy.LegacyNumericType;
|
||||
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.LegacyNumericConfig;
|
||||
import org.apache.lucene.queryparser.flexible.standard.parser.EscapeQuerySyntaxImpl;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TopDocs;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.apache.lucene.util.TestUtil;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestLegacyNumericQueryParser extends LuceneTestCase {
|
||||
|
||||
private static enum NumberType {
|
||||
NEGATIVE, ZERO, POSITIVE;
|
||||
}
|
||||
|
||||
final private static int[] DATE_STYLES = {DateFormat.FULL, DateFormat.LONG,
|
||||
DateFormat.MEDIUM, DateFormat.SHORT};
|
||||
|
||||
final private static int PRECISION_STEP = 8;
|
||||
final private static String FIELD_NAME = "field";
|
||||
private static Locale LOCALE;
|
||||
private static TimeZone TIMEZONE;
|
||||
private static Map<String,Number> RANDOM_NUMBER_MAP;
|
||||
private static EscapeQuerySyntax ESCAPER = new EscapeQuerySyntaxImpl();
|
||||
final private static String DATE_FIELD_NAME = "date";
|
||||
private static int DATE_STYLE;
|
||||
private static int TIME_STYLE;
|
||||
|
||||
private static Analyzer ANALYZER;
|
||||
|
||||
private static NumberFormat NUMBER_FORMAT;
|
||||
|
||||
private static StandardQueryParser qp;
|
||||
|
||||
private static NumberDateFormat DATE_FORMAT;
|
||||
|
||||
private static Directory directory = null;
|
||||
private static IndexReader reader = null;
|
||||
private static IndexSearcher searcher = null;
|
||||
|
||||
private static boolean checkDateFormatSanity(DateFormat dateFormat, long date) {
|
||||
try {
|
||||
return date == dateFormat.parse(dateFormat.format(new Date(date)))
|
||||
.getTime();
|
||||
} catch (ParseException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ANALYZER = new MockAnalyzer(random());
|
||||
|
||||
qp = new StandardQueryParser(ANALYZER);
|
||||
|
||||
final HashMap<String,Number> randomNumberMap = new HashMap<>();
|
||||
|
||||
SimpleDateFormat dateFormat;
|
||||
long randomDate;
|
||||
boolean dateFormatSanityCheckPass;
|
||||
int count = 0;
|
||||
do {
|
||||
if (count > 100) {
|
||||
fail("This test has problems to find a sane random DateFormat/NumberFormat. Stopped trying after 100 iterations.");
|
||||
}
|
||||
|
||||
dateFormatSanityCheckPass = true;
|
||||
LOCALE = randomLocale(random());
|
||||
TIMEZONE = randomTimeZone(random());
|
||||
DATE_STYLE = randomDateStyle(random());
|
||||
TIME_STYLE = randomDateStyle(random());
|
||||
|
||||
// assumes localized date pattern will have at least year, month, day,
|
||||
// hour, minute
|
||||
dateFormat = (SimpleDateFormat) DateFormat.getDateTimeInstance(
|
||||
DATE_STYLE, TIME_STYLE, LOCALE);
|
||||
|
||||
// not all date patterns includes era, full year, timezone and second,
|
||||
// so we add them here
|
||||
dateFormat.applyPattern(dateFormat.toPattern() + " G s Z yyyy");
|
||||
dateFormat.setTimeZone(TIMEZONE);
|
||||
|
||||
DATE_FORMAT = new NumberDateFormat(dateFormat);
|
||||
|
||||
do {
|
||||
randomDate = random().nextLong();
|
||||
|
||||
// prune date value so it doesn't pass in insane values to some
|
||||
// calendars.
|
||||
randomDate = randomDate % 3400000000000l;
|
||||
|
||||
// truncate to second
|
||||
randomDate = (randomDate / 1000L) * 1000L;
|
||||
|
||||
// only positive values
|
||||
randomDate = Math.abs(randomDate);
|
||||
} while (randomDate == 0L);
|
||||
|
||||
dateFormatSanityCheckPass &= checkDateFormatSanity(dateFormat, randomDate);
|
||||
|
||||
dateFormatSanityCheckPass &= checkDateFormatSanity(dateFormat, 0);
|
||||
|
||||
dateFormatSanityCheckPass &= checkDateFormatSanity(dateFormat,
|
||||
-randomDate);
|
||||
|
||||
count++;
|
||||
} while (!dateFormatSanityCheckPass);
|
||||
|
||||
NUMBER_FORMAT = NumberFormat.getNumberInstance(LOCALE);
|
||||
NUMBER_FORMAT.setMaximumFractionDigits((random().nextInt() & 20) + 1);
|
||||
NUMBER_FORMAT.setMinimumFractionDigits((random().nextInt() & 20) + 1);
|
||||
NUMBER_FORMAT.setMaximumIntegerDigits((random().nextInt() & 20) + 1);
|
||||
NUMBER_FORMAT.setMinimumIntegerDigits((random().nextInt() & 20) + 1);
|
||||
|
||||
double randomDouble;
|
||||
long randomLong;
|
||||
int randomInt;
|
||||
float randomFloat;
|
||||
|
||||
while ((randomLong = normalizeNumber(Math.abs(random().nextLong()))
|
||||
.longValue()) == 0L)
|
||||
;
|
||||
while ((randomDouble = normalizeNumber(Math.abs(random().nextDouble()))
|
||||
.doubleValue()) == 0.0)
|
||||
;
|
||||
while ((randomFloat = normalizeNumber(Math.abs(random().nextFloat()))
|
||||
.floatValue()) == 0.0f)
|
||||
;
|
||||
while ((randomInt = normalizeNumber(Math.abs(random().nextInt())).intValue()) == 0)
|
||||
;
|
||||
|
||||
randomNumberMap.put(LegacyNumericType.LONG.name(), randomLong);
|
||||
randomNumberMap.put(LegacyNumericType.INT.name(), randomInt);
|
||||
randomNumberMap.put(LegacyNumericType.FLOAT.name(), randomFloat);
|
||||
randomNumberMap.put(LegacyNumericType.DOUBLE.name(), randomDouble);
|
||||
randomNumberMap.put(DATE_FIELD_NAME, randomDate);
|
||||
|
||||
RANDOM_NUMBER_MAP = Collections.unmodifiableMap(randomNumberMap);
|
||||
|
||||
directory = newDirectory();
|
||||
RandomIndexWriter writer = new RandomIndexWriter(random(), directory,
|
||||
newIndexWriterConfig(new MockAnalyzer(random()))
|
||||
.setMaxBufferedDocs(TestUtil.nextInt(random(), 50, 1000))
|
||||
.setMergePolicy(newLogMergePolicy()));
|
||||
|
||||
Document doc = new Document();
|
||||
HashMap<String,LegacyNumericConfig> numericConfigMap = new HashMap<>();
|
||||
HashMap<String,Field> numericFieldMap = new HashMap<>();
|
||||
qp.setLegacyNumericConfigMap(numericConfigMap);
|
||||
|
||||
for (LegacyNumericType type : LegacyNumericType.values()) {
|
||||
numericConfigMap.put(type.name(), new LegacyNumericConfig(PRECISION_STEP,
|
||||
NUMBER_FORMAT, type));
|
||||
|
||||
LegacyFieldType ft = new LegacyFieldType(LegacyIntField.TYPE_NOT_STORED);
|
||||
ft.setNumericType(type);
|
||||
ft.setStored(true);
|
||||
ft.setNumericPrecisionStep(PRECISION_STEP);
|
||||
ft.freeze();
|
||||
final Field field;
|
||||
|
||||
switch(type) {
|
||||
case INT:
|
||||
field = new LegacyIntField(type.name(), 0, ft);
|
||||
break;
|
||||
case FLOAT:
|
||||
field = new LegacyFloatField(type.name(), 0.0f, ft);
|
||||
break;
|
||||
case LONG:
|
||||
field = new LegacyLongField(type.name(), 0l, ft);
|
||||
break;
|
||||
case DOUBLE:
|
||||
field = new LegacyDoubleField(type.name(), 0.0, ft);
|
||||
break;
|
||||
default:
|
||||
fail();
|
||||
field = null;
|
||||
}
|
||||
numericFieldMap.put(type.name(), field);
|
||||
doc.add(field);
|
||||
}
|
||||
|
||||
numericConfigMap.put(DATE_FIELD_NAME, new LegacyNumericConfig(PRECISION_STEP,
|
||||
DATE_FORMAT, LegacyNumericType.LONG));
|
||||
LegacyFieldType ft = new LegacyFieldType(LegacyLongField.TYPE_NOT_STORED);
|
||||
ft.setStored(true);
|
||||
ft.setNumericPrecisionStep(PRECISION_STEP);
|
||||
LegacyLongField dateField = new LegacyLongField(DATE_FIELD_NAME, 0l, ft);
|
||||
numericFieldMap.put(DATE_FIELD_NAME, dateField);
|
||||
doc.add(dateField);
|
||||
|
||||
for (NumberType numberType : NumberType.values()) {
|
||||
setFieldValues(numberType, numericFieldMap);
|
||||
if (VERBOSE) System.out.println("Indexing document: " + doc);
|
||||
writer.addDocument(doc);
|
||||
}
|
||||
|
||||
reader = writer.getReader();
|
||||
searcher = newSearcher(reader);
|
||||
writer.close();
|
||||
|
||||
}
|
||||
|
||||
private static Number getNumberType(NumberType numberType, String fieldName) {
|
||||
|
||||
if (numberType == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (numberType) {
|
||||
|
||||
case POSITIVE:
|
||||
return RANDOM_NUMBER_MAP.get(fieldName);
|
||||
|
||||
case NEGATIVE:
|
||||
Number number = RANDOM_NUMBER_MAP.get(fieldName);
|
||||
|
||||
if (LegacyNumericType.LONG.name().equals(fieldName)
|
||||
|| DATE_FIELD_NAME.equals(fieldName)) {
|
||||
number = -number.longValue();
|
||||
|
||||
} else if (LegacyNumericType.DOUBLE.name().equals(fieldName)) {
|
||||
number = -number.doubleValue();
|
||||
|
||||
} else if (LegacyNumericType.FLOAT.name().equals(fieldName)) {
|
||||
number = -number.floatValue();
|
||||
|
||||
} else if (LegacyNumericType.INT.name().equals(fieldName)) {
|
||||
number = -number.intValue();
|
||||
|
||||
} else {
|
||||
throw new IllegalArgumentException("field name not found: "
|
||||
+ fieldName);
|
||||
}
|
||||
|
||||
return number;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void setFieldValues(NumberType numberType,
|
||||
HashMap<String,Field> numericFieldMap) {
|
||||
|
||||
Number number = getNumberType(numberType, LegacyNumericType.DOUBLE
|
||||
.name());
|
||||
numericFieldMap.get(LegacyNumericType.DOUBLE.name()).setDoubleValue(
|
||||
number.doubleValue());
|
||||
|
||||
number = getNumberType(numberType, LegacyNumericType.INT.name());
|
||||
numericFieldMap.get(LegacyNumericType.INT.name()).setIntValue(
|
||||
number.intValue());
|
||||
|
||||
number = getNumberType(numberType, LegacyNumericType.LONG.name());
|
||||
numericFieldMap.get(LegacyNumericType.LONG.name()).setLongValue(
|
||||
number.longValue());
|
||||
|
||||
number = getNumberType(numberType, LegacyNumericType.FLOAT.name());
|
||||
numericFieldMap.get(LegacyNumericType.FLOAT.name()).setFloatValue(
|
||||
number.floatValue());
|
||||
|
||||
number = getNumberType(numberType, DATE_FIELD_NAME);
|
||||
numericFieldMap.get(DATE_FIELD_NAME).setLongValue(number.longValue());
|
||||
}
|
||||
|
||||
private static int randomDateStyle(Random random) {
|
||||
return DATE_STYLES[random.nextInt(DATE_STYLES.length)];
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInclusiveNumericRange() throws Exception {
|
||||
assertRangeQuery(NumberType.ZERO, NumberType.ZERO, true, true, 1);
|
||||
assertRangeQuery(NumberType.ZERO, NumberType.POSITIVE, true, true, 2);
|
||||
assertRangeQuery(NumberType.NEGATIVE, NumberType.ZERO, true, true, 2);
|
||||
assertRangeQuery(NumberType.NEGATIVE, NumberType.POSITIVE, true, true, 3);
|
||||
assertRangeQuery(NumberType.NEGATIVE, NumberType.NEGATIVE, true, true, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
// test disabled since standard syntax parser does not work with inclusive and
|
||||
// exclusive at the same time
|
||||
public void testInclusiveLowerNumericRange() throws Exception {
|
||||
assertRangeQuery(NumberType.NEGATIVE, NumberType.ZERO, false, true, 1);
|
||||
assertRangeQuery(NumberType.ZERO, NumberType.POSITIVE, false, true, 1);
|
||||
assertRangeQuery(NumberType.NEGATIVE, NumberType.POSITIVE, false, true, 2);
|
||||
assertRangeQuery(NumberType.NEGATIVE, NumberType.NEGATIVE, false, true, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
// test disabled since standard syntax parser does not work with inclusive and
|
||||
// exclusive at the same time
|
||||
public void testInclusiveUpperNumericRange() throws Exception {
|
||||
assertRangeQuery(NumberType.NEGATIVE, NumberType.ZERO, true, false, 1);
|
||||
assertRangeQuery(NumberType.ZERO, NumberType.POSITIVE, true, false, 1);
|
||||
assertRangeQuery(NumberType.NEGATIVE, NumberType.POSITIVE, true, false, 2);
|
||||
assertRangeQuery(NumberType.NEGATIVE, NumberType.NEGATIVE, true, false, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExclusiveNumericRange() throws Exception {
|
||||
assertRangeQuery(NumberType.ZERO, NumberType.ZERO, false, false, 0);
|
||||
assertRangeQuery(NumberType.ZERO, NumberType.POSITIVE, false, false, 0);
|
||||
assertRangeQuery(NumberType.NEGATIVE, NumberType.ZERO, false, false, 0);
|
||||
assertRangeQuery(NumberType.NEGATIVE, NumberType.POSITIVE, false, false, 1);
|
||||
assertRangeQuery(NumberType.NEGATIVE, NumberType.NEGATIVE, false, false, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpenRangeNumericQuery() throws Exception {
|
||||
assertOpenRangeQuery(NumberType.ZERO, "<", 1);
|
||||
assertOpenRangeQuery(NumberType.POSITIVE, "<", 2);
|
||||
assertOpenRangeQuery(NumberType.NEGATIVE, "<", 0);
|
||||
|
||||
assertOpenRangeQuery(NumberType.ZERO, "<=", 2);
|
||||
assertOpenRangeQuery(NumberType.POSITIVE, "<=", 3);
|
||||
assertOpenRangeQuery(NumberType.NEGATIVE, "<=", 1);
|
||||
|
||||
assertOpenRangeQuery(NumberType.ZERO, ">", 1);
|
||||
assertOpenRangeQuery(NumberType.POSITIVE, ">", 0);
|
||||
assertOpenRangeQuery(NumberType.NEGATIVE, ">", 2);
|
||||
|
||||
assertOpenRangeQuery(NumberType.ZERO, ">=", 2);
|
||||
assertOpenRangeQuery(NumberType.POSITIVE, ">=", 1);
|
||||
assertOpenRangeQuery(NumberType.NEGATIVE, ">=", 3);
|
||||
|
||||
assertOpenRangeQuery(NumberType.NEGATIVE, "=", 1);
|
||||
assertOpenRangeQuery(NumberType.ZERO, "=", 1);
|
||||
assertOpenRangeQuery(NumberType.POSITIVE, "=", 1);
|
||||
|
||||
assertRangeQuery(NumberType.NEGATIVE, null, true, true, 3);
|
||||
assertRangeQuery(NumberType.NEGATIVE, null, false, true, 2);
|
||||
assertRangeQuery(NumberType.POSITIVE, null, true, false, 1);
|
||||
assertRangeQuery(NumberType.ZERO, null, false, false, 1);
|
||||
|
||||
assertRangeQuery(null, NumberType.POSITIVE, true, true, 3);
|
||||
assertRangeQuery(null, NumberType.POSITIVE, true, false, 2);
|
||||
assertRangeQuery(null, NumberType.NEGATIVE, false, true, 1);
|
||||
assertRangeQuery(null, NumberType.ZERO, false, false, 1);
|
||||
|
||||
assertRangeQuery(null, null, false, false, 3);
|
||||
assertRangeQuery(null, null, true, true, 3);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleNumericQuery() throws Exception {
|
||||
assertSimpleQuery(NumberType.ZERO, 1);
|
||||
assertSimpleQuery(NumberType.POSITIVE, 1);
|
||||
assertSimpleQuery(NumberType.NEGATIVE, 1);
|
||||
}
|
||||
|
||||
public void assertRangeQuery(NumberType lowerType, NumberType upperType,
|
||||
boolean lowerInclusive, boolean upperInclusive, int expectedDocCount)
|
||||
throws QueryNodeException, IOException {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
String lowerInclusiveStr = (lowerInclusive ? "[" : "{");
|
||||
String upperInclusiveStr = (upperInclusive ? "]" : "}");
|
||||
|
||||
for (LegacyNumericType type : LegacyNumericType.values()) {
|
||||
String lowerStr = numberToString(getNumberType(lowerType, type.name()));
|
||||
String upperStr = numberToString(getNumberType(upperType, type.name()));
|
||||
|
||||
sb.append("+").append(type.name()).append(':').append(lowerInclusiveStr)
|
||||
.append('"').append(lowerStr).append("\" TO \"").append(upperStr)
|
||||
.append('"').append(upperInclusiveStr).append(' ');
|
||||
}
|
||||
|
||||
Number lowerDateNumber = getNumberType(lowerType, DATE_FIELD_NAME);
|
||||
Number upperDateNumber = getNumberType(upperType, DATE_FIELD_NAME);
|
||||
String lowerDateStr;
|
||||
String upperDateStr;
|
||||
|
||||
if (lowerDateNumber != null) {
|
||||
lowerDateStr = ESCAPER.escape(
|
||||
DATE_FORMAT.format(new Date(lowerDateNumber.longValue())), LOCALE,
|
||||
EscapeQuerySyntax.Type.STRING).toString();
|
||||
|
||||
} else {
|
||||
lowerDateStr = "*";
|
||||
}
|
||||
|
||||
if (upperDateNumber != null) {
|
||||
upperDateStr = ESCAPER.escape(
|
||||
DATE_FORMAT.format(new Date(upperDateNumber.longValue())), LOCALE,
|
||||
EscapeQuerySyntax.Type.STRING).toString();
|
||||
|
||||
} else {
|
||||
upperDateStr = "*";
|
||||
}
|
||||
|
||||
sb.append("+").append(DATE_FIELD_NAME).append(':')
|
||||
.append(lowerInclusiveStr).append('"').append(lowerDateStr).append(
|
||||
"\" TO \"").append(upperDateStr).append('"').append(
|
||||
upperInclusiveStr);
|
||||
|
||||
testQuery(sb.toString(), expectedDocCount);
|
||||
|
||||
}
|
||||
|
||||
public void assertOpenRangeQuery(NumberType boundType, String operator, int expectedDocCount)
|
||||
throws QueryNodeException, IOException {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (LegacyNumericType type : LegacyNumericType.values()) {
|
||||
String boundStr = numberToString(getNumberType(boundType, type.name()));
|
||||
|
||||
sb.append("+").append(type.name()).append(operator).append('"').append(boundStr).append('"').append(' ');
|
||||
}
|
||||
|
||||
String boundDateStr = ESCAPER.escape(
|
||||
DATE_FORMAT.format(new Date(getNumberType(boundType, DATE_FIELD_NAME)
|
||||
.longValue())), LOCALE, EscapeQuerySyntax.Type.STRING).toString();
|
||||
|
||||
sb.append("+").append(DATE_FIELD_NAME).append(operator).append('"').append(boundDateStr).append('"');
|
||||
|
||||
testQuery(sb.toString(), expectedDocCount);
|
||||
}
|
||||
|
||||
public void assertSimpleQuery(NumberType numberType, int expectedDocCount)
|
||||
throws QueryNodeException, IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (LegacyNumericType type : LegacyNumericType.values()) {
|
||||
String numberStr = numberToString(getNumberType(numberType, type.name()));
|
||||
sb.append('+').append(type.name()).append(":\"").append(numberStr)
|
||||
.append("\" ");
|
||||
}
|
||||
|
||||
String dateStr = ESCAPER.escape(
|
||||
DATE_FORMAT.format(new Date(getNumberType(numberType, DATE_FIELD_NAME)
|
||||
.longValue())), LOCALE, EscapeQuerySyntax.Type.STRING).toString();
|
||||
|
||||
sb.append('+').append(DATE_FIELD_NAME).append(":\"").append(dateStr)
|
||||
.append('"');
|
||||
|
||||
testQuery(sb.toString(), expectedDocCount);
|
||||
|
||||
}
|
||||
|
||||
private void testQuery(String queryStr, int expectedDocCount)
|
||||
throws QueryNodeException, IOException {
|
||||
if (VERBOSE) System.out.println("Parsing: " + queryStr);
|
||||
|
||||
Query query = qp.parse(queryStr, FIELD_NAME);
|
||||
if (VERBOSE) System.out.println("Querying: " + query);
|
||||
TopDocs topDocs = searcher.search(query, 1000);
|
||||
|
||||
String msg = "Query <" + queryStr + "> retrieved " + topDocs.totalHits
|
||||
+ " document(s), " + expectedDocCount + " document(s) expected.";
|
||||
|
||||
if (VERBOSE) System.out.println(msg);
|
||||
|
||||
assertEquals(msg, expectedDocCount, topDocs.totalHits);
|
||||
}
|
||||
|
||||
private static String numberToString(Number number) {
|
||||
return number == null ? "*" : ESCAPER.escape(NUMBER_FORMAT.format(number),
|
||||
LOCALE, EscapeQuerySyntax.Type.STRING).toString();
|
||||
}
|
||||
|
||||
private static Number normalizeNumber(Number number) throws ParseException {
|
||||
return NUMBER_FORMAT.parse(NUMBER_FORMAT.format(number));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
searcher = null;
|
||||
reader.close();
|
||||
reader = null;
|
||||
directory.close();
|
||||
directory = null;
|
||||
qp = null;
|
||||
LOCALE = null;
|
||||
TIMEZONE = null;
|
||||
NUMBER_FORMAT = null;
|
||||
DATE_FORMAT = null;
|
||||
ESCAPER = null;
|
||||
}
|
||||
|
||||
}
|
|
@ -23,7 +23,6 @@ import org.apache.lucene.document.IntPoint;
|
|||
import org.apache.lucene.index.DirectoryReader;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.legacy.LegacyIntField;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
|
@ -53,7 +52,6 @@ class CoreParserTestIndexData implements Closeable {
|
|||
Document doc = new Document();
|
||||
doc.add(LuceneTestCase.newTextField("date", date, Field.Store.YES));
|
||||
doc.add(LuceneTestCase.newTextField("contents", content, Field.Store.YES));
|
||||
doc.add(new LegacyIntField("date2", Integer.valueOf(date), Field.Store.NO));
|
||||
doc.add(new IntPoint("date3", Integer.valueOf(date)));
|
||||
writer.addDocument(doc);
|
||||
line = d.readLine();
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<BooleanQuery fieldName="contents">
|
||||
<Clause occurs="should">
|
||||
<TermQuery>merger</TermQuery>
|
||||
</Clause>
|
||||
<Clause occurs="mustnot">
|
||||
<TermQuery >sumitomo</TermQuery>
|
||||
</Clause>
|
||||
<Clause occurs="must">
|
||||
<TermQuery>bank</TermQuery>
|
||||
</Clause>
|
||||
<Clause occurs="must">
|
||||
<LegacyNumericRangeQuery fieldName="date2" lowerTerm="19870409" upperTerm="19870412"/>
|
||||
</Clause>
|
||||
</BooleanQuery>
|
|
@ -1,31 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<BooleanQuery fieldName="contents">
|
||||
<Clause occurs="should">
|
||||
<TermQuery>merger</TermQuery>
|
||||
</Clause>
|
||||
<Clause occurs="mustnot">
|
||||
<TermQuery >sumitomo</TermQuery>
|
||||
</Clause>
|
||||
<Clause occurs="must">
|
||||
<TermQuery>bank</TermQuery>
|
||||
</Clause>
|
||||
<Clause occurs="must">
|
||||
<LegacyNumericRangeQuery fieldName="date2" upperTerm="19870412"/>
|
||||
</Clause>
|
||||
</BooleanQuery>
|
|
@ -1,31 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<BooleanQuery fieldName="contents">
|
||||
<Clause occurs="should">
|
||||
<TermQuery>merger</TermQuery>
|
||||
</Clause>
|
||||
<Clause occurs="mustnot">
|
||||
<TermQuery >sumitomo</TermQuery>
|
||||
</Clause>
|
||||
<Clause occurs="must">
|
||||
<TermQuery>bank</TermQuery>
|
||||
</Clause>
|
||||
<Clause occurs="must">
|
||||
<LegacyNumericRangeQuery fieldName="date2"/>
|
||||
</Clause>
|
||||
</BooleanQuery>
|
|
@ -1,31 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<BooleanQuery fieldName="contents">
|
||||
<Clause occurs="should">
|
||||
<TermQuery>merger</TermQuery>
|
||||
</Clause>
|
||||
<Clause occurs="mustnot">
|
||||
<TermQuery >sumitomo</TermQuery>
|
||||
</Clause>
|
||||
<Clause occurs="must">
|
||||
<TermQuery>bank</TermQuery>
|
||||
</Clause>
|
||||
<Clause occurs="must">
|
||||
<LegacyNumericRangeQuery fieldName="date2" lowerTerm="19870409"/>
|
||||
</Clause>
|
||||
</BooleanQuery>
|
|
@ -132,26 +132,6 @@ public class TestCoreParser extends LuceneTestCase {
|
|||
Query q = parse("NestedBooleanQuery.xml");
|
||||
dumpResults("Nested Boolean query", q, 5);
|
||||
}
|
||||
|
||||
public void testNumericRangeQueryXML() throws ParserException, IOException {
|
||||
Query q = parse("LegacyNumericRangeQuery.xml");
|
||||
dumpResults("LegacyNumericRangeQuery", q, 5);
|
||||
}
|
||||
|
||||
public void testNumericRangeQueryXMLWithoutLowerTerm() throws ParserException, IOException {
|
||||
Query q = parse("LegacyNumericRangeQueryWithoutLowerTerm.xml");
|
||||
dumpResults("LegacyNumericRangeQueryWithoutLowerTerm", q, 5);
|
||||
}
|
||||
|
||||
public void testNumericRangeQueryXMLWithoutUpperTerm() throws ParserException, IOException {
|
||||
Query q = parse("LegacyNumericRangeQueryWithoutUpperTerm.xml");
|
||||
dumpResults("LegacyNumericRangeQueryWithoutUpperTerm", q, 5);
|
||||
}
|
||||
|
||||
public void testNumericRangeQueryXMLWithoutRange() throws ParserException, IOException {
|
||||
Query q = parse("LegacyNumericRangeQueryWithoutRange.xml");
|
||||
dumpResults("LegacyNumericRangeQueryWithoutRange", q, 5);
|
||||
}
|
||||
|
||||
public void testPointRangeQuery() throws ParserException, IOException {
|
||||
Query q = parse("PointRangeQuery.xml");
|
||||
|
|
|
@ -63,12 +63,31 @@ Apache UIMA 2.3.1
|
|||
Apache ZooKeeper 3.4.6
|
||||
Jetty 9.3.8.v20160314
|
||||
|
||||
Detailed Change List
|
||||
----------------------
|
||||
|
||||
New Features
|
||||
----------------------
|
||||
|
||||
Bug Fixes
|
||||
----------------------
|
||||
|
||||
* SOLR-9310: PeerSync fails on a node restart due to IndexFingerPrint mismatch (Pushkar Raste, noble)
|
||||
|
||||
Other Changes
|
||||
----------------------
|
||||
|
||||
* SOLR-9412: Add failOnMissingParams option to MacroExpander, add TestMacroExpander class.
|
||||
(Jon Dorando, Christine Poerschke)
|
||||
|
||||
Optimizations
|
||||
----------------------
|
||||
|
||||
Other Changes
|
||||
----------------------
|
||||
|
||||
* SOLR-7362: Fix TestReqParamsAPI test failures (noble, Varun Thacker)
|
||||
|
||||
================== 6.2.0 ==================
|
||||
|
||||
Versions of Major Components
|
||||
|
|
|
@ -29,6 +29,7 @@ import java.util.Map;
|
|||
import com.google.common.collect.ImmutableMap;
|
||||
import org.apache.solr.cloud.ZkSolrResourceLoader;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.common.cloud.SolrZkClient;
|
||||
import org.apache.solr.common.params.MapSolrParams;
|
||||
import org.apache.solr.common.util.Utils;
|
||||
import org.apache.zookeeper.KeeperException;
|
||||
|
@ -156,10 +157,8 @@ public class RequestParams implements MapSerializable {
|
|||
requestParams = new RequestParams((Map) o[0], (Integer) o[1]);
|
||||
log.info("request params refreshed to version {}", requestParams.getZnodeVersion());
|
||||
}
|
||||
} catch (KeeperException e) {
|
||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (KeeperException | InterruptedException e) {
|
||||
SolrZkClient.checkInterrupted(e);
|
||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
|
||||
}
|
||||
|
||||
|
|
|
@ -188,12 +188,12 @@ public class SolrConfigHandler extends RequestHandlerBase implements SolrCoreAwa
|
|||
resp.add(ZNODEVER, Utils.makeMap(
|
||||
ConfigOverlay.NAME, req.getCore().getSolrConfig().getOverlay().getZnodeVersion(),
|
||||
RequestParams.NAME, req.getCore().getSolrConfig().getRequestParams().getZnodeVersion()));
|
||||
boolean checkStale = false;
|
||||
boolean isStale = false;
|
||||
int expectedVersion = req.getParams().getInt(ConfigOverlay.NAME, -1);
|
||||
int actualVersion = req.getCore().getSolrConfig().getOverlay().getZnodeVersion();
|
||||
if (expectedVersion > actualVersion) {
|
||||
log.info("expecting overlay version {} but my version is {}", expectedVersion, actualVersion);
|
||||
checkStale = true;
|
||||
isStale = true;
|
||||
} else if (expectedVersion != -1) {
|
||||
log.info("I already have the expected version {} of config", expectedVersion);
|
||||
}
|
||||
|
@ -201,11 +201,11 @@ public class SolrConfigHandler extends RequestHandlerBase implements SolrCoreAwa
|
|||
actualVersion = req.getCore().getSolrConfig().getRequestParams().getZnodeVersion();
|
||||
if (expectedVersion > actualVersion) {
|
||||
log.info("expecting params version {} but my version is {}", expectedVersion, actualVersion);
|
||||
checkStale = true;
|
||||
isStale = true;
|
||||
} else if (expectedVersion != -1) {
|
||||
log.info("I already have the expected version {} of params", expectedVersion);
|
||||
}
|
||||
if (checkStale && req.getCore().getResourceLoader() instanceof ZkSolrResourceLoader) {
|
||||
if (isStale && req.getCore().getResourceLoader() instanceof ZkSolrResourceLoader) {
|
||||
new Thread(() -> {
|
||||
if (!reloadLock.tryLock()) {
|
||||
log.info("Another reload is in progress . Not doing anything");
|
||||
|
@ -221,7 +221,7 @@ public class SolrConfigHandler extends RequestHandlerBase implements SolrCoreAwa
|
|||
}
|
||||
}, SolrConfigHandler.class.getSimpleName() + "-refreshconf").start();
|
||||
} else {
|
||||
log.info("checkStale {} , resourceloader {}", checkStale, req.getCore().getResourceLoader().getClass().getName());
|
||||
log.info("isStale {} , resourceloader {}", isStale, req.getCore().getResourceLoader().getClass().getName());
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -287,7 +287,7 @@ public class SolrConfigHandler extends RequestHandlerBase implements SolrCoreAwa
|
|||
|
||||
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||
|
||||
Map val = null;
|
||||
Map val;
|
||||
String key = entry.getKey();
|
||||
if (isNullOrEmpty(key)) {
|
||||
op.addError("null key ");
|
||||
|
@ -354,16 +354,13 @@ public class SolrConfigHandler extends RequestHandlerBase implements SolrCoreAwa
|
|||
if (ops.isEmpty()) {
|
||||
ZkController.touchConfDir(zkLoader);
|
||||
} else {
|
||||
log.info("persisting params data : {}", Utils.toJSONString(params.toMap()));
|
||||
log.debug("persisting params data : {}", Utils.toJSONString(params.toMap()));
|
||||
int latestVersion = ZkController.persistConfigResourceToZooKeeper(zkLoader,
|
||||
params.getZnodeVersion(),
|
||||
RequestParams.RESOURCE,
|
||||
params.toByteArray(), true);
|
||||
log.info("persisted to version : {} ", latestVersion);
|
||||
params.getZnodeVersion(), RequestParams.RESOURCE, params.toByteArray(), true);
|
||||
|
||||
log.debug("persisted to version : {} ", latestVersion);
|
||||
waitForAllReplicasState(req.getCore().getCoreDescriptor().getCloudDescriptor().getCollectionName(),
|
||||
req.getCore().getCoreDescriptor().getCoreContainer().getZkController(),
|
||||
RequestParams.NAME,
|
||||
latestVersion, 30);
|
||||
req.getCore().getCoreDescriptor().getCoreContainer().getZkController(), RequestParams.NAME, latestVersion, 30);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
|
@ -34,10 +34,16 @@ public class MacroExpander {
|
|||
private String macroStart = MACRO_START;
|
||||
private char escape = '\\';
|
||||
private int level;
|
||||
private final boolean failOnMissingParams;
|
||||
|
||||
|
||||
public MacroExpander(Map<String,String[]> orig) {
|
||||
this(orig, false);
|
||||
}
|
||||
|
||||
public MacroExpander(Map<String,String[]> orig, boolean failOnMissingParams) {
|
||||
this.orig = orig;
|
||||
this.failOnMissingParams = failOnMissingParams;
|
||||
}
|
||||
|
||||
public static Map<String,String[]> expand(Map<String,String[]> params) {
|
||||
|
@ -163,8 +169,14 @@ public class MacroExpander {
|
|||
String replacement = replacementList!=null ? replacementList[0] : defVal;
|
||||
if (replacement != null) {
|
||||
String expandedReplacement = expand(replacement);
|
||||
if (failOnMissingParams && expandedReplacement == null) {
|
||||
return null;
|
||||
}
|
||||
sb.append(expandedReplacement);
|
||||
}
|
||||
else if (failOnMissingParams) {
|
||||
return null;
|
||||
}
|
||||
|
||||
} catch (SyntaxError syntaxError) {
|
||||
// append the part we would have skipped
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.lucene.queryparser.xml.builders;
|
||||
package org.apache.solr.search;
|
||||
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.legacy.LegacyNumericRangeQuery;
|
||||
|
@ -22,6 +22,7 @@ import org.apache.lucene.legacy.LegacyNumericUtils;
|
|||
import org.apache.lucene.queryparser.xml.DOMUtils;
|
||||
import org.apache.lucene.queryparser.xml.ParserException;
|
||||
import org.apache.lucene.queryparser.xml.QueryBuilder;
|
||||
import org.apache.lucene.queryparser.xml.builders.PointRangeQueryBuilder;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
|
@ -21,7 +21,6 @@ import java.util.Map;
|
|||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.queryparser.xml.CoreParser;
|
||||
import org.apache.lucene.queryparser.xml.QueryBuilder;
|
||||
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
import org.apache.solr.core.SolrResourceLoader;
|
||||
import org.apache.solr.request.SolrQueryRequest;
|
||||
|
@ -38,6 +37,7 @@ public class SolrCoreParser extends CoreParser implements NamedListInitializedPl
|
|||
public SolrCoreParser(String defaultField, Analyzer analyzer,
|
||||
SolrQueryRequest req) {
|
||||
super(defaultField, analyzer);
|
||||
queryFactory.addBuilder("LegacyNumericRangeQuery", new LegacyNumericRangeQueryBuilder());
|
||||
this.req = req;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,9 +22,10 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.apache.solr.client.solrj.SolrClient;
|
||||
import org.apache.solr.client.solrj.impl.HttpSolrClient;
|
||||
import org.apache.solr.client.solrj.embedded.JettySolrRunner;
|
||||
import org.apache.solr.client.solrj.impl.CloudSolrClient;
|
||||
import org.apache.solr.cloud.AbstractFullDistribZkTestBase;
|
||||
import org.apache.solr.cloud.SolrCloudTestCase;
|
||||
import org.apache.solr.common.cloud.DocCollection;
|
||||
import org.apache.solr.common.cloud.Replica;
|
||||
import org.apache.solr.common.cloud.Slice;
|
||||
|
@ -32,37 +33,48 @@ import org.apache.solr.common.cloud.ZkStateReader;
|
|||
import org.apache.solr.core.RequestParams;
|
||||
import org.apache.solr.core.TestSolrConfigHandler;
|
||||
import org.apache.solr.util.RestTestHarness;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.apache.solr.handler.TestSolrConfigHandlerCloud.compareValues;
|
||||
|
||||
public class TestReqParamsAPI extends AbstractFullDistribZkTestBase {
|
||||
public class TestReqParamsAPI extends SolrCloudTestCase {
|
||||
private List<RestTestHarness> restTestHarnesses = new ArrayList<>();
|
||||
|
||||
private static String COLL_NAME = "collection1";
|
||||
|
||||
private void setupHarnesses() {
|
||||
for (final SolrClient client : clients) {
|
||||
RestTestHarness harness = new RestTestHarness(() -> ((HttpSolrClient) client).getBaseURL());
|
||||
for (final JettySolrRunner jettySolrRunner : cluster.getJettySolrRunners()) {
|
||||
RestTestHarness harness = new RestTestHarness(() -> jettySolrRunner.getBaseUrl().toString() + "/" + COLL_NAME);
|
||||
restTestHarnesses.add(harness);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void distribTearDown() throws Exception {
|
||||
super.distribTearDown();
|
||||
for (RestTestHarness r : restTestHarnesses) {
|
||||
r.close();
|
||||
}
|
||||
@BeforeClass
|
||||
public static void createCluster() throws Exception {
|
||||
System.setProperty("managed.schema.mutable", "true");
|
||||
configureCluster(2)
|
||||
.addConfig("conf1", TEST_PATH().resolve("configsets").resolve("cloud-managed").resolve("conf"))
|
||||
.configure();
|
||||
cluster.createCollection(COLL_NAME, 1, 2, "conf1", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
setupHarnesses();
|
||||
testReqParams();
|
||||
try {
|
||||
setupHarnesses();
|
||||
testReqParams();
|
||||
} finally {
|
||||
for (RestTestHarness r : restTestHarnesses) {
|
||||
r.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void testReqParams() throws Exception {
|
||||
DocCollection coll = cloudClient.getZkStateReader().getClusterState().getCollection("collection1");
|
||||
CloudSolrClient cloudClient = cluster.getSolrClient();
|
||||
DocCollection coll = cloudClient.getZkStateReader().getClusterState().getCollection(COLL_NAME);
|
||||
List<String> urls = new ArrayList<>();
|
||||
for (Slice slice : coll.getSlices()) {
|
||||
for (Replica replica : slice.getReplicas())
|
||||
|
@ -70,14 +82,27 @@ public class TestReqParamsAPI extends AbstractFullDistribZkTestBase {
|
|||
}
|
||||
|
||||
RestTestHarness writeHarness = restTestHarnesses.get(random().nextInt(restTestHarnesses.size()));
|
||||
String payload = " {\n" +
|
||||
|
||||
String payload = "{\n" +
|
||||
"'create-requesthandler' : { 'name' : '/dump0', 'class': 'org.apache.solr.handler.DumpRequestHandler' }\n" +
|
||||
"}";
|
||||
|
||||
TestSolrConfigHandler.runConfigCommand(writeHarness, "/config?wt=json", payload);
|
||||
|
||||
payload = "{\n" +
|
||||
"'create-requesthandler' : { 'name' : '/dump1', 'class': 'org.apache.solr.handler.DumpRequestHandler', 'useParams':'x' }\n" +
|
||||
"}";
|
||||
TestSolrConfigHandler.runConfigCommand(writeHarness, "/config?wt=json", payload);
|
||||
|
||||
AbstractFullDistribZkTestBase.waitForRecoveriesToFinish(COLL_NAME, cloudClient.getZkStateReader(), false, true, 90);
|
||||
|
||||
payload = " {\n" +
|
||||
" 'set' : {'x': {" +
|
||||
" 'a':'A val',\n" +
|
||||
" 'b': 'B val'}\n" +
|
||||
" }\n" +
|
||||
" }";
|
||||
|
||||
|
||||
TestSolrConfigHandler.runConfigCommand(writeHarness, "/config/params?wt=json", payload);
|
||||
|
||||
Map result = TestSolrConfigHandler.testForResponseElement(null,
|
||||
|
@ -89,12 +114,6 @@ public class TestReqParamsAPI extends AbstractFullDistribZkTestBase {
|
|||
10);
|
||||
compareValues(result, "B val", asList("response", "params", "x", "b"));
|
||||
|
||||
payload = "{\n" +
|
||||
"'create-requesthandler' : { 'name' : '/dump0', 'class': 'org.apache.solr.handler.DumpRequestHandler' }\n" +
|
||||
"}";
|
||||
|
||||
TestSolrConfigHandler.runConfigCommand(writeHarness, "/config?wt=json", payload);
|
||||
|
||||
TestSolrConfigHandler.testForResponseElement(null,
|
||||
urls.get(random().nextInt(urls.size())),
|
||||
"/config/overlay?wt=json",
|
||||
|
@ -120,12 +139,6 @@ public class TestReqParamsAPI extends AbstractFullDistribZkTestBase {
|
|||
"fomrequest",
|
||||
5);
|
||||
|
||||
payload = "{\n" +
|
||||
"'create-requesthandler' : { 'name' : '/dump1', 'class': 'org.apache.solr.handler.DumpRequestHandler', 'useParams':'x' }\n" +
|
||||
"}";
|
||||
|
||||
TestSolrConfigHandler.runConfigCommand(writeHarness, "/config?wt=json", payload);
|
||||
|
||||
result = TestSolrConfigHandler.testForResponseElement(null,
|
||||
urls.get(random().nextInt(urls.size())),
|
||||
"/config/overlay?wt=json",
|
||||
|
@ -263,9 +276,5 @@ public class TestReqParamsAPI extends AbstractFullDistribZkTestBase {
|
|||
asList("response", "params", "y", "p"),
|
||||
null,
|
||||
10);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* 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.solr.request.macro;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
/*
|
||||
* Tests for the MacroExpander
|
||||
*/
|
||||
public class TestMacroExpander extends LuceneTestCase {
|
||||
|
||||
@Test
|
||||
public void testExamples() {
|
||||
final Map<String,String[]> testParams = new HashMap<String,String[]>();
|
||||
final MacroExpander me;
|
||||
// example behavior unaffected by absence or value of failOnMissingParams
|
||||
if (random().nextBoolean()) {
|
||||
me = new MacroExpander(testParams);
|
||||
} else {
|
||||
final boolean failOnMissingParams = random().nextBoolean();
|
||||
me = new MacroExpander(testParams, failOnMissingParams);
|
||||
}
|
||||
|
||||
//default examples: https://cwiki.apache.org/confluence/display/solr/Parameter+Substitution
|
||||
// and http://yonik.com/solr-query-parameter-substitution/
|
||||
|
||||
//using params
|
||||
String[] lowParams = {"50"};
|
||||
testParams.put("low",lowParams);
|
||||
String[] highParams = {"100"};
|
||||
testParams.put("high",highParams);
|
||||
|
||||
String testQuery = "q=popularity:[ ${low} TO ${high} ]";
|
||||
|
||||
assertEquals("q=popularity:[ 50 TO 100 ]", me.expand(testQuery));
|
||||
|
||||
//using default values
|
||||
testQuery = "q=popularity:[ ${low:10} TO ${high:20} ]";
|
||||
assertEquals("q=popularity:[ 50 TO 100 ]", me.expand(testQuery));
|
||||
|
||||
testParams.clear();
|
||||
assertEquals("q=popularity:[ 10 TO 20 ]", me.expand(testQuery));
|
||||
|
||||
//multiple levels of substitutions
|
||||
testQuery = "q=${pop_query}";
|
||||
String[] popQueryParams = {"${pop_field}:[ ${low} TO ${high} ] AND inStock:true"};
|
||||
String[] popFieldParams = {"popularity"};
|
||||
testParams.put("low",lowParams);
|
||||
testParams.put("high",highParams);
|
||||
testParams.put("pop_query",popQueryParams);
|
||||
testParams.put("pop_field",popFieldParams);
|
||||
|
||||
assertEquals("q=popularity:[ 50 TO 100 ] AND inStock:true", me.expand(testQuery));
|
||||
|
||||
//end default examples
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnMissingParams() {
|
||||
final Map<String,String[]> testParams = new HashMap<String,String[]>();
|
||||
final MacroExpander meSkipOnMissingParams = new MacroExpander(testParams);
|
||||
final MacroExpander meFailOnMissingParams = new MacroExpander(testParams, true);
|
||||
|
||||
final String low = "50";
|
||||
final String high = "100";
|
||||
testParams.put("low", new String[]{ low });
|
||||
testParams.put("high", new String[]{ high });
|
||||
|
||||
final String testQuery = "q=popularity:[ ${low} TO ${high} ]";
|
||||
|
||||
//when params all present the expansion results match
|
||||
final String expandedQuery = "q=popularity:[ "+low+" TO "+high+" ]";
|
||||
assertEquals(expandedQuery, meSkipOnMissingParams.expand(testQuery));
|
||||
assertEquals(expandedQuery, meFailOnMissingParams.expand(testQuery));
|
||||
|
||||
//when param(s) missing and have no default the expansion results differ
|
||||
final String expandedLow;
|
||||
final String expandedHigh;
|
||||
if (random().nextBoolean()) { // keep low
|
||||
expandedLow = low;
|
||||
} else {
|
||||
expandedLow = "";
|
||||
testParams.remove("low");
|
||||
}
|
||||
if (random().nextBoolean()) { // keep high
|
||||
expandedHigh = high;
|
||||
} else {
|
||||
expandedHigh = "";
|
||||
testParams.remove("high");
|
||||
}
|
||||
assertEquals("q=popularity:[ "+expandedLow+" TO "+expandedHigh+" ]",
|
||||
meSkipOnMissingParams.expand(testQuery));
|
||||
if (testParams.size() < 2) { // at least one of the two parameters missing
|
||||
assertEquals(null, meFailOnMissingParams.expand(testQuery));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.lucene.queryparser.xml.builders;
|
||||
package org.apache.solr.search;
|
||||
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
|
@ -32,7 +32,7 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class TestNumericRangeQueryBuilder extends LuceneTestCase {
|
||||
public class TestLegacyNumericRangeQueryBuilder extends LuceneTestCase {
|
||||
|
||||
public void testGetFilterHandleNumericParseErrorStrict() throws Exception {
|
||||
LegacyNumericRangeQueryBuilder filterBuilder = new LegacyNumericRangeQueryBuilder();
|
Loading…
Reference in New Issue