Thoughts about technology, business and all that's life.

This blog has moved to http://shal.in.

Monday, September 28, 2009

What's new in DataImportHandler in Solr 1.4

DataImportHandler is a Apache Solr module that provides a configuration driven way to import data from databases, XML and other sources into Solr in both "full builds" and incremental delta imports.

A large number of new features have been introduced since it was introduced in Solr 1.3.0. Here's a quick look at the major new features:

Error Handling & Rollback

Ability to control behavior on errors was an oft-request feature in DataImportHandler. With Solr 1.4, DataImportHandler provides configurable error handling options for each entity. You can specify the following as an attribute on the "entity" tag:
  1. onError="abort" - Aborts the import process
  2. onError="skip" - Skips the current document
  3. onError="continue" - Continues as if the error never occurred
All errors are still logged regardless of the selected option. When an import aborts, either due to an error or a user command, all changes to the index since the last commit are rolled back.

Event Listeners

An API is exposed to write listeners for import start and end. A new interface called EventListener has been introduced which has a single method:

public void onEvent(Context ctx);

For example, the listener can be specified as:
<document onImportStart="com.foo.StartListener" onImportEnd="com.foo.EndListener">
Push data to Solr through DataImportHandler

In Solr 1.3, DataImportHandler was pull based only. If you wanted to push data to Solr e.g. through a HTTP POST request, you had no choice but to convert it to Solr's update XML format or CSV format. That meant that all the DataImportHandler goodness was not available. With Solr 1.4, a new DataSource named ContentStreamDataSource allows one to push data to Solr through a regular POST request.

Suppose one wants to push the following XML to Solr and use DataImportHandler to parse and index:

<root>
<b>
<id>1</id>
<c>Hello C1</c>
</b>
<b>
<id>2</id>
<c>Hello C2</c>
</b>
</root>

We can use ContentStreamDataSource to read the XML pushed to Solr through HTTP POST:

<dataConfig>
<dataSource type="ContentStreamDataSource" name="c"/>
<document>
<entity name="b" dataSource="c" processor="XPathEntityProcessor"
forEach="/root/b">
<field column="desc" xpath="/root/b/c"/>
<field column="id" xpath="/root/b/id"/>
</entity>
</document>
</dataConfig>

More Power to Transformers

New flag variables have been added which can be emitted by custom Transformers to skip rows, delete documents or stop further transforms.

New DataSources
  • FieldReaderDataSource - Reads data from an entity's field. This can be used, for example, to read XMLs stored in databases.
  • ContentStreamDataSource - Accept HTTP POST data in a content stream (described above)
New EntityProcessors
  • PlainTextEntityProcessor - Reads from any DataSource and outputs a String
  • MailEntityProcessor (experimental) - Indexes mails from POP/IMAP sources into a solr index. Since it required extra dependencies, it is available as a separate package called "solr-dataimporthandler-extras".
  • LineEntityProcessor - Streams lines of text from a given file to be indexed directly or for processing with transformers and child entities.
New Transformers
  • HTMLStripTransformer - Strips HTML tags from input text using Solr's HTMLStripCharFilter
  • ClobTransformer - Read strings from Clob types in databases.
  • LogTransformer - Log data in a given template format. Very useful for debugging.
Apart from the above new features, there have been numerous bug fixes, optimizations and refactorings. In particular:
  • Optimized defaults for database imports
  • Delta imports consume less memory
  • A 'deltaImportQuery' attribute has been introduced which is used for delta imports along with 'deltaQuery' instead of DataImportHandler manipulating the SQL itself (which was error-prone for complex queries). Using only 'deltaQuery' without a 'deltaImportQuery' is deprecated and will be removed in future releases.
  • The 'where' attribute has been deprecated in favor of 'cacheKey' and 'cacheLookup' attributes making CachedSqlEntityProcessor easier to understand and use.
  • Variables placed in DataSources, EntityProcessor and Transformer attributes are now resolved making very dynamic configurations possible.
  • JdbcDataSource can lookup javax.sql.DataSource using JNDI
  • A revamped EntityProcessor APIs for ease in creating custom EntityProcessors
There are many more changes, see the changelog for the complete list. There's a new DIHQuickStart wiki page which can help you get started faster by providing cheat sheet solutions. Frequently asked questions along with their answers are recorded in the new DataImportHandlerFaq wiki page.

A big THANKS to all the contributors and users who have helped us by giving patches, suggestions and bug reports!

Future Roadmap

Once Solr 1.4 is released, there are a slew of features targeted for Solr 1.5, including:
  • Multi-threaded indexing
  • Integration with Solr Cell to import binary and/or structured documents such as Office, Word, PDF and other proprietary formats
  • DataImportHandler as an API which can be used for creating Lucene indexes (independent of Solr) and as a companion to Solrj (for true push support). It will also be possible to extend it for other document oriented, de-normalized data stores such as CouchDB.
  • Support for reading Gzipped files
  • Support for scheduling imports
  • Support for Callable statements (stored procedures)
If you have any feature requests or contributions in mind, do let us know on the solr-user mailing list.

Saturday, September 26, 2009

Apache Lucene 2.9 Released


Apache Lucene 2.9 has been released. Apache Lucene is a high performance, full-featured text search engine library written entirely in Java.

From the official announce email:

Lucene 2.9 comes with a bevy of new features, including:
  • Per segment searching and caching (can lead to much faster reopen among other things)
  • Near real-time search capabilities added to IndexWriter
  • New Query types
  • Smarter, more scalable multi-term queries (wildcard, range, etc)
  • A freshly optimized Collector/Scorer API
  • Improved Unicode support and the addition of Collation contrib
  • A new Attribute based TokenStream API
  • A new QueryParser framework in contrib with a core QueryParser replacement impl included.
  • Scoring is now optional when sorting by Field, or using a custom Collector, gaining sizable performance when scores are not required.
  • New analyzers (PersianAnalyzer, ArabicAnalyzer, SmartChineseAnalyzer)
  • New fast-vector-highlighter for large documents
  • Lucene now includes high-performance handling of numeric fields. Such fields are indexed with a trie structure, enabling simple to use and much faster numeric range searching without having to externally pre-process numeric values into textual values.
  • And many, many more features, bug fixes, optimizations, and various improvements.
Look at the release announcement for more details.

Congratulations to the Lucene team! Great work as always.

This is also the last minor release which supports Java 1.4 platform. The next release will be 3.0 with which deprecated APIs will be removed and Lucene will officially move to Java 5.0 as the minimum requirement.

Solr 1.4 is not far behind and we hope to release it within two weeks.

Monday, July 06, 2009

Thoughts on Tomcat

I saw an advertisement today for taking a survey on Tomcat to help define it's future directions. I don't usually click on ads but this one seemed interesting so I did. It was a short one (thanks guys!) so I didn't mind completing it. What I did not like so much was the focus on questions on how Tomcat can compete with "enterprise" application servers. What is "enterprise" anyway? If it's about performance then Tomcat is enterprise ready. It doesn't really matter if other commercial servers can do a few more requests per second on artificial tests. Tomcat is free (as in freedom)!. That's a huge advantage.

Tomcat is the most widely used application deployment platform at AOL. As with most other web companies, we don't really need all the cruft, cost and complexity which "enterprise" application servers bring in. It is a tried and tested platform with good performance characteristics, easy administration and monitoring. It scales well enough. We run thousands of Tomcats serving hundreds of millions of pages. Since it is free, we don't need to scale by buying expensive servers, we can just scale out by adding more low cost servers (which, by the way, also adds redundancy)

I don't think Tomcat's goal should be to add features (read complexity) to compete with the so called enterprise application servers. It should continue to focus on being a performant Servlet/JSP container with easy development, administration and monitoring support. What I'd like to see added to Tomcat is:
  • Easy ways to use Tomcat in an embedded fashion (like Jetty)
  • Improve Tomcat manager
  • Easy configuration for my webapp (Properties vs. JNDI/context)
I'm not a guy who adds features just for the heck of them. So I'll give use-cases for each of the above requests. These use-cases come from my own recent work.

Easy ways to use Tomcat in an embedded fashion

I don't see myself shipping a product with an embedded tomcat but I've frequently needed to have an embedded container for unit/integration testing REST APIs. Sometimes, I've used Jetty, other times I've mocked stuff. All of my production deployments use Tomcat so it is only natural that I use Tomcat for integration testing. Solr uses Jetty for testing and for providing a standalone example which works great. I like the easy embeddable nature of Jetty. However, I also believe that part of the reason behind the popularity of Jetty was that Tomcat was not embeddable enough. It had a lot of strongly coupled extra features (and a lot of related code) which were not needed. Valves, realms, JNDI contexts, authentication and clusters are things which are generally not needed in the embeddable scenarios. Note that embedding Tomcat is possible but it is not documented that well and there is no easy way to find out all the dependency jars I'd need to do that. The last time I did this successfully with Maven, I had to track down the dependencies myself and add each one to my application to make it work. So easy for me means: publish latest jars to Maven, use the dependency structure that Maven provides, make it easy for me to remove the extra features I don't need, focus on keeping the artifacts smaller and have good documentation on how to use the API.

Improve Tomcat Manager

A few months ago, I worked on a deployment application to push code updates to Tomcat servers across data centers. The use-case is simple. I want to update my application's code without causing a downtime. So I drain traffic away from individual servers, update the code, verify that it is in fact updated, and redirect traffic back to the server. I worked with the features provided by the Tomcat manager application. Not too many people actually use the Manager in the name of security but that's a separate topic. I wanted to add some custom commands to the manager and I couldn't because it was not designed to be extensible. In the end, I had to copy code from Tomcat's sources and modify to make it work. This is an area which could use some improvement. Coupled with good documentation on how to securely use the manager application, it has the potential to be used more widely. I want to use the Tomcat manager application from certain whitelisted IPs and only with SSL. Sounds simple but it was damn hard to get it working the way we wanted.

Easy configuration for my webapp

Configuration is a difficult issue. There are always so many right ways depending on who you ask. I just need to provide some key/value pairs to my application which change rarely but when they do, I'd really like them to be reloaded without bringing my application down. I'd really like to push those into the war but then I'd have different wars for different environments (dev/qa/prod) and that'd make some people very nervous (why?). I could use JNDI but that is much more complicated to manage than it needs to be for my simple use-case. Sysadmins don't like XML, and that is a well-known fact. It's easier for everybody to modify properties files vs an XML file for simple key/value pairs. I want to hot reload them, just like Tomcat hot-loads wars dropped into the webapps directory but I guess you can't do that. So I write my own small sweet library to read properties files from a certain location, checking every few minutes for changes to the file. If Tomcat itself had something similar, I'd just use that. I think it might be a very common use-case.

On a related note, I'm very excited about tomcat-lite, comet/bayuex and the new servlet API (asynchronous servlets) coming into Tomcat. I also wish for an easy way to write non-HTTP applications on top of Tomcat's NIO stack (again de-coupling may help) but that maybe asking too much. I know it's all do-o-cracy and I'm not doing my part. Someday I hope to contribute code rather than just ideas and complaints. For now, this is all I have.

Thursday, May 28, 2009

Solr in PHP/Drupal, Ruby/Sunspot and Python/Haystack

Adoption of Apache Solr is accelerating. Being accessible though HTTP makes it possible for Solr (a Java webapp) to be used with any language. All you need is support for making HTTP calls and parsing one of the many available formats such as XML or JSON.

Drupal

Drupal is one of the most popular CMS available as open source. It is written in PHP and boasts of a huge user and developer base. Recently, the Drupal community has integrated Apache Solr into Drupal for vertical search. The integration is available as a Drupal module at http://drupal.org/project/apachesolr. There are some excellent tutorials available on how to get started with using this as well as a hosted solution by Acquia.

Ruby

Ruby integration has been present in Solr since a long time. There is a module called solr-ruby as well as acts_as_solr. Solr even has a ruby response writer which outputs search results serialized in ruby. Blacklight is an open source project I know that uses Solr and is built in Ruby. Today, I came to know about SunSpot - A Solr powered search engine for Ruby. More details at this article in LinuxMag.

Python

Solr has a python response writer as well as many clients. See http://wiki.apache.org/solr/SolPython for details. Reddit is one site that uses Solr with a python front-end application. There is also HayStack for Django which can use Solr among other engines such as Xapian and Whoosh.

Solr 1.4 is nearing release with a number of features and performance improvements. On the other hand, Lucene is getting ready for near real-time search as well. Things are getting interesting in the Solr world!

Monday, April 20, 2009

Burst of activity in Lucene

There is a large amount of work being done in Lucene 2.9, in which a large portion is related to adding support for near real-time search.

To put it very simply, search engines transfer a lot of work from query-time to index-time. The reason this is done, is to speed up queries at the cost of adding documents slower. Until now, Lucene based systems have had problems with dealing with scenarios in which the searchers need to see the changes instantly (think Twitter Search). There exist a variety of tricks and techniques to acheive this even now. However, near real-time search support in Lucene itself is a boon to all those people who have been building and managing such systems because the grunt work will be done by Lucene itself.

This is still under development and will probably take a few more months to mature. Solr will benefit from it as well but before that can happen, a lot of work will be needed under the hood particularly in the way Solr handles its caching.

Michael McCandless has summarized the current state of Lucene trunk in this email on java-dev mailing list. In fact, there is so much activity that, at times, it becomes very difficult to follow all the excellent discussions that go on. There are some very talented people on that forum and it is a lot of learning for a guy like me, who started with Solr and is still trying to find his way in the Lucene code base.

Lucene 2.9 will bring huge improvements and I'm looking forward to working with other Solr developers to integrate them with Solr.

About Me

My photo
Committer on Apache Solr. Principal Software Engineer at AOL.

Twitter Updates

    follow me on Twitter

    Recently shared stories

    Recent questions on Apache Solr

    Recent development in Apache Solr