Search using Lucene in Playframework 1.x

In my web project on Playframework-e at one point, it took the search. The idea of a database search using like I'm immediately dismissed because I like ranking and other buns "smart" search, and to invent a Bicycle was neither the time nor the desire.
As the project is in Java — it was very tempting to use Lucene for this.
In Google I found a great module for Playframework-called Search, was also found module Elastic Search, which also uses Lucene, but it requires installing a separate server, and therefore was a tad off. Module Search liked its simplicity — all the "bells and whistles" in it is encapsulated, so using them is very easy.
With the installation of the module, as always in Play-e, no problems, the command play install search worked on "cheers" and took out a module from a repository.
Adding module.search=${play.path}/modules/search-2.0 application.conf I was able to use it in the application.
Following a brief leadership, I added to the entity Entry, which actually should search, abstract @Indexed, and the description field annotation @Field.
Writing the controller code that resembles the following:
the
public static void search(String phrase, int page) {
int pageSize = PAGE_SIZE;
Query Query = Search.search("description:" + phrase Entry.class);
List<Entry> entries = query.page(page*pageSize, pageSize).fetch();
long totalCount = query.count();
render(entries, totalCount, page, pageSize, phrase);
}

I was ready to do the first tests and to increase the functionality, but then the problems started...

Search did not work, that is, the method count() returned 0, and list entries was empty. I tried to search in Russian and English, and were called Search.rebuildAllIndexes(), and a lot more tried, but the result was unchanged.
The benefit of the module in play-e downloaded along with the source code and could sedebit. A short debugging showed that the index doesn't put the field description. I went a little deeper and saw that in search of the annotations @Field field of the entity uses the method object.getClass().getFields(), but wait, this method returns only public fields, and I have in the entity field as it should have protected access, and the author of the module should use the method getDeclaredFields().
Then I will make a digression: I did not want to rebuild the module and change the code, at least what I would have lost the opportunity to do play install search "battle" server, and have had hands put presbrey module. Write a bug report or provide a patch, it was not a quick undertaking, and the functionality needed now.
In General, it was decided to make description public-ω, and write a todo until you fix this bug in the module. And, lo and behold, search earned!
The next problem, which I already guessed after reading the tutorial, was that the module was "killer feature" — automatic update of the index(and add new records) when a CRUD operations with entity I didn't need to. The fact that the records are added to the system first needs to be validated and I absolutely don't need another "neotraditional" record hit in the search.
I want to call Search.index(entry) after moderation. I was really hoping that I can find in source code check for any line in the config: doing automatic updates or not, but I stumbled upon it in the code SearchPlugin:
the
@Override
public void onEvent(String message, Object context) {
if (!message.startsWith("JPASupport")) 
return;
if (message.equals("JPASupport.objectPersisted") || message.equals("JPASupport.objectUpdated")) {
Search.index (context);
} else  if  (message.equals("JPASupport.objectDeleted")) {
Search.unIndex(context);
}
}

Disable it was not, and it seems it is time to think about what we need to send the patch and kick to quickly release a version with the fix, but then a brilliant idea was born: but I was in fact still be a module or just a set of libraries that I put in the lib folder.
the
Search.init();
FileExtractor.init();

And when you stop
the
try {
Search.shutdown();
} catch (Exception e) {
throw new UnexpectedException (e);
}

This is easily done using the Job s annotations @OnApplicationStart/Stop.
The next step was to "wean" play to think that it is a plugin. Playframework finds modules on the classpath-use the file play.plugins, actually a normal archiver, this file was removed from the jar file, and all spun-spun.
I hope my experience will be useful and will help save time of people who is using Playframework in their work.
PS: if I had to put the module in the lib folder, I've reassembled it at the same time and adjusting an issue with public fields. :)
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

Integration of PostgreSQL with MS SQL Server for those who want faster and deeper

Custom database queries in MODx Revolution

Parse URL in Zend Framework 2