One of the new features of NHibernate ported from Hibernate 3.2 is NHibernate Search. The full text engine Lucene is used by NHibernate to allow applications to execute text queries. This feature you can reach at NHibernate 1.2.1 release or at NHibernate 2.0 (at trunk).
The example of NHibernate Search with NHibernate 2.0 you can download here:
In order to get the text-search at the entities you must decorate with attributes your classes like this:
using NHibernate.Search;
using NHibernate.Search.Attributes;
[Indexed]
public class Book {
private string author;
private int id;
private string name;
private string summary;
public Book() {
}
public Book(int id,string author, string name, string summary) {
this.id = id;
this.author = author;
this.name = name;
this.summary = summary;
}
[DocumentId]
public virtual int Id {
get { return id; }
set { id = value; }
}
[Field(Index.Tokenized, Store = Store.Yes)]
public virtual string Author {
get { return author; }
set { author = value; }
}
[Field(Index.Tokenized, Store = Store.Yes)]
public virtual string Summary {
get { return summary; }
set { summary = value; }
}
[Field(Index.Tokenized, Store = Store.Yes)]
public virtual string Name {
get { return name; }
set { name = value; }
}
}
You can’t configure yet this at hibernate.cfg.xml. The configuration you can do like this. There are some additional steps at the traditional configuration of NHibernate that you need take into account.
cfg = new Configuration();
cfg.SetProperty("hibernate.search.default.directory_provider",
typeof(RAMDirectoryProvider).AssemblyQualifiedName);
cfg.SetProperty(NHibernate.Search.Environment.AnalyzerClass,
typeof(StopAnalyzer).AssemblyQualifiedName);
cfg.Configure();
sf = cfg.BuildSessionFactory();
SearchFactory.Initialize(cfg, sf);
I create 3 books in order to make this demo functional:
using (IFullTextSession s = Search.CreateFullTextSession(sf.OpenSession(new SearchInterceptor()))) {
using(ITransaction tx = s.BeginTransaction()){
Book b1 = new Book(1,
"Eric Evans",
"Domain-Driven Design: Tackling Complexity in the Heart of Software",
@"This book provides a broad framework for making design decisions and a
technical vocabulary for discussing domain design. It is a synthesis of
widely accepted best practices along with the author's own insights and experiences."
);
s.Save(b1);
Book b2 = new Book(2,
"Pierre Kuate",
"NHibernate in Action",
@"In the classic style of Manning's 'In Action' series, NHibernate in Action introduces
.NET developers to the NHibernate Object/Relational Mapping tool. As NHibernate is a
port of Hibernate from Java to .NET.");
s.Save(b2);
Book b3 = new Book(3,
"John Doe",
"Foo book NHibernate",
"Foo series book");
s.Save(b3);
s.Flush();
tx.Commit();
}
}
Lets “query” this scenario. This is using the interface IQuery. The text search engine try to find the “series” at the property Summary.
using (IFullTextSession s = Search.CreateFullTextSession(sf.OpenSession(new SearchInterceptor()))) {
QueryParser qp = new QueryParser("id", new StopAnalyzer());
IQuery NHQuery = s.CreateFullTextQuery(qp.Parse("Summary:series"), typeof(Book));
IList result = NHQuery.List();
Debug.Assert(result.Count == 2);
}
And this is using Criteria way. The example try to find the text “NHibernate” at the properties Summary and Name (name of the book).
using (IFullTextSession s = Search.CreateFullTextSession(sf.OpenSession(new SearchInterceptor()))) {
IList result = s.CreateCriteria(typeof(Book))
.Add(Search.Query("Summary:NHibernate or Name:NHibernate"))
.List();
Debug.Assert(result.Count == 2);
}
As you can see, in order to achieve this search you must use the Interface IFullTextSession instead of ISession or IStatelessSession.