SOLR-7719 - added proper parsing of Suggester results (patch from Alessandro Benedetti)

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1691494 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Tommaso Teofili 2015-07-17 08:32:27 +00:00
parent 58ec4d8824
commit bc5d9f52d1
4 changed files with 294 additions and 0 deletions

View File

@ -49,6 +49,7 @@ public class QueryResponse extends SolrResponseBase
private NamedList<Object> _highlightingInfo = null;
private NamedList<Object> _spellInfo = null;
private List<NamedList<Object>> _clusterInfo = null;
private Map<String,NamedList<Object>> _suggestInfo = null;
private NamedList<Object> _statsInfo = null;
private NamedList<NamedList<Number>> _termsInfo = null;
private String _cursorMarkNext = null;
@ -78,6 +79,9 @@ public class QueryResponse extends SolrResponseBase
// Clustering Response
private ClusteringResponse _clusterResponse = null;
// Suggester Response
private SuggesterResponse _suggestResponse = null;
// Terms Response
private TermsResponse _termsResponse = null;
@ -153,6 +157,10 @@ public class QueryResponse extends SolrResponseBase
_clusterInfo = (ArrayList<NamedList<Object>>) res.getVal(i);
extractClusteringInfo(_clusterInfo);
}
else if ( "suggest".equals( n ) ) {
_suggestInfo = (Map<String,NamedList<Object>>) res.getVal( i );
extractSuggesterInfo(_suggestInfo);
}
else if ( "stats".equals( n ) ) {
_statsInfo = (NamedList<Object>) res.getVal( i );
extractStatsInfo( _statsInfo );
@ -176,6 +184,10 @@ public class QueryResponse extends SolrResponseBase
_clusterResponse = new ClusteringResponse(clusterInfo);
}
private void extractSuggesterInfo(Map<String, NamedList<Object>> suggestInfo) {
_suggestResponse = new SuggesterResponse(suggestInfo);
}
private void extractTermsInfo(NamedList<NamedList<Number>> termsInfo) {
_termsResponse = new TermsResponse(termsInfo);
}
@ -553,6 +565,10 @@ public class QueryResponse extends SolrResponseBase
return _clusterResponse;
}
public SuggesterResponse getSuggesterResponse() {
return _suggestResponse;
}
public TermsResponse getTermsResponse() {
return _termsResponse;
}

View File

@ -0,0 +1,87 @@
package org.apache.solr.client.solrj.response;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
/**
* Encapsulates responses from the Suggester Component
*/
public class SuggesterResponse {
private static final String SUGGESTIONS_NODE_NAME = "suggestions";
private static final String TERM_NODE_NAME = "term";
private static final String WEIGHT_NODE_NAME = "weight";
private static final String PAYLOAD_NODE_NAME = "payload";
private final Map<String, List<Suggestion>> suggestionsPerDictionary = new LinkedHashMap<>();
public SuggesterResponse(Map<String, NamedList<Object>> suggestInfo) {
for (Map.Entry<String, NamedList<Object>> entry : suggestInfo.entrySet()) {
SimpleOrderedMap suggestionsNode = (SimpleOrderedMap) entry.getValue().getVal(0);
List<SimpleOrderedMap> suggestionListToParse;
List<Suggestion> suggestionList = new LinkedList<>();
if (suggestionsNode != null) {
suggestionListToParse = (List<SimpleOrderedMap>) suggestionsNode.get(SUGGESTIONS_NODE_NAME);
for (SimpleOrderedMap suggestion : suggestionListToParse) {
String term = (String) suggestion.get(TERM_NODE_NAME);
long weight = (long) suggestion.get(WEIGHT_NODE_NAME);
String payload = (String) suggestion.get(PAYLOAD_NODE_NAME);
Suggestion parsedSuggestion = new Suggestion(term, weight, payload);
suggestionList.add(parsedSuggestion);
}
suggestionsPerDictionary.put(entry.getKey(), suggestionList);
}
}
}
/**
* get the suggestions provided by each
*
* @return a Map dictionary name : List of Suggestion
*/
public Map<String, List<Suggestion>> getSuggestions() {
return suggestionsPerDictionary;
}
/**
* This getter is lazily initialized and returns a simplified map dictionary : List of suggested terms
* This is useful for simple use cases when you simply need the suggested terms and no weight or payload
*
* @return a Map dictionary name : List of suggested terms
*/
public Map<String, List<String>> getSuggestedTerms() {
Map<String, List<String>> suggestedTermsPerDictionary = new LinkedHashMap<>();
for (Map.Entry<String, List<Suggestion>> entry : suggestionsPerDictionary.entrySet()) {
List<Suggestion> suggestions = entry.getValue();
List<String> suggestionTerms = new LinkedList<String>();
for (Suggestion s : suggestions) {
suggestionTerms.add(s.getTerm());
}
suggestedTermsPerDictionary.put(entry.getKey(), suggestionTerms);
}
return suggestedTermsPerDictionary;
}
}

View File

@ -0,0 +1,63 @@
package org.apache.solr.client.solrj.response;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This class models a Suggestion coming from Solr Suggest Component.
* It is a direct mapping fo the Json object Solr is returning.
*/
public class Suggestion {
private String term;
private long weight;
private String payload;
public Suggestion(String term, long weight, String payload) {
this.term = term;
this.weight = weight;
this.payload = payload;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Suggestion)) return false;
Suggestion that = (Suggestion) o;
return payload.equals(that.payload) && term.equals(that.term);
}
@Override
public int hashCode() {
int result = term.hashCode();
result = 31 * result + payload.hashCode();
return result;
}
public String getTerm() {
return term;
}
public long getWeight() {
return weight;
}
public String getPayload() {
return payload;
}
}

View File

@ -0,0 +1,128 @@
package org.apache.solr.client.solrj.response;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.apache.solr.SolrJettyTestBase;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.request.QueryRequest;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.CommonParams;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* Test for SuggesterComponent's response in Solrj
*
*/
public class TestSuggesterResponse extends SolrJettyTestBase {
@BeforeClass
public static void beforeTest() throws Exception {
initCore();
}
static String field = "cat";
@Test
public void testSuggesterResponseObject() throws Exception {
getSolrClient();
addSampleDocs();
SolrQuery query = new SolrQuery("*:*");
query.set(CommonParams.QT, "/suggest");
query.set("suggest.dictionary", "mySuggester");
query.set("suggest.q", "Com");
query.set("suggest.build", true);
QueryRequest request = new QueryRequest(query);
QueryResponse queryResponse = request.process(client);
SuggesterResponse response = queryResponse.getSuggesterResponse();
Map<String, List<Suggestion>> dictionary2suggestions = response.getSuggestions();
assertTrue(dictionary2suggestions.keySet().contains("mySuggester"));
List<Suggestion> mySuggester = dictionary2suggestions.get("mySuggester");
assertEquals("Computational framework", mySuggester.get(0).getTerm());
assertEquals(0, mySuggester.get(0).getWeight());
assertEquals("", mySuggester.get(0).getPayload());
assertEquals("Computer", mySuggester.get(1).getTerm());
assertEquals(0, mySuggester.get(1).getWeight());
assertEquals("", mySuggester.get(1).getPayload());
}
@Test
public void testSuggesterResponseTerms() throws Exception {
getSolrClient();
addSampleDocs();
SolrQuery query = new SolrQuery("*:*");
query.set(CommonParams.QT, "/suggest");
query.set("suggest.dictionary", "mySuggester");
query.set("suggest.q", "Com");
query.set("suggest.build", true);
QueryRequest request = new QueryRequest(query);
QueryResponse queryResponse = request.process(client);
SuggesterResponse response = queryResponse.getSuggesterResponse();
Map<String, List<String>> dictionary2suggestions = response.getSuggestedTerms();
assertTrue(dictionary2suggestions.keySet().contains("mySuggester"));
List<String> mySuggester = dictionary2suggestions.get("mySuggester");
assertEquals("Computational framework", mySuggester.get(0));
assertEquals("Computer", mySuggester.get(1));
}
@Test
public void testEmptySuggesterResponse() throws Exception {
getSolrClient();
addSampleDocs();
SolrQuery query = new SolrQuery("*:*");
query.set(CommonParams.QT, "/suggest");
query.set("suggest.dictionary", "mySuggester");
query.set("suggest.q", "Empty");
query.set("suggest.build", true);
QueryRequest request = new QueryRequest(query);
QueryResponse queryResponse = request.process(client);
SuggesterResponse response = queryResponse.getSuggesterResponse();
Map<String, List<String>> dictionary2suggestions = response.getSuggestedTerms();
assertTrue(dictionary2suggestions.keySet().contains("mySuggester"));
List<String> mySuggester = dictionary2suggestions.get("mySuggester");
assertEquals(0, mySuggester.size());
}
private void addSampleDocs() throws SolrServerException, IOException {
client.deleteByQuery("*:*");
client.commit(true, true);
SolrInputDocument doc = new SolrInputDocument();
doc.setField("id", "111");
doc.setField(field, "Computer");
SolrInputDocument doc2 = new SolrInputDocument();
doc2.setField("id", "222");
doc2.setField(field, "Computational framework");
SolrInputDocument doc3 = new SolrInputDocument();
doc3.setField("id", "333");
doc3.setField(field, "Laptop");
client.add(doc);
client.add(doc2);
client.add(doc3);
client.commit(true, true);
}
}