I've used SI4T for one completed project and one that's currently in development so I've got a bit of experience with it.
I really like the flexibility of the mappings between component data and the index (in our case Solr) and we've been able to get most of the stuff we need into Solr very easily which has been brilliant.
We've had a few more challenging issues at the storage extension side though so I thought it would be worth feeding back on those while they're fresh in my mind now (and I'll add any more I can think of in the next few days) so that you're aware of them and also to maybe be integrated into v2.0.
The biggest issue we ran into was publishing multimedia components which also had metadata attached. We have a DCP for the MM component which is used elsewhere but allowed us to add in the Si4T TBBs and map fields to the index data. The CM side worked great. However on the Storage Extension side, because the DCP was being stored in the DB and the binary (PDF) was being stored on the filestore, they would be handled with 2 separate SearchIndexer instances and as such would effectively overwrite each other when committed to Solr. ie. we would either get the extracted data from the PDF or the metadata and not the binary's content. We had to implement partial updating in the Storage Extension to solve this issue. It's a bit hard coded and hacky (time constraints) to have provided you with the code to release earlier but I can certainly send over what we did if it helps get a proper resolution in v2.0.
The above issue also raised a potential bug in the SearchIndexProcessor.java code in the triggerIndexing function. The function loops over the actions before setting the SearchIndex and performing the actions.
However, it's only outside the for loop that the commit function is called on the SearchIndex object, meaning (as in the above case with the binary and the DCP) only one of these is being committed.
See comments below (I've removed some lines of code to keep it short and to the point!)
public void triggerIndexing(String transactionId)
SearchIndex s = null; <--DECLARE THE SEARCHINDEX OBJECT
for (String itemId : actions.keySet())
BaseIndexData data = actions.get(itemId);
s = this.searchIndexer.get(data.getStorageId()); <-- INSTANTIATE SEARCHINDEX IN THE LOOP
processAction(s, actions, itemId); <-- PERFORM ACTIONS ON THE SEARCHINDEX
} <-- END FOR LOOP
if (s != null)
s.commit(pubId); <-- COMMIT THE (LAST) SEARCHINDEX
As you can see, only the SearchIndex object for the storage type of the last action item will ever be committed.
Hope that helps for now. I will add more as I can remember them.