NHibernate Search
Una de las características nuevas de NHibernate portadas de Hibernate 3.2 es NHibernate Search. Lucene es el motor de búsqueda de textos usado por NHibernate que permite a las aplicaciones a realizar consultas sobre texto almacenado. Esta característica está disponible en NHibernate 1.2.1 o en NHibernate 2.0 (versión del SVN).
El ejemplo de NHibernate Search con NHibernate 2.0 está disponible para la descarga aquí:
NHibernate Search Demo
Para poder hacer búsquedas sobre el texto de nuestras entidades debemos decorar nuestros objetos de negocio con algunos atributos como se muestra aquí:
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; } } }
No se puede realizar la configuración vía el archivo hibernate.cfg.xml todavía. La configuración debe lucir como se muestra abajo. Hay unos pasos adicionales a tener en cuenta a la hora de configurar NHibernate Search en nuestra aplicación.
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);
Creé 3 libros (Book) para poder hacer este ejemplo funcional:
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(); } }
Realizamos algunas consultas de texto sobre este escenario. El ejemplo a continuación es utilizando la interfase IQuery. El motor de búsqueda de texto tratará de encontrar la palabra "series" en las propiedad 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); }
Y este ejemplo a continuación es usando Criteria. El ejemplo trata de encontrar el texto "NHibernate" en las propiedades Summary (resume) y Name (nombre del libro)
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); }
Como se puede apreciar, para realizar las búsquedas se debe usar la interfase IFullTextSession en vez de las conocidas hasta el momento ISession o IStatelessSession.
[...] este post estábamos viendo la integración de Lucene.Net con NHibernate mediante NHibernate [...]
[...] NHibernate Search, we can make queries against the index that Lucene maintain, whether in Memory or on File System. [...]