mirror of https://github.com/apache/lucene.git
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:
parent
9b2e0fd1ef
commit
dabddad667
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
Loading…
Reference in New Issue