I have the following code, which is simply searching the Solr Server.
SolrServer server = new CommonsHttpSolrServer(url);
SolrQuery searchquery = new SolrQuery("company profile");
QueryResponse response = server.query(searchquery)
I want to have the response in json, other than the default which is xml. So I went into the solrconfig.xml file and enabled the following line:
<queryResponseWriter name="json" class="org.apache.solr.request.JSONResponseWriter" />
However, from the console, I'm still getting wt=javabin encoded to the search query request.
Also, I've modified the above code like this:
SolrServer server = new CommonsHttpSolrServer(url);
SolrQuery searchquery = new SolrQuery("company profile");
searchquery.setParam("wt", "json");
QueryResponse response = server.query(searchquery)
But I'm still getting wt=javabin encoded and wt=json also appended, such that the query now looks like this:
webapp/solr path=/select params={wt=javabin&wt=json}
Is there anything I'm doing wrong?
Thanks
SolrJ only supports the javabin and xml formats (configurable with CommonHttpSolrServer.setParser).
But why would you want to use JSON? Javabin is by far the format which provides the best decompression speed, its drawback being that is is not human-readable, on the contrary to JSON and XML (which is not a problem in this case since SolrJ is parsing the result for you).
With SolrJ and json-lib, I was able to get json response like this:
SolrServer server = new CommonsHttpSolrServer(url);
SolrQuery searchquery = new SolrQuery("company profile");
QueryResponse response = server.query(searchquery)
JSONArray jsonObject = JSONArray.fromObject( response.getResults() );
log.log(Level.INFO, "received jsonObject is {0}", jsonObject.toString());
Iterator data = jsonObject.iterator();
SolrResultBean bean = new SolrResultBean();
List output = new ArrayList();
while(data.hasNext()) {
output.add(data.next());
}
log.log(Level.INFO, "json items in the List are {0}", output);
bean.setObject(output);
// wicket page redirect
setResponsePage(SearchPage.class, new PageParameters());
Related
I am able to fetch all the documents for a solr query in Solr 6.3.0 using the JAVA API SolrJ.I want an additional field of correct "score" calculated by solr(using tf,idf and field norm) to rank the documents.I am getting the score field as 1.0 for all the documents.Can you help me get the correct "score" field.
Below is my code snippet and the output.
String urlString = "http://localhost:8983/solr/mycore2";
SolrClient solr = new HttpSolrClient.Builder(urlString).build();
SolrQuery query = new SolrQuery();
query.setQuery( "*" );
query.set("fl", "id,house,postcode,score");
String s="house=".concat(address.getHouseNumber().getCoveredText());
query.addFilterQuery(s);
QueryResponse resp = solr.query(query);
SolrDocumentList list = resp.getResults();
if(list!=null)
{
System.out.println(list.toString());
}
Output
{numFound=4,start=0,maxScore=1.0,docs=[SolrDocument{id=1, house=[150-151], postcode=[641044], score=1.0}, SolrDocument{id=2, house=[150/151], postcode=[641044], score=1.0}, SolrDocument{id=3, house=[151/150], postcode=[641044], score=1.0}, SolrDocument{id=4, house=[151/150], postcode=[641044], score=1.0}]}
Edit
After MatsLindh's suggestion,here is the tweaked code and the output.
String urlString = "http://localhost:8983/solr/mycore2";
SolrClient solr = new HttpSolrClient.Builder(urlString).build();
SolrQuery query = new SolrQuery();
query.setQuery(address.getHouseNumber().getCoveredText().concat(" ").concat(address.getPostcode().getCoveredText()));
query.set("fl", "id,house,postcode,score");
QueryResponse resp = solr.query(query);
SolrDocumentList list = resp.getResults();
if(list!=null)
{
System.out.println(list.toString());
}
Output
{numFound=3,start=0,maxScore=2.4800222,docs=[SolrDocument{id=6, house=[34], postcode=[641006], score=2.4800222}, SolrDocument{id=5, house=[34], postcode=[641005], score=1.2400111}, SolrDocument{id=7, house=[2-11A], postcode=[641006], score=1.1138368}]}
Since you're not querying for anything, you're not getting a score (each score is the same, 1.0f). You're only applying a filter, which does not affect the score.
There is no tf/idf (but remember that Solr now uses BM25 as the default similarity model and not tf/idf) score to calculate if there are no tokens to match in the actual query.
What is the correct way of getting results from solrj using Solr Suggester?
This is my request:
SolrQuery query = new SolrQuery();
query.setRequestHandler("/suggest");
query.setParam("suggest", "true");
query.setParam("suggest.build", "true");
query.setParam("suggest.dictionary", "mySuggester");
query.setParam("suggest.q", "So");
QueryResponse response = server.query(query);
However I found it extremely difficult to get the response. The way I got the response is with this:
NamedList obj = (NamedList)((Map)response.getResponse().get("suggest")).get("mySuggester");
SimpleOrderedMap obj2 = (SimpleOrderedMap) obj.get("So");
List<SimpleOrderedMap> obj3 = (List<SimpleOrderedMap>) obj2.get("suggestions");
This seems to assume a lot about the objects I am getting from the response and will be difficult to anticipate errors.
Is there a better and cleaner way than this?
In new versions have a SuggesterResponse:
https://lucene.apache.org/solr/5_3_1/solr-solrj/org/apache/solr/client/solrj/response/SuggesterResponse.html
Best option is to get it as List, below code worked for me
HttpSolrClient solrClient = new HttpSolrClient(solrURL);
SolrQuery query = new SolrQuery();
query.setRequestHandler("/suggest");
query.setParam("suggest.q", "Ins");
query.setParam("wt", "json");
try {
QueryResponse response = solrClient.query(query);
System.out.println(response.getSuggesterResponse().getSuggestedTerms());
List<String> types=response.getSuggesterResponse().getSuggestedTerms().get("infixSuggester");
System.out.println(types);
} catch (SolrServerException | IOException e) {
e.printStackTrace();
}
You can get the suggestions via the SpellCheckResponse by doing the following
SpellCheckResponse spellCheckResponse=response.getSpellCheckResponse();
Check this link for more details
I am trying to perform a retrieveAndRank query using Java wrapper. I follow the online javadocs for Retrieve and Rank API.
The example there for SearchAndRank is:
https://www.ibm.com/watson/developercloud/retrieve-and-rank/api/v1/#query_ranker
RetrieveAndRank service = new RetrieveAndRank();
service.setUsernameAndPassword("{username}","{password}");
HttpSolrClient solrClient = new HttpSolrClient;
solrClient = getSolrClient(service.getSolrUrl("scfaaf8903_02c1_4297_84c6_76b79537d849"), "{username}","{password}");
SolrQuery query = new SolrQuery("what is the basic mechanism of the transonic aileron buzz");
QueryResponse response = solrClient.query("example_collection", query);
Ranking ranking = service.rank("B2E325-rank-67", response);
System.out.println(ranking);
but RetrieveAndRank class has no such rank(String rankerId, QueryResponse response) method. Just one getting a file or an InputStream as arguments (browsing IBM’s source code I see it expects CSV content not a java QueryResponse there).
How should I pass QueryResponse to the rank method?
I am using solr-solrj-5.5.2.jar and java-sdk-3.2.0-jar-with-dependencies.jar libraries
You need to use the /fcselect query handler and send the ranker_id as a parameter.
The code below assumes you have a Solr collection with documents and you have trained a ranker, otherwise follow this tutorial.
RetrieveAndRank service = new RetrieveAndRank();
service.setUsernameAndPassword(USERNAME, PASSWORD);
// create the solr client
String solrUrl = service.getSolrUrl(SOLR_CLUSTER_ID);
HttpClient client = createHttpClient(solrUrl, USERNAME, PASSWORD);
HttpSolrClient solrClient = new HttpSolrClient(solrUrl, client);
// build the query
SolrQuery query = new SolrQuery("*:*");
query.setRequestHandler("/fcselect");
query.set("ranker_id", RANKER_ID);
// execute the query
QueryResponse response = solrClient.query(SOLR_COLLECTION_NAME, query);
System.out.println("Found " + response.getResults().size() + " documents!");
System.out.println(response);
Make sure you update the service credentials for RetrieveAndRank(USERNAME and PASSWORD), SOLR_CLUSTER_ID, SOLR_COLLECTION_NAME and RANKER_ID.
The code for createHttpClient() can be found here.
I am trying to query Solr using certain fields and I want the response in XML format. Somehow I am not able to get the response in XML format even though I have set the parser to XMLResponseParser. Please check the code and let me know what is wrong in here:
HttpSolrServer solr = new HttpSolrServer(urlString);
String queryString ="*:*";
SolrQuery query = new SolrQuery(queryString);
query.setQuery(queryString);
query.setFields("type", "typestring");
query.addFilterQuery("id");
query.setStart(0);
query.setRows(100);
solr.setParser(new XMLResponseParser());
QueryResponse resp = solr.query(query);
SolrDocumentList results = resp.getResults();
for (int i = 0; i < results.size(); ++i) {
// I need this results in xml format
System.out.println(results.get(i));
}
Your code is using SolrJ as a Solr client. It's precisely done to avoid dealing with XML responses, and it provides a clean way to get Solr results back in your code as objects.
If you want to get the raw xml response, just pick up any java HTTP Client, build the request and send it to Solr. You'll get a nice XML String...
NOTE : You can use ClientUtils.toQueryString(SolrParams params, boolean xml) to build the query part of your URL
As Grooveek already wrote, SolrJ is intended to take XML parsing away from you as a user of the library. If you want to see the XML, you need to fetch the response on your own.
SolrQuery query = new SolrQuery("*:*");
// set indent == true, so that the xml output is formatted
query.set("indent", true);
// use org.apache.solr.client.solrj.util.ClientUtils
// to make a URL compatible query string of your SolrQuery
String urlQueryString = ClientUtils.toQueryString(query, false);
String solrURL = "http://localhost:8080/solr/shard-1/select";
URL url = new URL(solrURL + urlQueryString);
// use org.apache.commons.io.IOUtils to do the http handling for you
String xmlResponse = IOUtils.toString(url);
// have a look
System.out.println(xmlResponse);
I'm developing in java / groovy and am new to the Rally API, I begun using it last week. I want to be able to use the REST API to create a new Test Case Result. On friday (its monday when I wrote this), I got it working using the example below, putting in the data I wanted using arguments into the method. I found this example on another website.
Today when I ran the code, and I dont think I changed anything, I keep getting "ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 1390; received: 1389).
I rewrote the code again, this time not changing anything from the example just to try and get it working again, and I get the same exception. Heres the code I'm using:
public static void createTestCaseResults(){
// Create and configure a new instance of RallyRestApi
RallyRestApi restApi = new RallyRestApi(new URI("https://rally1.rallydev.com"),"username#company.com", "Password");
restApi.setWsapiVersion("1.36");
restApi.setApplicationName("Add Test Case Result");
//Query User
QueryRequest userRequest = new QueryRequest("User");
userRequest.setFetch(new Fetch("UserName", "Subscription", "DisplayName"));
userRequest.setQueryFilter(new QueryFilter("UserName", "=", "username#company.com"));
QueryResponse userQueryResponse = restApi.query(userRequest);
JsonArray userQueryResults = userQueryResponse.getResults();
JsonElement userQueryElement = userQueryResults.get(0);
JsonObject userQueryObject = userQueryElement.getAsJsonObject();
String userRef = userQueryObject.get("_ref").getAsString();
// Query for Test Case to which we want to add results
QueryRequest testCaseRequest = new QueryRequest("TestCase");
testCaseRequest.setFetch(new Fetch("FormattedID","Name"));
testCaseRequest.setQueryFilter(new QueryFilter("FormattedID", "=", "TC7562"));
QueryResponse testCaseQueryResponse = restApi.query(testCaseRequest);
JsonObject testCaseJsonObject = testCaseQueryResponse.getResults().get(0).getAsJsonObject();
String testCaseRef = testCaseQueryResponse.getResults().get(0).getAsJsonObject().get("_ref").getAsString();
try{
//Add a Test Case Result
System.out.println("Creating Test Case Result...");
JsonObject newTestCaseResult = new JsonObject();
newTestCaseResult.addProperty("Verdict", "Pass");
newTestCaseResult.addProperty("Date", "2012-06-12T18:00:00.000Z");
newTestCaseResult.addProperty("Notes", "Automated Selenium Test Runs");
newTestCaseResult.addProperty("Build", "2012.05.31.0020101");
newTestCaseResult.addProperty("Tester", userRef);
newTestCaseResult.addProperty("TestCase", testCaseRef);
CreateRequest createRequest = new CreateRequest("testcaseresult", newTestCaseResult);
CreateResponse createResponse = restApi.create(createRequest);
if(createResponse.wasSuccessful()){
println(String.format("Created %s", createResponse.getObject().get("_ref").getAsString()));
//Read Test Case
String ref = Ref.getRelativeRef(createResponse.getObject().get("_ref").getAsString());
System.out.println(String.format("\nReading Test Case Result %s...", ref));
GetRequest getRequest = new GetRequest(ref);
getRequest.setFetch(new Fetch("Date", "Verdict"));
GetResponse getResponse = restApi.get(getRequest);
JsonObject obj = getResponse.getObject();
println(String.format("Read Test Case Result. Date = %s, Verdict = %s", obj.get("Date").getAsString(), obj.get("Verdict").getAsString()));
} else {
String[] createErrors;
createErrors = createResponse.getErrors();
System.out.println("Error occurred creating Test Case: ");
for (int i=0; i<createErrors.length;i++) {
System.out.println(createErrors[i]);
}
}
}
finally{
restApi.close()
}
}
Appreciate any help with this. Thanks. :)
Is this still happening for you today? I just tried your code on both rally1 and our demo system, and it works reliably every time (only changed username and password, and the test case formatted id).
As a possible next step, I'd set a breakpoint in RallyRestApi.doRequest where the server response code is checked and see what additional information was available - for example, the response code, and the body and headers for the response.
This very well may be a bug in the underlying Apache HttpComponents library. I just upgraded to the latest 4.2.1 components. Would you mind giving the new 1.0.2 jar a try?
https://github.com/RallyTools/RallyRestToolkitForJava
Update:
This has been fixed with the 1.0.4 release of the toolkit today:
https://github.com/downloads/RallyTools/RallyRestToolkitForJava/rally-rest-api-1.0.4.jar