SOLR-769: make response JSON friendly, use SolrQueryRequest instead of core

git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@790594 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yonik Seeley 2009-07-02 13:51:19 +00:00
parent 9b2e0fd1ef
commit dabddad667
5 changed files with 55 additions and 61 deletions

View File

@ -72,8 +72,8 @@ public class ClusteringComponent extends SearchComponent implements SolrCoreAwar
SearchClusteringEngine engine = searchClusteringEngines.get(name); SearchClusteringEngine engine = searchClusteringEngines.get(name);
if (engine != null) { if (engine != null) {
DocListAndSet results = rb.getResults(); DocListAndSet results = rb.getResults();
NamedList nl = engine.cluster(rb.getQuery(), results.docList, params); Object clusters = engine.cluster(rb.getQuery(), results.docList, rb.req);
rb.rsp.add("clusters", nl); rb.rsp.add("clusters", clusters);
} else { } else {
log.warn("No engine for: " + name); log.warn("No engine for: " + name);
} }

View File

@ -20,6 +20,7 @@ import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.params.SolrParams; import org.apache.solr.common.params.SolrParams;
import org.apache.solr.core.SolrCore; import org.apache.solr.core.SolrCore;
import org.apache.solr.search.DocList; import org.apache.solr.search.DocList;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
@ -30,7 +31,7 @@ import org.apache.lucene.search.Query;
public abstract class SearchClusteringEngine extends ClusteringEngine { public abstract class SearchClusteringEngine extends ClusteringEngine {
public abstract NamedList cluster(Query query, DocList docList, SolrParams solrParams); public abstract Object cluster(Query query, DocList docList, SolrQueryRequest sreq);
} }

View File

