This project is a non-GUI application intended to illustrate
the Hibernate search mechanisms. It assumes that you have already
installed and run the SwingNotes
project from the Swing Notes Project document,
so that the swingnotes
MySQL database is viable. The support files, including the
models package as well as the XML configuration
files are identical to those
in that project.
Download the
HibernateSearchExample.zip archive
and install it as a Java Project with Existing Sources
with project name HibernateSearchExample. Add the MySQL Driver
and HibernateSearch libraries to the project and run it.
The word "object" is a good choice for search keyword.
Fulltext search
Fulltext search is a well-known method which achieves its speed
on large documents by an indexing technique.
A keyword search is normally meant to match against the
the keyword's presence in the text as an complete word
(in a case-insensitive manner), not a
substring of a longer word.
Certain common English words, like "a", "an", "the" are ignored
in the search indexing.
MySQL native fulltext search
MySQL, per se, permits fulltext search on its tables using a table
declaration something like this:
create table ... (
content text not null,
...
fulltext(content),
...
) type=myisam;
The fulltext declaration is necessary
and the type=myisam may be necessary, depending on the MySQL
installation details.
Record selection based upon matching a given keyword within
the content field is most commonly
done like this:
SELECT ... WHERE MATCH(content) AGAINST ('keyword' IN BOOLEAN MODE);
Hibernate fulltext search
Hibernate's fulltext search method
does not use any of the DBMS's native fulltext search capability.
Instead, it is based on fulltext search drivers from the Java open source
Lucene code:
One of the key features with this search method
is the presence of a directory, indexes, which
serves as persistent storage (effectively, an extension
of the database). It is used for indexing the
content field of Notes.
This directory is specified by the hibernate.cfg.xml
property setting:
Any pre-created Notes
(such as those created by the table-data.sql file) need to
to be explicity indexed as is done in this example program.
Otherwise, the indexing takes place automatically for Update, Insert and
Delete operations by virtue of the three event element
specifications in hibernate.cfg.xml.
Main program
hibernatesearchexample.Main
package hibernatesearchexample;
import org.hibernate.*;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.apache.lucene.queryParser.*;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import java.util.List;
import models.*;
public class Main {
public static void main(String[] args) {
DB db = new DB();
// Index pre-existing database elements is only necessary for
// records which were NOT created by Hibernate's
// insert, delete and update operations
System.out.println("Indexing pre-existing elements");
Session sess = db.getSession();
List<Note> notes = sess.createCriteria(Note.class).list();
FullTextSession ftsess = Search.getFullTextSession(sess);
ftsess.getTransaction().begin();
for (Note note : notes) {
ftsess.index(note);
}
ftsess.getTransaction().commit();
// obtain the search key and define the Lucene parser
String[] fields = new String[]{"content"};
QueryParser parser
= new MultiFieldQueryParser(fields, new StandardAnalyzer());
String
key = javax.swing.JOptionPane.showInputDialog("Enter search key");
if (key == null) {
// dialog was cancelled
System.exit(1);
}
key = key.trim();
org.apache.lucene.search.Query lquery = null;
try {
lquery = parser.parse(key);
} catch (Exception x) {
x.printStackTrace();
System.exit(1);
}
// create the Hibernate search query as a wrapper around
// the Lucene query
sess = db.getSession();
ftsess = Search.getFullTextSession(sess);
org.hibernate.Query
hquery = ftsess.createFullTextQuery(lquery, Note.class);
List<Note> results = hquery.list(); // execute the query
System.out.println("\n# matching records: " + results.size());
for (Note note : results) {
System.out.println("\n" + note);
}
System.exit(0);
}
}