SOLR-6248: Fixing an exception in case of missing qf

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1636784 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Anshum Gupta 2014-11-05 00:21:42 +00:00
parent 7e07a9c578
commit 2c8de2f35c
3 changed files with 38 additions and 8 deletions

View File

@ -591,7 +591,7 @@ public final class MoreLikeThis {
* @param filteredDocument Document with field values extracted for selected fields.
* @return More Like This query for the passed document.
*/
public Query like(Map<String, ArrayList<String>> filteredDocument) throws IOException {
public Query like(Map<String, Collection<Object>> filteredDocument) throws IOException {
if (fieldNames == null) {
// gather list of valid fields from lucene
Collection<String> fields = MultiFields.getIndexedFields(ir);
@ -754,16 +754,16 @@ public final class MoreLikeThis {
}
private PriorityQueue<ScoreTerm> retrieveTerms(Map<String, ArrayList<String>> fields) throws
private PriorityQueue<ScoreTerm> retrieveTerms(Map<String, Collection<Object>> fields) throws
IOException {
HashMap<String,Int> termFreqMap = new HashMap();
for (String fieldName : fieldNames) {
for (String field : fields.keySet()) {
ArrayList<String> fieldValues = fields.get(field);
for(String fieldValue:fieldValues) {
Collection<Object> fieldValues = fields.get(field);
for(Object fieldValue:fieldValues) {
if (fieldValue != null) {
addTermFrequencies(new StringReader(fieldValue), termFreqMap,
addTermFrequencies(new StringReader(String.valueOf(fieldValue)), termFreqMap,
fieldName);
}
}

View File

@ -27,11 +27,15 @@ import org.apache.solr.core.SolrCore;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrQueryRequestBase;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.QParser;
import org.apache.solr.search.QueryParsing;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@ -42,6 +46,8 @@ public class CloudMLTQParser extends QParser {
super(qstr, localParams, params, req);
}
private static Logger log = LoggerFactory
.getLogger(CloudMLTQParser.class);
public Query parse() {
String id = localParams.get(QueryParsing.V);
// Do a Real Time Get for the document
@ -61,18 +67,28 @@ public class CloudMLTQParser extends QParser {
mlt.setAnalyzer(req.getSchema().getIndexAnalyzer());
String[] qf = localParams.getParams("qf");
Map<String, ArrayList<String>> filteredDocument = new HashMap();
Map<String, Collection<Object>> filteredDocument = new HashMap();
if (qf != null) {
mlt.setFieldNames(qf);
for (String field : qf) {
filteredDocument.put(field, (ArrayList<String>) doc.get(field));
filteredDocument.put(field, doc.getFieldValues(field));
}
} else {
Map<String, SchemaField> fields = req.getSchema().getFields();
ArrayList<String> fieldNames = new ArrayList();
for (String field : doc.getFieldNames()) {
filteredDocument.put(field, (ArrayList<String>) doc.get(field));
// Only use fields that are stored and have an explicit analyzer.
// This makes sense as the query uses tf/idf/.. for query construction.
// We might want to relook and change this in the future though.
if(fields.get(field).stored()
&& fields.get(field).getType().isExplicitAnalyzer()) {
fieldNames.add(field);
filteredDocument.put(field, doc.getFieldValues(field));
}
}
mlt.setFieldNames(fieldNames.toArray(new String[fieldNames.size()]));
}
try {
return mlt.like(filteredDocument);

View File

@ -129,6 +129,20 @@ public class CloudMLTQParserTest extends AbstractFullDistribZkTestBase {
compareParsedQueryStrings(expectedQueryString,
actualParsedQueries.get(counter)));
}
// Assert that {!mlt}id does not throw an exception i.e. implicitly, only fields that are stored + have explicit
// analyzer are used for MLT Query construction.
params = new ModifiableSolrParams();
params.set(CommonParams.Q, "{!mlt}20");
queryResponse = queryServer(params);
solrDocuments = queryResponse.getResults();
expectedIds = new int[]{18, 23, 13, 14, 20, 22, 19, 21, 15, 16};
i = 0;
for (SolrDocument solrDocument : solrDocuments) {
actualIds[i++] = Integer.valueOf(String.valueOf(solrDocument.getFieldValue("id")));
}
assertArrayEquals(expectedIds, actualIds);
}
private boolean compareParsedQueryStrings(String expected, String actual) {