@ -27,6 +27,7 @@ import org.apache.lucene.search.Query;
import org.apache.solr.common.params.HighlightParams; import org.apache.solr.common.params.HighlightParams;
import org.apache.solr.common.params.SolrParams; import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException;
import org.apache.solr.core.SolrCore; import org.apache.solr.core.SolrCore;
import org.apache.solr.handler.clustering.SearchClusteringEngine; import org.apache.solr.handler.clustering.SearchClusteringEngine;
@ -58,23 +59,22 @@ public class CarrotClusteringEngine extends SearchClusteringEngine {
private CachingController controller = new CachingController(); private CachingController controller = new CachingController();
private Class<? extends IClusteringAlgorithm> clusteringAlgorithmClass; private Class<? extends IClusteringAlgorithm> clusteringAlgorithmClass;
private SolrCore core;
private String idFieldName; private String idFieldName;
public NamedList cluster(Query query, DocList docList, SolrParams solrParams) { public Object cluster(Query query, DocList docList, SolrQueryRequest sreq) {
try { try {
// Prepare attributes for Carrot2 clustering call // Prepare attributes for Carrot2 clustering call
Map<String, Object> attributes = new HashMap<String, Object>(); Map<String, Object> attributes = new HashMap<String, Object>();
List<Document> documents = getDocuments(docList, core, query, solrParams); List<Document> documents = getDocuments(docList, query, sreq);
attributes.put(AttributeNames.DOCUMENTS, documents); attributes.put(AttributeNames.DOCUMENTS, documents);
attributes.put(AttributeNames.QUERY, query.toString()); attributes.put(AttributeNames.QUERY, query.toString());
// Pass extra overriding attributes from the request, if any // Pass extra overriding attributes from the request, if any
extractCarrotAttributes(solrParams, attributes); extractCarrotAttributes(sreq.getParams(), attributes);
// Perform clustering and convert to named list // Perform clustering and convert to named list
return clustersToNamedList(controller.process(attributes, return clustersToNamedList(controller.process(attributes,
clusteringAlgorithmClass).getClusters(), solrParams); clusteringAlgorithmClass).getClusters(), sreq.getParams());
} catch (Exception e) { } catch (Exception e) {
log.error("Carrot2 clustering failed", e); log.error("Carrot2 clustering failed", e);
throw new RuntimeException(e); throw new RuntimeException(e);
@ -91,7 +91,6 @@ public class CarrotClusteringEngine extends SearchClusteringEngine {
extractCarrotAttributes(initParams, initAttributes); extractCarrotAttributes(initParams, initAttributes);
this.controller.init(initAttributes); this.controller.init(initAttributes);
this.core = core;
this.idFieldName = core.getSchema().getUniqueKeyField().getName(); this.idFieldName = core.getSchema().getUniqueKeyField().getName();
// Make sure the requested Carrot2 clustering algorithm class is available // Make sure the requested Carrot2 clustering algorithm class is available
@ -116,9 +115,11 @@ public class CarrotClusteringEngine extends SearchClusteringEngine {
/** /**
* Prepares Carrot2 documents for clustering. * Prepares Carrot2 documents for clustering.
*/ */
private List<Document> getDocuments(DocList docList, SolrCore core, private List<Document> getDocuments(DocList docList,
Query query, SolrParams solrParams) { Query query, final SolrQueryRequest sreq) throws IOException {
SolrHighlighter highligher = null; SolrHighlighter highligher = null;
SolrParams solrParams = sreq.getParams();
SolrCore core = sreq.getCore();
// Names of fields to deliver content for clustering // Names of fields to deliver content for clustering
String urlField = solrParams.get(CarrotParams.URL_FIELD_NAME, "url"); String urlField = solrParams.get(CarrotParams.URL_FIELD_NAME, "url");
@ -145,13 +146,16 @@ public class CarrotClusteringEngine extends SearchClusteringEngine {
snippetFieldAry = new String[] { snippetField }; snippetFieldAry = new String[] { snippetField };
args.put(HighlightParams.FIELDS, snippetFieldAry); args.put(HighlightParams.FIELDS, snippetFieldAry);
args.put(HighlightParams.HIGHLIGHT, "true"); args.put(HighlightParams.HIGHLIGHT, "true");
req = new LocalSolrQueryRequest(core, query.toString(), "", 0, 1, args); req = new LocalSolrQueryRequest(core, query.toString(), "", 0, 1, args) {
@Override
public SolrIndexSearcher getSearcher() {
return sreq.getSearcher();
}
};
} }
RefCounted<SolrIndexSearcher> refCounter = core.getSearcher(); SolrIndexSearcher searcher = sreq.getSearcher();
SolrIndexSearcher searcher = refCounter.get();
List<Document> result = new ArrayList<Document>(docList.size()); List<Document> result = new ArrayList<Document>(docList.size());
try {
FieldSelector fieldSelector = new SetBasedFieldSelector(fieldsToLoad, FieldSelector fieldSelector = new SetBasedFieldSelector(fieldsToLoad,
Collections.emptySet()); Collections.emptySet());
float[] scores = { 1.0f }; float[] scores = { 1.0f };
@ -173,11 +177,7 @@ public class CarrotClusteringEngine extends SearchClusteringEngine {
carrotDocument.addField("solrId", doc.get(idFieldName)); carrotDocument.addField("solrId", doc.get(idFieldName));
result.add(carrotDocument); result.add(carrotDocument);
} }
} catch (IOException e) {
log.error("IOException", e);
} finally {
refCounter.decref();
}
return result; return result;
} }
@ -194,9 +194,9 @@ public class CarrotClusteringEngine extends SearchClusteringEngine {
return result.toString().trim(); return result.toString().trim();
} }
private NamedList clustersToNamedList(List<Cluster> carrotClusters, private List clustersToNamedList(List<Cluster> carrotClusters,
SolrParams solrParams) { SolrParams solrParams) {
NamedList result = new NamedList(); List result = new ArrayList();
clustersToNamedList(carrotClusters, result, solrParams.getBool( clustersToNamedList(carrotClusters, result, solrParams.getBool(
CarrotParams.OUTPUT_SUB_CLUSTERS, false), solrParams.getInt( CarrotParams.OUTPUT_SUB_CLUSTERS, false), solrParams.getInt(
CarrotParams.NUM_DESCRIPTIONS, Integer.MAX_VALUE)); CarrotParams.NUM_DESCRIPTIONS, Integer.MAX_VALUE));
@ -204,33 +204,27 @@ public class CarrotClusteringEngine extends SearchClusteringEngine {
} }
private void clustersToNamedList(List<Cluster> outputClusters, private void clustersToNamedList(List<Cluster> outputClusters,
NamedList parent, boolean outputSubClusters, int maxLabels) { List parent, boolean outputSubClusters, int maxLabels) {
for (Cluster outCluster : outputClusters) { for (Cluster outCluster : outputClusters) {
NamedList cluster = new NamedList(); NamedList cluster = new SimpleOrderedMap();
parent.add("cluster", cluster); parent.add(cluster);
List<String> labels = outCluster.getPhrases(); List<String> labels = outCluster.getPhrases();
NamedList labelsNL = new NamedList(); if (labels.size() > maxLabels)
cluster.add("labels", labelsNL); labels = labels.subList(0,maxLabels);
int labelsAdded = 0; cluster.add("labels", labels);
for (String label : labels) {
if (++labelsAdded > maxLabels) {
break;
}
labelsNL.add("label", label);
}
List<Document> docs = outCluster.getDocuments(); List<Document> docs = outCluster.getDocuments();
NamedList docsNL = new NamedList(); List docList = new ArrayList();
cluster.add("docs", docsNL); cluster.add("docs", docList);
for (Document doc : docs) { for (Document doc : docs) {
docsNL.add("doc", doc.getField("solrId")); docList.add(doc.getField("solrId"));
} }
if (outputSubClusters) { if (outputSubClusters) {
NamedList subclustersNL = new NamedList(); List subclusters = new ArrayList();
cluster.add("clusters", subclustersNL); cluster.add("clusters",subclusters);
clustersToNamedList(outCluster.getSubclusters(), subclustersNL, clustersToNamedList(outCluster.getSubclusters(), subclusters,
outputSubClusters, maxLabels); outputSubClusters, maxLabels);
} }
} }

View File

@ -55,7 +55,7 @@ public class ClusteringComponentTest extends AbstractClusteringTest {
rsp.add("responseHeader", new SimpleOrderedMap()); rsp.add("responseHeader", new SimpleOrderedMap());
handler.handleRequest(new LocalSolrQueryRequest(core, params), rsp); handler.handleRequest(new LocalSolrQueryRequest(core, params), rsp);
NamedList values = rsp.getValues(); NamedList values = rsp.getValues();
NamedList clusters = (NamedList) values.get("clusters"); Object clusters = values.get("clusters");
//System.out.println("Clusters: " + clusters); //System.out.println("Clusters: " + clusters);
assertTrue("clusters is null and it shouldn't be", clusters != null); assertTrue("clusters is null and it shouldn't be", clusters != null);
@ -72,7 +72,7 @@ public class ClusteringComponentTest extends AbstractClusteringTest {
rsp.add("responseHeader", new SimpleOrderedMap()); rsp.add("responseHeader", new SimpleOrderedMap());
handler.handleRequest(new LocalSolrQueryRequest(core, params), rsp); handler.handleRequest(new LocalSolrQueryRequest(core, params), rsp);
values = rsp.getValues(); values = rsp.getValues();
clusters = (NamedList) values.get("clusters"); clusters = values.get("clusters");
//System.out.println("Clusters: " + clusters); //System.out.println("Clusters: " + clusters);
assertTrue("clusters is null and it shouldn't be", clusters != null); assertTrue("clusters is null and it shouldn't be", clusters != null);

View File

@ -18,6 +18,7 @@ package org.apache.solr.handler.clustering.carrot2;
*/ */
import java.io.IOException; import java.io.IOException;
import java.util.List;
import org.apache.lucene.search.*; import org.apache.lucene.search.*;
import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.ModifiableSolrParams;
@ -28,6 +29,7 @@ import org.apache.solr.handler.clustering.ClusteringComponent;
import org.apache.solr.search.DocList; import org.apache.solr.search.DocList;
import org.apache.solr.search.SolrIndexSearcher; import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.util.RefCounted; import org.apache.solr.util.RefCounted;
import org.apache.solr.request.LocalSolrQueryRequest;
import org.carrot2.util.attribute.AttributeUtils; import org.carrot2.util.attribute.AttributeUtils;
/** /**
@ -82,12 +84,12 @@ public class CarrotClusteringEngineTest extends AbstractClusteringTest {
return engine; return engine;
} }
private NamedList checkEngine(CarrotClusteringEngine engine, private List checkEngine(CarrotClusteringEngine engine,
int expectedNumClusters) throws IOException { int expectedNumClusters) throws IOException {
return checkEngine(engine, expectedNumClusters, new ModifiableSolrParams()); return checkEngine(engine, expectedNumClusters, new ModifiableSolrParams());
} }
private NamedList checkEngine(CarrotClusteringEngine engine, private List checkEngine(CarrotClusteringEngine engine,
int expectedNumClusters, SolrParams clusteringParams) throws IOException { int expectedNumClusters, SolrParams clusteringParams) throws IOException {
// Get all documents to cluster // Get all documents to cluster
RefCounted<SolrIndexSearcher> ref = h.getCore().getSearcher(); RefCounted<SolrIndexSearcher> ref = h.getCore().getSearcher();
@ -107,45 +109,42 @@ public class CarrotClusteringEngineTest extends AbstractClusteringTest {
solrParams.add(clusteringParams); solrParams.add(clusteringParams);
// Perform clustering // Perform clustering
NamedList results = engine.cluster(query, docList, solrParams); LocalSolrQueryRequest req = new LocalSolrQueryRequest(h.getCore(), solrParams);
List results = (List)engine.cluster(query, docList, req);
req.close();
assertEquals("number of clusters", expectedNumClusters, results.size()); assertEquals("number of clusters", expectedNumClusters, results.size());
checkClusters(results, false); checkClusters(results, false);
return results; return results;
} }
private void checkClusters(NamedList results, int expectedDocCount, private void checkClusters(List results, int expectedDocCount,
int expectedLabelCount, int expectedSubclusterCount) { int expectedLabelCount, int expectedSubclusterCount) {
for (int i = 0; i < results.size(); i++) { for (int i = 0; i < results.size(); i++) {
if (results.getName(i).equals("cluster")) { NamedList cluster = (NamedList) results.get(i);
NamedList cluster = (NamedList) results.getVal(i);
checkCluster(cluster, expectedDocCount, expectedLabelCount, checkCluster(cluster, expectedDocCount, expectedLabelCount,
expectedSubclusterCount); expectedSubclusterCount);
} }
} }
}
private void checkClusters(NamedList results, boolean hasSubclusters) { private void checkClusters(List results, boolean hasSubclusters) {
for (int i = 0; i < results.size(); i++) { for (int i = 0; i < results.size(); i++) {
if (results.getName(i).equals("cluster")) { checkCluster((NamedList)results.get(i), hasSubclusters );
NamedList cluster = (NamedList) results.getVal(i);
checkCluster(cluster, hasSubclusters);
}
} }
} }
private void checkCluster(NamedList cluster, boolean hasSubclusters) { private void checkCluster(NamedList cluster, boolean hasSubclusters) {
NamedList docs = (NamedList) cluster.get("docs"); List docs = (List)cluster.get("docs");
assertNotNull("docs is null and it shouldn't be", docs); assertNotNull("docs is null and it shouldn't be", docs);
for (int j = 0; j < docs.size(); j++) { for (int j = 0; j < docs.size(); j++) {
String id = (String) docs.getVal(j); String id = (String) docs.get(j);
assertNotNull("id is null and it shouldn't be", id); assertNotNull("id is null and it shouldn't be", id);
} }
NamedList labels = (NamedList) cluster.get("labels"); List labels = (List) cluster.get("labels");
assertNotNull("labels is null but it shouldn't be", labels); assertNotNull("labels is null but it shouldn't be", labels);
if (hasSubclusters) { if (hasSubclusters) {
NamedList subclusters = (NamedList) cluster.get("clusters"); List subclusters = (List) cluster.get("clusters");
assertNotNull("subclusters is null but it shouldn't be", subclusters); assertNotNull("subclusters is null but it shouldn't be", subclusters);
} }
} }
@ -154,12 +153,12 @@ public class CarrotClusteringEngineTest extends AbstractClusteringTest {
int expectedLabelCount, int expectedSubclusterCount) { int expectedLabelCount, int expectedSubclusterCount) {
checkCluster(cluster, expectedSubclusterCount > 0); checkCluster(cluster, expectedSubclusterCount > 0);
assertEquals("number of docs in cluster", expectedDocCount, assertEquals("number of docs in cluster", expectedDocCount,
((NamedList) cluster.get("docs")).size()); ((List) cluster.get("docs")).size());
assertEquals("number of labels in cluster", expectedLabelCount, assertEquals("number of labels in cluster", expectedLabelCount,
((NamedList) cluster.get("labels")).size()); ((List) cluster.get("labels")).size());
if (expectedSubclusterCount > 0) { if (expectedSubclusterCount > 0) {
NamedList subclusters = (NamedList) cluster.get("clusters"); List subclusters = (List) cluster.get("clusters");
assertEquals("numClusters", expectedSubclusterCount, subclusters.size()); assertEquals("numClusters", expectedSubclusterCount, subclusters.size());
assertEquals("number of subclusters in cluster", assertEquals("number of subclusters in cluster",
expectedSubclusterCount, subclusters.size()); expectedSubclusterCount, subclusters.size());