mirror of https://github.com/apache/lucene.git
SOLR-4208: ExtendedDismaxQParserPlugin has been refactored to make subclassing easier
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1430399 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9ee4b4d5fa
commit
76f5a8bada
|
@ -569,6 +569,9 @@ Other Changes
|
|||
* SOLR-4226: Extract fl parsing code out of ReturnFields constructor.
|
||||
(Ryan Ernst via Robert Muir)
|
||||
|
||||
* SOLR-4208: ExtendedDismaxQParserPlugin has been refactored to make
|
||||
subclassing easier. (Tomás Fernández Löbbe, hossman)
|
||||
|
||||
================== 4.0.0 ==================
|
||||
|
||||
Versions of Major Components
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -597,6 +597,7 @@
|
|||
<!-- unused, for testing luke copyFields -->
|
||||
<dynamicField name="foo_copysource_*" type="ignored" multiValued="true"/>
|
||||
<dynamicField name="bar_copydest_*" type="ignored" multiValued="true"/>
|
||||
<dynamicField name="*_es" type="text" indexed="true" stored="true"/>
|
||||
|
||||
</fields>
|
||||
|
||||
|
|
|
@ -17,8 +17,21 @@
|
|||
|
||||
package org.apache.solr.search;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.lucene.search.BooleanClause;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.DisjunctionMaxQuery;
|
||||
import org.apache.lucene.search.FuzzyQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.common.params.ModifiableSolrParams;
|
||||
import org.apache.solr.common.params.SolrParams;
|
||||
import org.apache.solr.request.SolrQueryRequest;
|
||||
import org.apache.solr.util.AbstractSolrTestCase;
|
||||
import org.apache.solr.util.SolrPluginUtils;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -510,37 +523,42 @@ public class TestExtendedDismaxParser extends AbstractSolrTestCase {
|
|||
|
||||
public void testCyclicAliasing() throws Exception {
|
||||
try {
|
||||
h.query(req("defType","edismax", "q","ignore_exception", "qf","who", "f.who.qf","name","f.name.qf","who"));
|
||||
fail("Simple cyclic alising");
|
||||
} catch (SolrException e) {
|
||||
assertTrue(e.getCause().getMessage().contains("Field aliases lead to a cycle"));
|
||||
}
|
||||
|
||||
try {
|
||||
h.query(req("defType","edismax", "q","ignore_exception", "qf","who", "f.who.qf","name","f.name.qf","myalias", "f.myalias.qf","who"));
|
||||
fail();
|
||||
} catch (SolrException e) {
|
||||
assertTrue(e.getCause().getMessage().contains("Field aliases lead to a cycle"));
|
||||
}
|
||||
|
||||
try {
|
||||
h.query(req("defType","edismax", "q","ignore_exception", "qf","field1", "f.field1.qf","field2 field3","f.field2.qf","field4 field5", "f.field4.qf","field5", "f.field5.qf","field6", "f.field3.qf","field6"));
|
||||
} catch (SolrException e) {
|
||||
fail("This is not cyclic alising");
|
||||
}
|
||||
|
||||
try {
|
||||
h.query(req("defType","edismax", "q","ignore_exception", "qf","field1", "f.field1.qf","field2 field3", "f.field2.qf","field4 field5", "f.field4.qf","field5", "f.field5.qf","field4"));
|
||||
fail();
|
||||
} catch (SolrException e) {
|
||||
assertTrue(e.getCause().getMessage().contains("Field aliases lead to a cycle"));
|
||||
}
|
||||
|
||||
try {
|
||||
h.query(req("defType","edismax", "q","who:(Zapp Pig) ignore_exception", "qf","field1", "f.who.qf","name","f.name.qf","myalias", "f.myalias.qf","who"));
|
||||
fail();
|
||||
} catch (SolrException e) {
|
||||
assertTrue(e.getCause().getMessage().contains("Field aliases lead to a cycle"));
|
||||
ignoreException(".*Field aliases lead to a cycle.*");
|
||||
try {
|
||||
h.query(req("defType","edismax", "q","blarg", "qf","who", "f.who.qf","name","f.name.qf","who"));
|
||||
fail("Simple cyclic alising not detected");
|
||||
} catch (SolrException e) {
|
||||
assertTrue(e.getCause().getMessage().contains("Field aliases lead to a cycle"));
|
||||
}
|
||||
|
||||
try {
|
||||
h.query(req("defType","edismax", "q","blarg", "qf","who", "f.who.qf","name","f.name.qf","myalias", "f.myalias.qf","who"));
|
||||
fail("Cyclic alising not detected");
|
||||
} catch (SolrException e) {
|
||||
assertTrue(e.getCause().getMessage().contains("Field aliases lead to a cycle"));
|
||||
}
|
||||
|
||||
try {
|
||||
h.query(req("defType","edismax", "q","blarg", "qf","field1", "f.field1.qf","field2 field3","f.field2.qf","field4 field5", "f.field4.qf","field5", "f.field5.qf","field6", "f.field3.qf","field6"));
|
||||
} catch (SolrException e) {
|
||||
fail("This is not cyclic alising");
|
||||
}
|
||||
|
||||
try {
|
||||
h.query(req("defType","edismax", "q","blarg", "qf","field1", "f.field1.qf","field2 field3", "f.field2.qf","field4 field5", "f.field4.qf","field5", "f.field5.qf","field4"));
|
||||
fail("Cyclic alising not detected");
|
||||
} catch (SolrException e) {
|
||||
assertTrue(e.getCause().getMessage().contains("Field aliases lead to a cycle"));
|
||||
}
|
||||
|
||||
try {
|
||||
h.query(req("defType","edismax", "q","who:(Zapp Pig)", "qf","field1", "f.who.qf","name","f.name.qf","myalias", "f.myalias.qf","who"));
|
||||
fail("Cyclic alising not detected");
|
||||
} catch (SolrException e) {
|
||||
assertTrue(e.getCause().getMessage().contains("Field aliases lead to a cycle"));
|
||||
}
|
||||
} finally {
|
||||
resetExceptionIgnores();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -930,4 +948,157 @@ public class TestExtendedDismaxParser extends AbstractSolrTestCase {
|
|||
"defType", "edismax")
|
||||
, "*[count(//doc)=1]");
|
||||
}
|
||||
|
||||
public void testEdismaxSimpleExtension() throws SyntaxError {
|
||||
ModifiableSolrParams params = new ModifiableSolrParams();
|
||||
params.set("q", "foo bar");
|
||||
params.set("qf", "subject title^5");
|
||||
params.set("qf_fr", "subject_fr title_fr^5");
|
||||
params.set("qf_en", "subject_en title_en^5");
|
||||
params.set("qf_es", "subject_es title_es^5");
|
||||
|
||||
MultilanguageQueryParser parser = new MultilanguageQueryParser("foo bar", new ModifiableSolrParams(), params, req(params));
|
||||
Query query = parser.parse();
|
||||
assertNotNull(query);
|
||||
assertTrue(containsClause(query, "title", "foo", 5, false));
|
||||
assertTrue(containsClause(query, "title", "bar", 5, false));
|
||||
assertTrue(containsClause(query, "subject", "foo", 1, false));
|
||||
assertTrue(containsClause(query, "subject", "bar", 1, false));
|
||||
|
||||
params.set("language", "es");
|
||||
parser = new MultilanguageQueryParser("foo bar", new ModifiableSolrParams(), params, req(params));
|
||||
query = parser.parse();
|
||||
assertNotNull(query);
|
||||
assertTrue(containsClause(query, "title_es", "foo", 5, false));
|
||||
assertTrue(containsClause(query, "title_es", "bar", 5, false));
|
||||
assertTrue(containsClause(query, "subject_es", "foo", 1, false));
|
||||
assertTrue(containsClause(query, "subject_es", "bar", 1, false));
|
||||
|
||||
FuzzyDismaxQParser parser2 = new FuzzyDismaxQParser("foo bar absence", new ModifiableSolrParams(), params, req(params));
|
||||
query = parser2.parse();
|
||||
assertNotNull(query);
|
||||
assertTrue(containsClause(query, "title", "foo", 5, false));
|
||||
assertTrue(containsClause(query, "title", "bar", 5, false));
|
||||
assertTrue(containsClause(query, "title", "absence", 5, true));
|
||||
|
||||
}
|
||||
|
||||
private boolean containsClause(Query query, String field, String value,
|
||||
int boost, boolean fuzzy) {
|
||||
|
||||
if(query instanceof BooleanQuery) {
|
||||
return containsClause((BooleanQuery)query, field, value, boost, fuzzy);
|
||||
}
|
||||
if(query instanceof DisjunctionMaxQuery) {
|
||||
return containsClause((DisjunctionMaxQuery)query, field, value, boost, fuzzy);
|
||||
}
|
||||
if(query instanceof TermQuery && !fuzzy) {
|
||||
return containsClause((TermQuery)query, field, value, boost);
|
||||
}
|
||||
if(query instanceof FuzzyQuery && fuzzy) {
|
||||
return containsClause((FuzzyQuery)query, field, value, boost);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean containsClause(FuzzyQuery query, String field, String value,
|
||||
int boost) {
|
||||
if(query.getTerm().field().equals(field) &&
|
||||
query.getTerm().bytes().utf8ToString().equals(value) &&
|
||||
query.getBoost() == boost) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean containsClause(BooleanQuery query, String field, String value, int boost, boolean fuzzy) {
|
||||
for(BooleanClause clause:query.getClauses()) {
|
||||
if(containsClause(clause.getQuery(), field, value, boost, fuzzy)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean containsClause(TermQuery query, String field, String value, int boost) {
|
||||
if(query.getTerm().field().equals(field) &&
|
||||
query.getTerm().bytes().utf8ToString().equals(value) &&
|
||||
query.getBoost() == boost) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean containsClause(DisjunctionMaxQuery query, String field, String value, int boost, boolean fuzzy) {
|
||||
for(Query disjunct:query.getDisjuncts()) {
|
||||
if(containsClause(disjunct, field, value, boost, fuzzy)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class MultilanguageQueryParser extends ExtendedDismaxQParser {
|
||||
|
||||
public MultilanguageQueryParser(String qstr, SolrParams localParams,
|
||||
SolrParams params, SolrQueryRequest req) {
|
||||
super(qstr, localParams, params, req);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ExtendedDismaxConfiguration createConfiguration(String qstr,
|
||||
SolrParams localParams, SolrParams params, SolrQueryRequest req) {
|
||||
return new MultilanguageDismaxConfiguration(localParams, params, req);
|
||||
}
|
||||
|
||||
class MultilanguageDismaxConfiguration extends ExtendedDismaxConfiguration {
|
||||
|
||||
public MultilanguageDismaxConfiguration(SolrParams localParams,
|
||||
SolrParams params, SolrQueryRequest req) {
|
||||
super(localParams, params, req);
|
||||
String language = params.get("language");
|
||||
if(language != null) {
|
||||
super.queryFields = SolrPluginUtils.parseFieldBoosts(solrParams.getParams("qf_" + language));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class FuzzyDismaxQParser extends ExtendedDismaxQParser {
|
||||
|
||||
public FuzzyDismaxQParser(String qstr, SolrParams localParams,
|
||||
SolrParams params, SolrQueryRequest req) {
|
||||
super(qstr, localParams, params, req);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ExtendedSolrQueryParser createEdismaxQueryParser(QParser qParser,
|
||||
String field) {
|
||||
return new FuzzyQueryParser(qParser, field);
|
||||
}
|
||||
|
||||
class FuzzyQueryParser extends ExtendedSolrQueryParser{
|
||||
|
||||
private Set<String> frequentlyMisspelledWords;
|
||||
|
||||
public FuzzyQueryParser(QParser parser, String defaultField) {
|
||||
super(parser, defaultField);
|
||||
frequentlyMisspelledWords = new HashSet<String>();
|
||||
frequentlyMisspelledWords.add("absence");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Query getFieldQuery(String field,
|
||||
String val, boolean quoted) throws SyntaxError {
|
||||
if(frequentlyMisspelledWords.contains(val)) {
|
||||
return getFuzzyQuery(field, val, 0.75F);
|
||||
}
|
||||
return super.getFieldQuery(field, val, quoted);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue