mirror of https://github.com/apache/lucene.git
LUCENE-2945: Fix equals/hashCode for surround query parser generated queries
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1166156 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ab3883291e
commit
35e7439ca4
|
@ -530,6 +530,9 @@ Bug fixes
|
||||||
rarely cause deletions to be incorrectly applied. (Yonik Seeley,
|
rarely cause deletions to be incorrectly applied. (Yonik Seeley,
|
||||||
Simon Willnauer, Mike McCandless)
|
Simon Willnauer, Mike McCandless)
|
||||||
|
|
||||||
|
* LUCENE-2945: Fix hashCode/equals for surround query parser generated queries.
|
||||||
|
(Paul Elschot, Simon Rosenthal, gsingers via ehatcher)
|
||||||
|
|
||||||
======================= Lucene 3.x (not yet released) ================
|
======================= Lucene 3.x (not yet released) ================
|
||||||
|
|
||||||
Bug fixes
|
Bug fixes
|
||||||
|
|
|
@ -45,8 +45,19 @@ public class BasicQueryFactory {
|
||||||
public int getNrQueriesMade() {return queriesMade;}
|
public int getNrQueriesMade() {return queriesMade;}
|
||||||
public int getMaxBasicQueries() {return maxBasicQueries;}
|
public int getMaxBasicQueries() {return maxBasicQueries;}
|
||||||
|
|
||||||
private synchronized void checkMax() throws TooManyBasicQueries {
|
public String toString() {
|
||||||
if (queriesMade >= maxBasicQueries)
|
return getClass().getName()
|
||||||
|
+ "(maxBasicQueries: " + maxBasicQueries
|
||||||
|
+ ", queriesMade: " + queriesMade
|
||||||
|
+ ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean atMax() {
|
||||||
|
return queriesMade >= maxBasicQueries;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected synchronized void checkMax() throws TooManyBasicQueries {
|
||||||
|
if (atMax())
|
||||||
throw new TooManyBasicQueries(getMaxBasicQueries());
|
throw new TooManyBasicQueries(getMaxBasicQueries());
|
||||||
queriesMade++;
|
queriesMade++;
|
||||||
}
|
}
|
||||||
|
@ -60,6 +71,22 @@ public class BasicQueryFactory {
|
||||||
checkMax();
|
checkMax();
|
||||||
return new SpanTermQuery(term);
|
return new SpanTermQuery(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return getClass().hashCode() ^ (atMax() ? 7 : 31*32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Two BasicQueryFactory's are equal when they generate
|
||||||
|
* the same types of basic queries, or both cannot generate queries anymore.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (! (obj instanceof BasicQueryFactory))
|
||||||
|
return false;
|
||||||
|
BasicQueryFactory other = (BasicQueryFactory) obj;
|
||||||
|
return atMax() == other.atMax();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,36 +24,36 @@ import org.apache.lucene.search.Query;
|
||||||
|
|
||||||
public abstract class ComposedQuery extends SrndQuery {
|
public abstract class ComposedQuery extends SrndQuery {
|
||||||
|
|
||||||
public ComposedQuery(List qs, boolean operatorInfix, String opName) {
|
public ComposedQuery(List<SrndQuery> qs, boolean operatorInfix, String opName) {
|
||||||
recompose(qs);
|
recompose(qs);
|
||||||
this.operatorInfix = operatorInfix;
|
this.operatorInfix = operatorInfix;
|
||||||
this.opName = opName;
|
this.opName = opName;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void recompose(List queries) {
|
protected void recompose(List<SrndQuery> queries) {
|
||||||
if (queries.size() < 2) throw new AssertionError("Too few subqueries");
|
if (queries.size() < 2) throw new AssertionError("Too few subqueries");
|
||||||
this.queries = queries;
|
this.queries = queries;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String opName;
|
protected String opName;
|
||||||
public String getOperatorName() {return opName;}
|
public String getOperatorName() {return opName;}
|
||||||
|
|
||||||
private List queries;
|
protected List<SrndQuery> queries;
|
||||||
|
|
||||||
public Iterator getSubQueriesIterator() {return queries.listIterator();}
|
public Iterator<SrndQuery> getSubQueriesIterator() {return queries.listIterator();}
|
||||||
|
|
||||||
public int getNrSubQueries() {return queries.size();}
|
public int getNrSubQueries() {return queries.size();}
|
||||||
|
|
||||||
public SrndQuery getSubQuery(int qn) {return (SrndQuery) queries.get(qn);}
|
public SrndQuery getSubQuery(int qn) {return queries.get(qn);}
|
||||||
|
|
||||||
private boolean operatorInfix;
|
private boolean operatorInfix;
|
||||||
public boolean isOperatorInfix() { return operatorInfix; } /* else prefix operator */
|
public boolean isOperatorInfix() { return operatorInfix; } /* else prefix operator */
|
||||||
|
|
||||||
public List<Query> makeLuceneSubQueriesField(String fn, BasicQueryFactory qf) {
|
public List<Query> makeLuceneSubQueriesField(String fn, BasicQueryFactory qf) {
|
||||||
List<Query> luceneSubQueries = new ArrayList<Query>();
|
List<Query> luceneSubQueries = new ArrayList<Query>();
|
||||||
Iterator sqi = getSubQueriesIterator();
|
Iterator<SrndQuery> sqi = getSubQueriesIterator();
|
||||||
while (sqi.hasNext()) {
|
while (sqi.hasNext()) {
|
||||||
luceneSubQueries.add( ((SrndQuery) sqi.next()).makeLuceneQueryField(fn, qf));
|
luceneSubQueries.add( (sqi.next()).makeLuceneQueryField(fn, qf));
|
||||||
}
|
}
|
||||||
return luceneSubQueries;
|
return luceneSubQueries;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ public abstract class ComposedQuery extends SrndQuery {
|
||||||
|
|
||||||
protected void infixToString(StringBuilder r) {
|
protected void infixToString(StringBuilder r) {
|
||||||
/* Brackets are possibly redundant in the result. */
|
/* Brackets are possibly redundant in the result. */
|
||||||
Iterator sqi = getSubQueriesIterator();
|
Iterator<SrndQuery> sqi = getSubQueriesIterator();
|
||||||
r.append(getBracketOpen());
|
r.append(getBracketOpen());
|
||||||
if (sqi.hasNext()) {
|
if (sqi.hasNext()) {
|
||||||
r.append(sqi.next().toString());
|
r.append(sqi.next().toString());
|
||||||
|
@ -92,7 +92,7 @@ public abstract class ComposedQuery extends SrndQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void prefixToString(StringBuilder r) {
|
protected void prefixToString(StringBuilder r) {
|
||||||
Iterator sqi = getSubQueriesIterator();
|
Iterator<SrndQuery> sqi = getSubQueriesIterator();
|
||||||
r.append(getOperatorName()); /* prefix operator */
|
r.append(getOperatorName()); /* prefix operator */
|
||||||
r.append(getBracketOpen());
|
r.append(getBracketOpen());
|
||||||
if (sqi.hasNext()) {
|
if (sqi.hasNext()) {
|
||||||
|
@ -109,9 +109,9 @@ public abstract class ComposedQuery extends SrndQuery {
|
||||||
@Override
|
@Override
|
||||||
public boolean isFieldsSubQueryAcceptable() {
|
public boolean isFieldsSubQueryAcceptable() {
|
||||||
/* at least one subquery should be acceptable */
|
/* at least one subquery should be acceptable */
|
||||||
Iterator sqi = getSubQueriesIterator();
|
Iterator<SrndQuery> sqi = getSubQueriesIterator();
|
||||||
while (sqi.hasNext()) {
|
while (sqi.hasNext()) {
|
||||||
if (((SrndQuery) sqi.next()).isFieldsSubQueryAcceptable()) {
|
if ((sqi.next()).isFieldsSubQueryAcceptable()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ package org.apache.lucene.queryparser.surround.query;
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
@ -39,12 +38,14 @@ public class DistanceQuery extends ComposedQuery implements DistanceSubQuery {
|
||||||
this.ordered = ordered;
|
this.ordered = ordered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private int opDistance;
|
private int opDistance;
|
||||||
public int getOpDistance() {return opDistance;}
|
public int getOpDistance() {return opDistance;}
|
||||||
|
|
||||||
private boolean ordered;
|
private boolean ordered;
|
||||||
public boolean subQueriesOrdered() {return ordered;}
|
public boolean subQueriesOrdered() {return ordered;}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String distanceSubQueryNotAllowed() {
|
public String distanceSubQueryNotAllowed() {
|
||||||
Iterator<?> sqi = getSubQueriesIterator();
|
Iterator<?> sqi = getSubQueriesIterator();
|
||||||
while (sqi.hasNext()) {
|
while (sqi.hasNext()) {
|
||||||
|
@ -62,30 +63,13 @@ public class DistanceQuery extends ComposedQuery implements DistanceSubQuery {
|
||||||
return null; /* subqueries acceptable */
|
return null; /* subqueries acceptable */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void addSpanQueries(SpanNearClauseFactory sncf) throws IOException {
|
public void addSpanQueries(SpanNearClauseFactory sncf) throws IOException {
|
||||||
Query snq = getSpanNearQuery(sncf.getIndexReader(),
|
Query snq = getSpanNearQuery(sncf.getIndexReader(),
|
||||||
sncf.getFieldName(),
|
sncf.getFieldName(),
|
||||||
getWeight(),
|
getWeight(),
|
||||||
sncf.getBasicQueryFactory());
|
sncf.getBasicQueryFactory());
|
||||||
sncf.addSpanNearQuery(snq);
|
sncf.addSpanQuery(snq);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query makeLuceneQueryFieldNoBoost(final String fieldName, final BasicQueryFactory qf) {
|
|
||||||
return new Query () {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString(String fn) {
|
|
||||||
return getClass().toString() + " " + fieldName + " (" + fn + "?)";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query rewrite(IndexReader reader) throws IOException {
|
|
||||||
return getSpanNearQuery(reader, fieldName, getBoost(), qf);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Query getSpanNearQuery(
|
public Query getSpanNearQuery(
|
||||||
|
@ -93,7 +77,7 @@ public class DistanceQuery extends ComposedQuery implements DistanceSubQuery {
|
||||||
String fieldName,
|
String fieldName,
|
||||||
float boost,
|
float boost,
|
||||||
BasicQueryFactory qf) throws IOException {
|
BasicQueryFactory qf) throws IOException {
|
||||||
SpanQuery[] spanNearClauses = new SpanQuery[getNrSubQueries()];
|
SpanQuery[] spanClauses = new SpanQuery[getNrSubQueries()];
|
||||||
Iterator<?> sqi = getSubQueriesIterator();
|
Iterator<?> sqi = getSubQueriesIterator();
|
||||||
int qi = 0;
|
int qi = 0;
|
||||||
while (sqi.hasNext()) {
|
while (sqi.hasNext()) {
|
||||||
|
@ -108,14 +92,18 @@ public class DistanceQuery extends ComposedQuery implements DistanceSubQuery {
|
||||||
return SrndQuery.theEmptyLcnQuery;
|
return SrndQuery.theEmptyLcnQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
spanNearClauses[qi] = sncf.makeSpanNearClause();
|
spanClauses[qi] = sncf.makeSpanClause();
|
||||||
|
|
||||||
qi++;
|
qi++;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpanNearQuery r = new SpanNearQuery(spanNearClauses, getOpDistance() - 1, subQueriesOrdered());
|
SpanNearQuery r = new SpanNearQuery(spanClauses, getOpDistance() - 1, subQueriesOrdered());
|
||||||
r.setBoost(boost);
|
r.setBoost(boost);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query makeLuceneQueryFieldNoBoost(final String fieldName, final BasicQueryFactory qf) {
|
||||||
|
return new DistanceRewriteQuery(this, fieldName, qf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package org.apache.lucene.queryparser.surround.query;
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.lucene.index.IndexReader;
|
||||||
|
import org.apache.lucene.search.Query;
|
||||||
|
|
||||||
|
class DistanceRewriteQuery extends RewriteQuery<DistanceQuery> {
|
||||||
|
|
||||||
|
DistanceRewriteQuery(
|
||||||
|
DistanceQuery srndQuery,
|
||||||
|
String fieldName,
|
||||||
|
BasicQueryFactory qf) {
|
||||||
|
super(srndQuery, fieldName, qf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query rewrite(IndexReader reader) throws IOException {
|
||||||
|
return srndQuery.getSpanNearQuery(reader, fieldName, getBoost(), qf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
package org.apache.lucene.queryparser.surround.query;
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.lucene.index.IndexReader;
|
||||||
|
import org.apache.lucene.search.Query;
|
||||||
|
|
||||||
|
abstract class RewriteQuery<SQ extends SrndQuery> extends Query {
|
||||||
|
protected final SQ srndQuery;
|
||||||
|
protected final String fieldName;
|
||||||
|
protected final BasicQueryFactory qf;
|
||||||
|
|
||||||
|
RewriteQuery(
|
||||||
|
SQ srndQuery,
|
||||||
|
String fieldName,
|
||||||
|
BasicQueryFactory qf) {
|
||||||
|
this.srndQuery = srndQuery;
|
||||||
|
this.fieldName = fieldName;
|
||||||
|
this.qf = qf;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
abstract public Query rewrite(IndexReader reader) throws IOException;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return toString(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(String field) {
|
||||||
|
return getClass().getName()
|
||||||
|
+ (field == null ? "" : "(unused: " + field + ")")
|
||||||
|
+ "(" + fieldName
|
||||||
|
+ ", " + srndQuery.toString()
|
||||||
|
+ ", " + qf.toString()
|
||||||
|
+ ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return getClass().hashCode()
|
||||||
|
^ fieldName.hashCode()
|
||||||
|
^ qf.hashCode()
|
||||||
|
^ srndQuery.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (! getClass().equals(obj.getClass()))
|
||||||
|
return false;
|
||||||
|
RewriteQuery other = (RewriteQuery)obj;
|
||||||
|
return fieldName.equals(other.fieldName)
|
||||||
|
&& qf.equals(other.qf)
|
||||||
|
&& srndQuery.equals(other.srndQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @throws UnsupportedOperationException */
|
||||||
|
@Override
|
||||||
|
public Object clone() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -17,12 +17,9 @@ package org.apache.lucene.queryparser.surround.query;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.lucene.index.IndexReader;
|
import org.apache.lucene.index.IndexReader;
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
import org.apache.lucene.search.BooleanClause;
|
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
|
|
||||||
public abstract class SimpleTerm
|
public abstract class SimpleTerm
|
||||||
|
@ -39,6 +36,10 @@ public abstract class SimpleTerm
|
||||||
|
|
||||||
public abstract String toStringUnquoted();
|
public abstract String toStringUnquoted();
|
||||||
|
|
||||||
|
/** @deprecated (March 2011) Not normally used, to be removed from Lucene 4.0.
|
||||||
|
* This class implementing Comparable is to be removed at the same time.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public int compareTo(SimpleTerm ost) {
|
public int compareTo(SimpleTerm ost) {
|
||||||
/* for ordering terms and prefixes before using an index, not used */
|
/* for ordering terms and prefixes before using an index, not used */
|
||||||
return this.toStringUnquoted().compareTo( ost.toStringUnquoted());
|
return this.toStringUnquoted().compareTo( ost.toStringUnquoted());
|
||||||
|
@ -70,35 +71,10 @@ public abstract class SimpleTerm
|
||||||
void visitMatchingTerm(Term t)throws IOException;
|
void visitMatchingTerm(Term t)throws IOException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String distanceSubQueryNotAllowed() {return null;}
|
public String distanceSubQueryNotAllowed() {return null;}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Query makeLuceneQueryFieldNoBoost(final String fieldName, final BasicQueryFactory qf) {
|
|
||||||
return new Query() {
|
|
||||||
@Override
|
|
||||||
public String toString(String fn) {
|
|
||||||
return getClass().toString() + " " + fieldName + " (" + fn + "?)";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query rewrite(IndexReader reader) throws IOException {
|
|
||||||
final List<Query> luceneSubQueries = new ArrayList<Query>();
|
|
||||||
visitMatchingTerms( reader, fieldName,
|
|
||||||
new MatchingTermVisitor() {
|
|
||||||
public void visitMatchingTerm(Term term) throws IOException {
|
|
||||||
luceneSubQueries.add(qf.newTermQuery(term));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return (luceneSubQueries.size() == 0) ? SrndQuery.theEmptyLcnQuery
|
|
||||||
: (luceneSubQueries.size() == 1) ? luceneSubQueries.get(0)
|
|
||||||
: SrndBooleanQuery.makeBooleanQuery(
|
|
||||||
/* luceneSubQueries all have default weight */
|
|
||||||
luceneSubQueries, BooleanClause.Occur.SHOULD); /* OR the subquery terms */
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addSpanQueries(final SpanNearClauseFactory sncf) throws IOException {
|
public void addSpanQueries(final SpanNearClauseFactory sncf) throws IOException {
|
||||||
visitMatchingTerms(
|
visitMatchingTerms(
|
||||||
sncf.getIndexReader(),
|
sncf.getIndexReader(),
|
||||||
|
@ -109,6 +85,11 @@ public abstract class SimpleTerm
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query makeLuceneQueryFieldNoBoost(final String fieldName, final BasicQueryFactory qf) {
|
||||||
|
return new SimpleTermRewriteQuery(this, fieldName, qf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
package org.apache.lucene.queryparser.surround.query;
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import org.apache.lucene.index.IndexReader;
|
||||||
|
import org.apache.lucene.search.Query;
|
||||||
|
import org.apache.lucene.search.BooleanClause;
|
||||||
|
import org.apache.lucene.index.Term;
|
||||||
|
|
||||||
|
class SimpleTermRewriteQuery extends RewriteQuery<SimpleTerm> {
|
||||||
|
|
||||||
|
SimpleTermRewriteQuery(
|
||||||
|
SimpleTerm srndQuery,
|
||||||
|
String fieldName,
|
||||||
|
BasicQueryFactory qf) {
|
||||||
|
super(srndQuery, fieldName, qf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query rewrite(IndexReader reader) throws IOException {
|
||||||
|
final List<Query> luceneSubQueries = new ArrayList<Query>();
|
||||||
|
srndQuery.visitMatchingTerms(reader, fieldName,
|
||||||
|
new SimpleTerm.MatchingTermVisitor() {
|
||||||
|
public void visitMatchingTerm(Term term) throws IOException {
|
||||||
|
luceneSubQueries.add(qf.newTermQuery(term));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return (luceneSubQueries.size() == 0) ? SrndQuery.theEmptyLcnQuery
|
||||||
|
: (luceneSubQueries.size() == 1) ? luceneSubQueries.get(0)
|
||||||
|
: SrndBooleanQuery.makeBooleanQuery(
|
||||||
|
/* luceneSubQueries all have default weight */
|
||||||
|
luceneSubQueries, BooleanClause.Occur.SHOULD); /* OR the subquery terms */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ import org.apache.lucene.search.spans.SpanQuery;
|
||||||
import org.apache.lucene.search.spans.SpanTermQuery;
|
import org.apache.lucene.search.spans.SpanTermQuery;
|
||||||
|
|
||||||
|
|
||||||
public class SpanNearClauseFactory {
|
public class SpanNearClauseFactory { // FIXME: rename to SpanClauseFactory
|
||||||
public SpanNearClauseFactory(IndexReader reader, String fieldName, BasicQueryFactory qf) {
|
public SpanNearClauseFactory(IndexReader reader, String fieldName, BasicQueryFactory qf) {
|
||||||
this.reader = reader;
|
this.reader = reader;
|
||||||
this.fieldName = fieldName;
|
this.fieldName = fieldName;
|
||||||
|
@ -101,16 +101,15 @@ public class SpanNearClauseFactory {
|
||||||
addSpanQueryWeighted(stq, weight);
|
addSpanQueryWeighted(stq, weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addSpanNearQuery(Query q) {
|
public void addSpanQuery(Query q) {
|
||||||
if (q == SrndQuery.theEmptyLcnQuery)
|
if (q == SrndQuery.theEmptyLcnQuery)
|
||||||
return;
|
return;
|
||||||
if (! (q instanceof SpanNearQuery))
|
if (! (q instanceof SpanQuery))
|
||||||
throw new AssertionError("Expected SpanNearQuery: " + q.toString(getFieldName()));
|
throw new AssertionError("Expected SpanQuery: " + q.toString(getFieldName()));
|
||||||
/* CHECKME: wrap in Hashable...? */
|
addSpanQueryWeighted((SpanQuery)q, q.getBoost());
|
||||||
addSpanQueryWeighted((SpanNearQuery)q, q.getBoost());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpanQuery makeSpanNearClause() {
|
public SpanQuery makeSpanClause() {
|
||||||
SpanQuery [] spanQueries = new SpanQuery[size()];
|
SpanQuery [] spanQueries = new SpanQuery[size()];
|
||||||
Iterator<SpanQuery> sqi = weightBySpanQuery.keySet().iterator();
|
Iterator<SpanQuery> sqi = weightBySpanQuery.keySet().iterator();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
|
@ -53,6 +53,9 @@ public abstract class SrndQuery implements Cloneable {
|
||||||
|
|
||||||
public abstract Query makeLuceneQueryFieldNoBoost(String fieldName, BasicQueryFactory qf);
|
public abstract Query makeLuceneQueryFieldNoBoost(String fieldName, BasicQueryFactory qf);
|
||||||
|
|
||||||
|
/** This method is used by {@link #hashCode()} and {@link #equals(Object)},
|
||||||
|
* see LUCENE-2945.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public abstract String toString();
|
public abstract String toString();
|
||||||
|
|
||||||
|
@ -67,7 +70,31 @@ public abstract class SrndQuery implements Cloneable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* An empty Lucene query */
|
/** For subclasses of {@link SrndQuery} within the package
|
||||||
|
* {@link org.apache.lucene.queryparser.surround.query}
|
||||||
|
* it is not necessary to override this method,
|
||||||
|
* @see #toString().
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return getClass().hashCode() ^ toString().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** For subclasses of {@link SrndQuery} within the package
|
||||||
|
* {@link org.apache.lucene.queryparser.surround.query}
|
||||||
|
* it is not necessary to override this method,
|
||||||
|
* @see #toString().
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (! getClass().equals(obj.getClass()))
|
||||||
|
return false;
|
||||||
|
return toString().equals(obj.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** An empty Lucene query */
|
||||||
public final static Query theEmptyLcnQuery = new BooleanQuery() { /* no changes allowed */
|
public final static Query theEmptyLcnQuery = new BooleanQuery() { /* no changes allowed */
|
||||||
@Override
|
@Override
|
||||||
public void setBoost(float boost) {
|
public void setBoost(float boost) {
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
package org.apache.lucene.queryparser.surround.query;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
import org.apache.lucene.queryparser.surround.parser.QueryParser;
|
||||||
|
import org.apache.lucene.search.Query;
|
||||||
|
import org.apache.lucene.search.QueryUtils;
|
||||||
|
import org.apache.lucene.util.LuceneTestCase;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
public class SrndQueryTest extends LuceneTestCase {
|
||||||
|
|
||||||
|
void checkEqualParsings(String s1, String s2) throws Exception {
|
||||||
|
String fieldName = "foo";
|
||||||
|
BasicQueryFactory qf = new BasicQueryFactory(16);
|
||||||
|
Query lq1, lq2;
|
||||||
|
lq1 = QueryParser.parse(s1).makeLuceneQueryField(fieldName, qf);
|
||||||
|
lq2 = QueryParser.parse(s2).makeLuceneQueryField(fieldName, qf);
|
||||||
|
QueryUtils.checkEqual(lq1, lq2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHashEquals() throws Exception {
|
||||||
|
//grab some sample queries from Test02Boolean and Test03Distance and
|
||||||
|
//check there hashes and equals
|
||||||
|
checkEqualParsings("word1 w word2", " word1 w word2 ");
|
||||||
|
checkEqualParsings("2N(w1,w2,w3)", " 2N(w1, w2 , w3)");
|
||||||
|
checkEqualParsings("abc?", " abc? ");
|
||||||
|
checkEqualParsings("w*rd?", " w*rd?");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue