Using Solrj – A short guide to getting started with Solrj
As Solrj – The Java Interface for Solr – is slated for being released together with Solr 1.3, it’s time to take a closer look! Solrj is the preferred, easiest way of talking to a Solr server from Java (unless you’re using Embedded Solr). This way you get everything in a neat little package, and can avoid parsing and working with XML etc directly. Everything is tucked neatly away under a few classes, and since the web generally lacks a good example of how to use SolrJ, I’m going to share a small class I wrote for testing the data we were indexing at work. As Solr 1.2 is the currently most recent version available at apache.org, you’ll have to take a look at the Apache Solr Nightly Builds website and download the latest version. The documentation is also contained in the archive, so if you’re going to do any serious solrj development, this is the place to do it.
Oh well, enough of that, let’s cut to the chase. We start by creating a CommonsHttpSolrServer instance, which we provide with the URL of our Solr server as the only argument in the constructor. You may also provide your own parsers, but I’ll leave that for those who need it. I don’t. By default your Solr-installation is running on port 8080 and under the solr directory, but you’ll have to accomodate your own setup here. I’ve included the complete source file for download.
-
class SolrjTest
-
{
-
public void query(String q)
-
{
-
CommonsHttpSolrServer server = null;
-
-
try
-
{
-
server = new CommonsHttpSolrServer("http://localhost:8080/solr/");
-
}
-
catch(Exception e)
-
{
-
e.printStackTrace();
-
}
The next thing we’re going to do is to actually create the query we’re about to ask the Solr server about, and this means building a SolrQuery object. We simply instanciate the object and then start to set the query values to what we’re looking for. The setQueryType call can be dropped to use the default QueryType-handler, but as we currently use dismax, this is what I’ve used here. You can then also turn on Facet-ing (to create navigators/facets) and add the fields you want for those.
-
SolrQuery query = new SolrQuery();
-
query.setQuery(q);
-
query.setQueryType("dismax");
-
query.setFacet(true);
-
query.addFacetField("firstname");
-
query.addFacetField("lastname");
-
query.setFacetMinCount(2);
-
query.setIncludeScore(true);
Then we simply query the server by calling server.query, which takes our parameters, build the query URL, sends it to the server and parses the response for us.
-
try
-
{
-
QueryResponse qr = server.query(query);
This result can then be fetched by calling .getResults(); on the QueryResponse object; qr.
-
SolrDocumentList sdl = qr.getResults();
We then output the information fetched in the query. You can change this to print all fields or other stuff, but as this is a simple application for searching a database of names, we just collect the first and last name of each entry and print them out. Before we do that, we print a small header containing information about the query, such as the number of elements found and which element we started on.
-
System.out.println("Found: " + sdl.getNumFound());
-
System.out.println("Start: " + sdl.getStart());
-
System.out.println("Max Score: " + sdl.getMaxScore());
-
System.out.println("——————————–");
-
-
ArrayList<HashMap<String, Object>> hitsOnPage = new ArrayList<HashMap<String, Object>>();
-
-
for(SolrDocument d : sdl)
-
{
-
HashMap<String, Object> values = new HashMap<String, Object>();
-
-
for(Iterator<Map.Entry<String, Object>> i = d.iterator(); i.hasNext(); )
-
Map.Entry<String, Object> e2 = i.next();
-
values.put(e2.getKey(), e2.getValue());
-
}
-
-
hitsOnPage.add(values);
-
System.out.println(values.get("displayname") + " (" + values.get("displayphone") + ")");
-
}
After this we output the facets and their information, just so you can see how you’d go about fetching this information from Solr too:
-
List facets = qr.getFacetFields();
-
-
for(FacetField facet : facets)
-
{
-
List facetEntries<FacetField.Count> = facet.getValues();
-
-
for(FacetField.Count fcount : facetEntries)
-
{
-
System.out.println(fcount.getName() + ": " + fcount.getCount());
-
}
-
}
-
}
-
catch (SolrServerException e)
-
{
-
e.printStackTrace();
-
}
-
}
-
-
public static void main(String[] args)
-
{
-
SolrjTest solrj = new SolrjTest();
-
solrj.query(args[0]);
-
}
-
}
And there you have it, a very simple application to just test the interface against Solr. You’ll need to add the jar-files from the lib/-directory in the solrj archive (and from the solr library itself) to compile and run the example.
Download: SolrTest.java


September 10th, 2008 at 20:40
This is great, thanks for posting this… I don’t suppose you know how to add content to the index… I’m digging through the API but there is no documentation (until the release of 1.3 I presume).
Thanks again…
September 10th, 2008 at 20:57
Adding content to the index can be performed by simply POST-ing a suitable XML document to the index by using a regular HTTP POST. You can see this in the regular Solr Tutorial: http://lucene.apache.org/solr/tutorial.html
If you want to use SolrJ for this, there is a very, very simple example in the Solrj Wiki now, check out:
http://wiki.apache.org/solr/Solrj#head-0adf51b414cbf44c692bcadad4b12326df56d298
November 11th, 2008 at 10:36
Nice guide! I have a newbie question though; how do I add the required .jar files when I compile?
November 11th, 2008 at 11:29
Simply provide them together with the -classpath directive to javac and java, or set the CLASSPATH environment variable.
If you’re using an IDE like Netbeans or Eclipse, you can add the libraries by right clicking on your project and selecting add -> library (or something like that, it’s been a while since I added things manually).
Hope that helps!
November 13th, 2008 at 21:00
Mats,
Thanks for the tutorial!
Question: are the CommonsHttpSolrServer and the EmbeddedSolarServer classes thread-safe?
November 13th, 2008 at 22:49
The CommonsHttpSolrServer class represents a client connection to the server, so that should be thread-safe. I have no experience with the EmbeddedSolrServer class, so I’d suggest you post that question to the Solr development list or do a Google search for the issue instead.
If my memory serves me right (which it very well may not do), the EmbeddedSolrServer is considered to be a inferior way of running Solr compared to the full stack.
April 6th, 2009 at 17:41
Hi All,
I want to index the document fields in a xml file to index using solrj. I
know how to index the document fields using doc.addfield(). But I dont know
how to post the xml document instead of adding each field in solrj.
Can I index xml file using solrj? Can anyone help me in how to do this?
Thanks,
May 27th, 2009 at 10:20
Very helpful tutorial!
Trying to follow it, I wrote a small app that uses Solr through Solrj. Everything works fine except for the fact that I don’t get the results I expect. :) Probably because I can’t find where the indexed data is kept. The Solr documentation says that it should go the the solr/data directory which is made automatically by Solr. But it’s not there.
Does anybody know the answer?
Thanks a lot.
May 27th, 2009 at 10:43
@Sergey: Remember to commit after adding the documents, otherwise they will not be added to the index.
@aida: To index xml-files directly, just submit the XML documents through a regular POST operation to the /update-handler. This is what solrj does in the background for you.
August 5th, 2009 at 00:53
A very helpful tutorial, thanks!
BTW, I think this line should be tweaked:
List facetEntries = facet.getValues();
To:
List facetEntries = facet.getValues();
At least with my compiler setup I was getting a warning about missing semicolon in the first version.
September 30th, 2009 at 19:58
Hi,
Does anybody how to query a specific core with solrj ?
I have a core0 configured but I didnt find how to query it with solrj
Thanks
November 23rd, 2009 at 14:47
I am trying to run a SolrJ test program. I am having problems with the Tomcat 6.0 configuration for SolrJ. Sorry for posting the Exception Trace. What does it mean:
org.apache.solr.client.solrj.SolrServerException: Error executing query
at org.apache.solr.client.solrj.request.QueryRequest.process(QueryRequest.java:96)
at org.apache.solr.client.solrj.SolrServer.query(SolrServer.java:109)
at SolrJQuery.query(SolrJQuery.java:64)
at SolrJQuery.main(SolrJQuery.java:112)
Caused by: org.apache.solr.client.solrj.SolrServerException: java.net.SocketTimeoutException: Read timed out
at org.apache.solr.client.solrj.impl.CommonsHttpSolrServer.request(CommonsHttpSolrServer.java:391)
at org.apache.solr.client.solrj.impl.CommonsHttpSolrServer.request(CommonsHttpSolrServer.java:183)
at org.apache.solr.client.solrj.request.QueryRequest.process(QueryRequest.java:90)
… 3 more
Caused by: java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at com.sun.net.ssl.internal.ssl.InputRecord.readFully(InputRecord.java:293)
at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:331)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:789)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1112)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:623)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:828)
at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.flushRequestOutputStream(MultiThreadedHttpConnectionManager.java:1565)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2116)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
at org.apache.solr.client.solrj.impl.CommonsHttpSolrServer.request(CommonsHttpSolrServer.java:335)
… 5 more
November 23rd, 2009 at 15:51
The exception indicates that the request timed out while trying to get results from the Solr server. This can be caused by the Solr server not being available, locking up or other issues. Try issuing the same query through the web interface to the solr server or use Wireshark to look at the traffic between your application and the Solr server.
March 4th, 2010 at 20:42
Hi Mats,
My application already has the Lucene´s indexes and I want to use it with the Solr passing the path where the indexes are stored. How can I do this?
Thanks a lot.
André
March 5th, 2010 at 15:58
Read about how to use an existing Lucene index in Solr at the solr-user mailinglist. Hopefully that helps!