SOLR-1889: The default logic for the 'mm' param of DismaxQParser and ExtendedDismaxQParser has been changed to be determined based on the effective value of the 'q.op' param

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@950710 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Chris M. Hostetter 2010-06-02 18:34:11 +00:00
parent 425ffb2a2b
commit 7000b05a05
6 changed files with 71 additions and 21 deletions

View File

@ -66,6 +66,16 @@ Upgrading from Solr 1.4
(since it has never worked properly). Solr will now warn you if
you attempt to set this configuration option at all. (see SOLR-1846)
* The default logic for the 'mm' param of the 'dismax' QParser has
been changed. If no 'mm' param is specified (either in the query,
or as a default in solrconfig.xml) then the effective value of the
'q.op' param (either in the query or as a default in solrconfig.xml
or from the 'defaultOperator' option in schema.xml) is used to
influence the behavior. If q.op is effectively "AND" then mm=100%.
If q.op is effectively "OR" then mm=0%. Users who wish to force the
legacy behavior should set a default value for the 'mm' param in
their solrconfig.xml file.
Detailed Change List
----------------------
@ -393,6 +403,10 @@ Other Changes
option. It has never worked very well, and in recent versions of
Solr hasn't worked at all. (hossman)
* SOLR-1889: The default logic for the 'mm' param of DismaxQParser and
ExtendedDismaxQParser has been changed to be determined based on the
effective value of the 'q.op' param (hossman)
Build
----------------------

View File

