mirror of https://github.com/apache/lucene.git
SOLR-737: use a constant score query for wildcards
git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@689978 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
451b795c47
commit
415dff5d25
|
@ -396,6 +396,10 @@ Changes in runtime behavior
|
|||
|
||||
3. SOLR-647: reference count the SolrCore uses to prevent a premature
|
||||
close while a core is still in use. (Henri Biestro, Noble Paul, yonik)
|
||||
|
||||
4. SOLR-737: SolrQueryParser now uses a ConstantScoreQuery for wildcard
|
||||
queries that prevent an exception from being thrown when the number
|
||||
of matching terms exceeds the BooleanQuery clause limit. (yonik)
|
||||
|
||||
Optimizations
|
||||
1. SOLR-276: improve JSON writer speed. (yonik)
|
||||
|
|
|
@ -22,6 +22,8 @@ import org.apache.lucene.queryParser.ParseException;
|
|||
import org.apache.lucene.queryParser.QueryParser;
|
||||
import org.apache.lucene.search.ConstantScoreRangeQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.WildcardQuery;
|
||||
import org.apache.lucene.search.ConstantScoreQuery;
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.schema.FieldType;
|
||||
|
@ -144,4 +146,12 @@ public class SolrQueryParser extends QueryParser {
|
|||
return new ConstantScorePrefixQuery(t);
|
||||
}
|
||||
|
||||
protected Query getWildcardQuery(String field, String termStr) throws ParseException {
|
||||
Query q = super.getWildcardQuery(field, termStr);
|
||||
if (q instanceof WildcardQuery) {
|
||||
// use a constant score query to avoid overflowing clauses
|
||||
return new ConstantScoreQuery(new WildcardFilter(((WildcardQuery)q).getTerm()));
|
||||
}
|
||||
return q;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/**
|
||||
* 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.search;
|
||||
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.search.DocIdSet;
|
||||
import org.apache.lucene.search.WildcardTermEnum;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.TermEnum;
|
||||
import org.apache.lucene.index.TermDocs;
|
||||
import org.apache.lucene.util.OpenBitSet;
|
||||
|
||||
import java.util.BitSet;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @version $Id$
|
||||
*/
|
||||
public class WildcardFilter extends Filter {
|
||||
protected final Term term;
|
||||
|
||||
public WildcardFilter(Term wildcardTerm) {
|
||||
this.term = wildcardTerm;
|
||||
}
|
||||
|
||||
public Term getTerm() { return term; }
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getDocIdSet(IndexReader)} instead.
|
||||
*/
|
||||
public BitSet bits(IndexReader reader) throws IOException {
|
||||
final BitSet bitSet = new BitSet(reader.maxDoc());
|
||||
new WildcardGenerator(term) {
|
||||
public void handleDoc(int doc) {
|
||||
bitSet.set(doc);
|
||||
}
|
||||
}.generate(reader);
|
||||
return bitSet;
|
||||
}
|
||||
|
||||
public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
|
||||
final OpenBitSet bitSet = new OpenBitSet(reader.maxDoc());
|
||||
new WildcardGenerator(term) {
|
||||
public void handleDoc(int doc) {
|
||||
bitSet.set(doc);
|
||||
}
|
||||
}.generate(reader);
|
||||
return bitSet;
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("WildcardFilter(");
|
||||
sb.append(term.toString());
|
||||
sb.append(")");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
abstract class WildcardGenerator implements IdGenerator {
|
||||
protected final Term wildcard;
|
||||
|
||||
WildcardGenerator(Term wildcard) {
|
||||
this.wildcard = wildcard;
|
||||
}
|
||||
|
||||
public void generate(IndexReader reader) throws IOException {
|
||||
TermEnum enumerator = new WildcardTermEnum(reader, wildcard);
|
||||
TermDocs termDocs = reader.termDocs();
|
||||
try {
|
||||
do {
|
||||
Term term = enumerator.term();
|
||||
if (term==null) break;
|
||||
termDocs.seek(term);
|
||||
while (termDocs.next()) {
|
||||
handleDoc(termDocs.doc());
|
||||
}
|
||||
} while (enumerator.next());
|
||||
} finally {
|
||||
termDocs.close();
|
||||
enumerator.close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -812,6 +812,9 @@ public class ConvertedLegacyTest extends AbstractSolrTestCase {
|
|||
);
|
||||
// val_s:* %//*[@numFound="8"]
|
||||
|
||||
// test wildcard query
|
||||
assertQ(req("val_s:a*p*") ,"//*[@numFound='3']");
|
||||
assertQ(req("val_s:p?a*") ,"//*[@numFound='3']");
|
||||
|
||||
assertU("<delete><query>id:[100 TO 110]</query></delete>");
|
||||
|
||||
|
|
Loading…
Reference in New Issue