@ -17,9 +17,11 @@
package org.apache.solr.search;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser.Operator;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.DefaultSolrParams;
import org.apache.solr.common.params.DisMaxParams;
@ -47,6 +49,21 @@ public class DisMaxQParser extends QParser {
*/
private static String IMPOSSIBLE_FIELD_NAME = "\uFFFC\uFFFC\uFFFC";
/**
* Applies the appropriate default rules for the "mm" param based on the
* effective value of the "q.op" param
*
* @see QueryParsing#getQueryParserDefaultOperator
* @see QueryParsing#OP
* @see DisMaxParams#MM
*/
public static String parseMinShouldMatch(final IndexSchema schema,
final SolrParams params) {
Operator op = QueryParsing.getQueryParserDefaultOperator
(schema, params.get(QueryParsing.OP));
return params.get(DisMaxParams.MM,
op.equals(Operator.AND) ? "100%" : "0%");
}
public DisMaxQParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) {
super(qstr, localParams, params, req);
@ -194,7 +211,7 @@ public class DisMaxQParser extends QParser {
protected Query getUserQuery(String userQuery, SolrPluginUtils.DisjunctionMaxQueryParser up, SolrParams solrParams)
throws ParseException {
String minShouldMatch = solrParams.get(DisMaxParams.MM, "100%");
String minShouldMatch = parseMinShouldMatch(req.getSchema(), solrParams);
Query dis = up.parse(userQuery);
Query query = dis;

View File

@ -103,6 +103,9 @@ class ExtendedDismaxQParser extends QParser {
SolrParams solrParams = localParams == null ? params : new DefaultSolrParams(localParams, params);
final String minShouldMatch =
DisMaxQParser.parseMinShouldMatch(req.getSchema(), solrParams);
queryFields = U.parseFieldBoosts(solrParams.getParams(DMP.QF));
if (0 == queryFields.size()) {
queryFields.put(req.getSchema().getDefaultSearchFieldName(), 1.0f);
@ -244,7 +247,6 @@ class ExtendedDismaxQParser extends QParser {
}
if (parsedUserQuery != null && doMinMatched) {
String minShouldMatch = solrParams.get(DMP.MM, "100%");
if (parsedUserQuery instanceof BooleanQuery) {
U.setMinShouldMatch((BooleanQuery)parsedUserQuery, minShouldMatch);
}
@ -281,9 +283,6 @@ class ExtendedDismaxQParser extends QParser {
String escapedUserQuery = sb.toString();
parsedUserQuery = up.parse(escapedUserQuery);
// Only do minimum-match logic
String minShouldMatch = solrParams.get(DMP.MM, "100%");
if (parsedUserQuery instanceof BooleanQuery) {
BooleanQuery t = new BooleanQuery();
U.flattenBooleanQuery(t, (BooleanQuery)parsedUserQuery);

View File

@ -65,15 +65,9 @@ class LuceneQParser extends QParser {
}
lparser = new SolrQueryParser(this, defaultField);
// these could either be checked & set here, or in the SolrQueryParser constructor
String opParam = getParam(QueryParsing.OP);
if (opParam != null) {
lparser.setDefaultOperator("AND".equals(opParam) ? QueryParser.Operator.AND : QueryParser.Operator.OR);
} else {
// try to get default operator from schema
QueryParser.Operator operator = getReq().getSchema().getSolrQueryParser(null).getDefaultOperator();
lparser.setDefaultOperator(null == operator ? QueryParser.Operator.OR : operator);
}
lparser.setDefaultOperator
(QueryParsing.getQueryParserDefaultOperator(getReq().getSchema(),
getParam(QueryParsing.OP)));
return lparser.parse(qstr);
}

View File

@ -20,6 +20,7 @@ package org.apache.solr.search;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.queryParser.QueryParser.Operator;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.ConstantScoreQuery;
@ -65,6 +66,23 @@ public class QueryParsing {
public static final char LOCALPARAM_END = '}';
public static final String DOCID = "_docid_";
/**
* Returns the "prefered" default operator for use by Query Parsers,
* based on the settings in the IndexSchema which may be overridden using
* an optional String override value.
*
* @see IndexSchema#getQueryParserDefaultOperator()
* @see #OP
*/
public static Operator getQueryParserDefaultOperator(final IndexSchema sch,
final String override) {
String val = override;
if (null == val) val = sch.getQueryParserDefaultOperator();
return "AND".equals(val) ? Operator.AND : Operator.OR;
}
/**
* Helper utility for parsing a query using the Lucene QueryParser syntax.
*
@ -109,10 +127,8 @@ public class QueryParsing {
public static Query parseQuery(String qs, String defaultField, SolrParams params, IndexSchema schema) {
try {
SolrQueryParser parser = schema.getSolrQueryParser(defaultField);
String opParam = params.get(OP);
if (opParam != null) {
parser.setDefaultOperator("AND".equals(opParam) ? QueryParser.Operator.AND : QueryParser.Operator.OR);
}
parser.setDefaultOperator(getQueryParserDefaultOperator
(schema, params.get(QueryParsing.OP)));
Query query = parser.parse(qs);
if (SolrCore.log.isTraceEnabled()) {

View File

@ -106,9 +106,16 @@ public class TestExtendedDismaxParser extends AbstractSolrTestCase {
assertQ(req("defType", "edismax", "qf", "name title subject text",
"q","op"), twor
);
assertQ(req("defType", "edismax", "qf", "name title subject text",
assertQ(req("defType", "edismax",
"qf", "name title subject text",
"q.op", "AND",
"q","Order op"), oner
);
assertQ(req("defType", "edismax",
"qf", "name title subject text",
"q.op", "OR",
"q","Order op"), twor
);
assertQ(req("defType", "edismax", "qf", "name title subject text",
"q","Order AND op"), oner
);
@ -146,8 +153,11 @@ public class TestExtendedDismaxParser extends AbstractSolrTestCase {
);
// test for stopwords not removed
assertQ(req("defType", "edismax", "qf", "text_sw", "stopwords","false",
"q","the big"), oner
assertQ(req("defType", "edismax",
"qf", "text_sw",
"stopwords","false",
"q.op","AND",
"q","the big"), oner
);
/** stopword removal in conjunction with multi-word synonyms at query time