Sei sulla pagina 1di 182

ii

Abstract
In recent years, advances in the eld of Information Retrieval has accelerated the provision of intelligent tools that help us to access information in an unstructured way using natural language. These tools are capable of searching for web pages, map locations, jobs, products, images and many other elements. In parallel to advances in information retrieval, the eld of software engineering shows a widespread adoption of object oriented programming, modeling business process and entities into domain models. This fact has been strengthened in the context of enterprise applications, which support organization's business and processes. This thesis is about the construction of a search engine over domain models, a problem called the Domain Model Search problem. This thesis makes a survey of the state of the art in information retrieval, domain models and their persistence. Additionally, we make case studies of tools that solve similar problems. As part of experimentation, there has been built a complete and extensible search engine for indexing and retrieving information over domain models, validating this framework on dierent domains and achieving a state of the art performance.
Keywords:

information retrieval, search engines, indexing, software engineering, domain models,

enteprise applications

Resumen
Desde hace algunos aos, los avances en el campo de Recuperacin de Informacin han acelerado la provisin de herramientas inteligentes que nos ayudan a acceder a la informacin de manera desestructurada utilizando el lenguaje natural. Estas herramientas que son capaces de buscar pginas web, ubicaciones en el mapa, empleos, productos, imgenes y muchos otros elementos. En paralelo a los avances en materia de recuperacin de la informacin, el campo de la ingeniera de software muestra una amplia adopcin de la programacin orientada a objetos, modelando procesos y entidades de negocio en modelos del dominio. Este hecho se ha visto potenciado en el contexto de las aplicaciones empresariales, las cuales soportan el negocio y/o los procesos de las organizaciones. Esta tesis trata la construccin de un motor de bsqueda sobre objetos de un modelo de dominio, lo cual llamamos el problema de Recuperacin de Informacin sobre Modelos de Dominio. En este trabajo se realiza un relevamiento del estado del arte en materia de recuperacin de la informacin, modelos de dominio y su persistencia, tomando casos de estudio de herramientas que resuelven problemas similares. Como parte de la experimentacin se ha construido un framework completo y extensible para la indexacin y recuperacin de informacin sobre objetos, validndolo en distintos dominios y logrando rendimientos propios del estado del arte.

recuperacin de informacin, motor de bsqueda, indexacin, ingeniera de software, modelos de dominio, aplicaciones empresariales
Palabras Clave:

ndice general
1. Introduccin
1.1. Motivacin 1.1.1. 1.1.2. 1.1.3. 1.1.4. 1.2. 1.3. 1.4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Information Retrieval

1
1 1 2 2 4 5 5 5

Modelos de Dominio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . El problema del Domain Model Search . . . . . . . . . . . . . . . . . . . . . . . . . Objetivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Contribucin de la Tesis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Plan de Tesis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Algunas convenciones adoptadas

2. Estado del Arte


2.1. Information Retrieval 2.1.1. 2.1.2. 2.1.3. 2.1.4. 2.1.5. 2.1.6. 2.2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Clasicacin de los Sistemas de IR . . . . . . . . . . . . . . . . . . . . . . . . . . . Deniciones Generales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mtricas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Modelos de Information Retrieval . . . . . . . . . . . . . . . . . . . . . . . . . . . . Tcnicas de Matching y Acceso a Datos . . . . . . . . . . . . . . . . . . . . . . . .

7
7 7 8 9 12 21 35 44 44 50 51 54 55 55 56 56 57 59 59 65

Tcnicas de Puntaje y Relevancia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Modelos de Dominio 2.2.1. 2.2.2. 2.2.3.

Deniciones Generales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Independencia del Modelo de Dominio . . . . . . . . . . . . . . . . . . . . . . . . . Inversin del Control e Inyeccin de Dependencias . . . . . . . . . . . . . . . . . .

2.3.

Persistencia de Modelos de Dominio 2.3.1. 2.3.2. 2.3.3. 2.3.4. 2.3.5. 2.3.6. 2.3.7. 2.3.8.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Persistencia y Ciclos de Vida en Aplicaciones Enterprise . . . . . . . . . . . . . . . Persistencia Manual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Persistencia Administrada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Binaria Ad-Hoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Object Relational Mapper (ORM) . . . . . . . . . . . . . . . . . . . . . . . . . . .

Bases de Datos Orientadas a Objetos . . . . . . . . . . . . . . . . . . . . . . . . . .

iii

iv

NDICE GENERAL

2.4.

Casos de Estudio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.1. 2.4.2. 2.4.3. 2.4.4. Apache Lucene . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Hibernate Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Compass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

65 66 70 73 78

Anlisis de Hibernate Search y Compass . . . . . . . . . . . . . . . . . . . . . . . .

3. Desarrollo de la Propuesta de Solucin


3.1. Anlisis General del Problema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.1. 3.1.2. 3.1.3. 3.1.4. 3.2. Modelos de IR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

85
85 85 86 93 98 100 100 100 103 108 108 108 112 118 122

Tcnicas de Matching y Acceso a Datos Procesos de Indexacin

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Tcnicas de Puntaje y Relevancia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Mapeo de Clases 3.2.1. 3.2.2. 3.2.3.

Introduccin

Conguracin y Mapeo

Mapeos Avanzados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3.3.

Diseo del Framework de IR sobre objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.1. 3.3.2. 3.3.3. 3.3.4. 3.3.5. Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Arquitectura del Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Tcnicas de Matching y Acceso a Datos Procesos de Indexacin . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Tcnicas de Puntaje y Relevancia . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4. Experimentacin
4.1. 4.2. Tipo de Pruebas Efectuadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Pruebas con Aplicaciones de Referencia 4.2.1. 4.2.2. 4.2.3. 4.3. PetClinic Klink . . . . . . . . . . . . . . . . . . . . . . . . . . . .

129
129 130 130 137 145 151 151 153 163

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

KStore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Pruebas de Calidad y Rendimiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3.1. 4.3.2. 4.3.3. Pruebas de Calidad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Pruebas de Rendimiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Anlisis Comparativo Cualitativo . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5. Conclusiones
5.1. 5.2. Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Trabajos Futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

167
167 168

Bibliografa A. Instalacin del Software y el Cdigo Fuente


A.1. Instalacin del Software de Pruebas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.2. Cdigo Fuente y Sitio Web del Proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . . .

171 175
175 176

Captulo 1

Introduccin
En este captulo comenzaremos a denir el problema que vamos resolver en esta tesis. Las siguientes secciones tratarn la motivacin, contribucin, el plan de tesis y las convenciones que emplearemos a lo largo de este trabajo.

1.1.

Motivacin

Para explicar la motivacin de esta tesis, es necesario repasar algunos conceptos bsicos de Recuperacin de Informacin (en adelante tambin Information Retrieval o simplemente IR ) y Modelos de Dominio (en adelante tambin Domain Model ). Las prximas subsecciones repasan brevemente deniciones generales y conceptos necesarios para denir el problema a resolver (motivacin), el cual llamaremos el problema del Domain Model Search.

1.1.1. Information Retrieval


Como primer paso creemos conveniente denir qu es Information Retrieval. Dependiendo del autor que tomemos, existen diferentes deniciones de IR. Veamos algunas de stas:

 IR trata acerca de la representacin, almacenamiento, organizacin y acceso a items de informacin (Baeza-Yates et al., 1999).  Information retrieval (IR) consiste en encontrar material (usualmente documentos) de naturaleza des estructurada (usualmente texto) que satisfaga una necesidad de informacin sobre grandes colecciones de documentos (usualmente almacenada en computadoras) (Manning et al., 2008).

El objetivo de un sistema de IR es encontrar informacin que pueda ser relevante para la consulta realizada por el usuario (Baeza-Yates et al., 1999). Estas consultas son una representacin de la necesidad de informacin del usuario e ingresan al sistema mediante texto libre (eventualmente pueden existir operadores lgicos y otros complementos, pero normalmente se trata de texto libre). Ejemplos de sistemas de IR:

Library Book Search: www.nypl.org (New York Public Library) Web Search: www.google.com (Google Search), www.yahoo.com (Yahoo! Search) Online Store Product Search: www.ebay.com (eBay) , www.shopping.com (Shopping.com) Social Network Search: www.linkedin.com (Linked-In Contact Network), www.facebook.com (Facebook Social Network)

CAPTULO 1.

INTRODUCCIN

1.1.2. Modelos de Dominio


De la misma forma que hicimos con IR, vamos a comenzar dando una denicin de modelo de dominio o

domain model :

Domain Model

 es un modelo de objetos que incorpora comportamiento y datos (Fowler, 2002).

Esta denicin, adems de ser algo escueta, es perfectible. Por esto vamos a replantearla pensando a los modelos de dominio de la siguiente forma:

Domain Model

un diseo de objetos que representa un dominio de problema de la realidad.

Este nuevo enfoque nos permite ver a los objetos no slo como datos y comportamiento sino como verdaderos modelos de entes de un dominio de problema. Para terminar de comprender esto hay que explicar a qu nos referimos con realidad y dominio de problema: La realidad comprende cualquier tipo de idea que podamos concebir, por ejemplo: un objeto concreto, la nada, las relaciones de amistad y enemistad, etc. Un dominio de problema es una porcin de la realidad en la cual sus entes estn relacionados entre si. Ejemplos de dominios de problema podran ser las cuentas bancarias, un lesystem o la sincronizacin entre procesos. Los domain models no son un concepto nuevo en el diseo de software orientado a objetos, sino que implementan premisas bsicas de este paradigma: dentro de un dominio particular se efecta un anlisis segn el cual se modelan entes de negocio junto a sus responsabilidades, protocolo y colaboraciones. En un domain model encontraremos objetos como productos, personas, pagos, pginas web, etc. Volviendo a la perspectiva de Fowler, ste propone al domain model como un patrn de arquitectura (ver subseccin 2.2.1), el cual, dependiendo del sistema particular, puede o no ser el ms adecuado para implementar dicho sistema (Fowler, 2002). En esta tesis nos ocuparemos principalmente de aplicaciones que modelan sus entidades en modelos de dominio.

1.1.3. El problema del Domain Model Search


Introduccin
Cuando se desarrolla un sistema orientado a objetos, las metodologas de anlisis y diseo aportan un buen grado de certidumbre acerca de qu entidades se van a modelar y qu operaciones van a realizar. Sin embargo, ya sea por omisin a la hora de hacer el anlisis o porque se considera innecesario, inadecuado o fuera de alcance, no solemos contemplar la necesidad de acceder a los datos de manera desestructurada utilizando el lenguaje natural. Veamos algunos ejemplos:

Ejemplo 1.1.1.
SQL.

Para una aplicacin que administra una librera, construimos un modelo del negocio

con las entidades: libros, autores y sucursales. Suponiendo que este sistema almacena sus datos en una base de datos relacional (RDBMS), denimos formularios que ejecutan consultas predenidas en lenguaje

Si quisiramos responder la pregunta Qu libros de ciencia ccin hay en la sucursal San Martn?, deberamos implementar un formulario que ejecute una consulta como la siguiente:

SELECT FROM
BOOK_TITLE

WHERE

BOOKS B ,

BOOK_STORE_MAP BSM,

STORES

S . LOCATION =

AND

' SAN MARTN '

AND

B . GENRE =

' CIENCIA

FICCIN '

AND

BSM . STORE_ID = S . STORE_ID

BSM . BOOK_ID = B . BOOK_ID

Los inconvenientes ms claros al resolver el problema de esta forma son: Es poco exible ya que las consultas deben ser previstas durante el anlisis.

1.1.

MOTIVACIN

No se extiende automticamente a buscar elementos en diferentes esquemas. Esto es, es capaz de buscar libros o autores que cumplen con un criterio, pero si luego agregamos el esquema msica, no incluye automticamente al nuevo esquema. Se depende del RDBMS particular para contar con herramientas que permitan procesar textos. El lenguaje SQL no est diseado para aplicar procesos que faciliten la coincidencia entre los trminos de bsqueda y de indexacin (elementos sobre los que uno busca). Si vamos a desarrollar estos procedimientos, normalmente se deben implementar en un lenguaje procedural propietario (ejemplo: PL/SQL). Las bsquedas recaen enteramente sobre la base de datos, de manera que para soportar volumen de bsquedas, se debe contar con un RDBMS de gran escala.

En este ejemplo anterior comenzamos a ver que un RDBMS no se adecua al tipo de consultas que estamos queriendo resolver. Veamos otros ejemplos de sistemas donde tenemos requisitos de procesamiento de lenguaje natural y un RDBMS no se ajusta a la solucin:

Ejemplo 1.1.2

(Consultas a Sistema de Bibliotecas)

A continuacin analizamos dos ejemplos de

consultas en lenguaje natural a un sistema bibliotecario:

1. Consulta:  libros sobre information retrieval publicados desde 1999


a) Libros debe reconocerse como una entidad, no es un tpico. Ver que si la biblioteca no cuenta

con libros, podra sugerir revistas.


b) Information retrieval se debe reconocer como un tpico. En caso de no tener sucientes libros

del tema podramos ofrecer resultados que traten acerca de search engines o procesamiento
del lenguaje natural.

2. Consulta:  traducciones de Macbeth al espaol La lgica a aplicar debe reconocer que:


a) Macbeth es una obra y no un autor, b) entre todas las obras, buscamos slo las del espaol.

Nuevamente, el ejemplo nos muestra que la lgica estndar de una base de datos no es la ms adecuada ya que la mejor respuesta requiere un anlisis semntico de la consulta.

Otros ejemplos de sistemas donde podramos efectuar consultas en lenguaje natural:

Sitio Web de Comercio Electrnico: 1. Consulta:  stereo 2. Consulta:  alarmas vehiculares 3. Consulta:  guitarras en capital Sistema Universitario: 1. Consulta:  certicacin de normas tcnicas 2. Consulta:  olimpiadas

En todos estos casos vemos que las preguntas son consistentes dentro del contexto que maneja el usuario que realiza las mismas, pero no necesariamente estarn contempladas por el anlisis inicial del sistema. Adems, estas consultas presentan un cierto grado de ambigedad que las vuelve difciles de resolver con el mismo lenguaje SQL que utilizamos para recuperar objetos y generar reportes.

CAPTULO 1.

INTRODUCCIN

Herramientas Actuales
En las ltimas dcadas han surgido herramientas de IR que nos permiten utilizar el lenguaje natural para encontrar informacin til entre vastas colecciones de documentos, libros, audio o video. Algunos ejemplos de esto son los buscadores web como (Google, 2009b ; Yahoo, 2009). Estas herramientas de IR transforman nuestras expresiones del lenguaje natural en items de informacin (enlaces a pginas web). Adems de las los buscadores web, existen herramientas maduras que permiten hacer IR sobre documentos de texto y estn emergiendo las que permiten hacerlo sobre los objetos de nuestras aplicaciones. Dentro de las primeras, la ms popular es Apache Lucene (Apache, 2009b ). Entre las segundas debemos destacar Hibernate Search (Hibernate, 2009b ) y Compass Project (Compass Project, 2009). El objetivo de Lucene es indexar y recuperar documentos de forma eciente y exible. Sin embargo, Lucene no es una herramienta adecuada para indexar objetos de un modelo de dominio. Adelantndonos al anlisis del problema, podemos sealar las deciencias que encontraron los autores de Compass al intentar utilizar Lucene como herramienta de IR sobre objetos: Es relativamente difcil de integrar, Sus APIs son de bajo nivel, No es transaccional, No soporta bsquedas sobre todos los campos de un documento, No indexa directamente datos de un RDBMS, Las actualizaciones de documentos son difciles de implementar A esto agregamos las crticas de los autores de Hibernate Search, quienes plantean que Lucene produce desajustes en el paradigma: Desajuste de Sincronizacin (Synchronization Mismatch ): con Lucene somos responsables de mantener sincronizado el almacn de objetos (tpicamente un RDBMS) y los ndices de Lucene. Desajuste Estructural (Structural Mismatch ): debemos resolver el problema de efectuar un mapeo de objetos a documentos de texto. Desajuste de Recuperacin (Retrieval Mismatch ): al recuperar informacin, Lucene no devuelve directamente nuestros objetos de dominio sino objetos genricos de Lucene. Estos son problemas que veremos en detalle a lo largo de esta tesis y que hacen que libreras como Apache Lucene no sean adecuadas para indexar objetos. En en esta tesis tambin vamos a analizar herramientas como Compass y Hibernate Search, las cuales fueron pensadas para indexar y recuperar objetos y sobre las cuales tambin implementaremos mejoras. Teniendo un panorama de las herramientas actuales y del problema que queremos resolver, en la prxima subseccin explicaremos el objetivo de esta tesis.

1.1.4. Objetivo
El objetivo de esta tesis se puede enunciar de la siguiente forma:

Objetivo

en esta Tesis se busca resolver el problema de aplicar las tcnicas de IR para encontrar infor-

macin almacenada en los objetos de los modelos de dominio. Para esto es necesario determinar las actividades y componentes de un motor de bsqueda sobre objetos del dominio y las alternativas de implementacin de cada una de ellas. El objetivo implica resolver el problema planteado de forma general, esto es, permitiendo indexar objetos provenientes de cualquier modelo de dominio. En las prximas subsecciones se trata cmo contribuye esta Tesis a la solucin del problema as como explicamos su plan de desarrollo.

1.2.

CONTRIBUCIN DE LA TESIS

1.2.

Contribucin de la Tesis

Enunciemos el aporte que hace este trabajo al entendimiento del campo del conocimiento: Esta tesis contribuye en:

la denicin acerca de cules son los componentes principales de un motor de bsqueda sobre objetos, sus alternativas de implementacin y las consecuencias de distintas variantes de diseo, la implementacin de una solucin concreta al problema de IR sobre informacin contenida en objetos, escogiendo las alternativas de implementacin ms adecuadas.

Para probar la adecuacin de la solucin al problema, se implementa una pieza de software que acta como un framework de recuperacin de informacin sobre objetos, tres aplicaciones de referencia sobre las que validar el framework y un conjunto de pruebas cuantitativas y cualitativas que lo contrastan con las soluciones previas. Este framework reeja las mejores prcticas, criterios y premisas defendidas a lo largo de los prximos captulos en base al estudio del problema y el anlisis de las soluciones actuales.

1.3.

Plan de Tesis

En esta seccin vamos a organizar el resto de la tesis, describiendo la funcin que cumplen los prximos captulos: El segundo captulo describe el estado del arte. Este captulo tiene un objetivo mixto. La primera parte incluye el soporte tecnolgico y cientco necesario en materia de IR, diseo orientado a objetos y persistencia. El objetivo de esta primera parte es sentar las bases sobre la cual analizar los componentes del problema, sus soluciones actuales y nuestra propuesta. En la segunda parte del captulo tomamos como casos de estudio para su anlisis en profundidad las tres herramientas ms importantes de la actualidad. Dicho anlisis producir el aprendizaje necesario para que nuestra propuesta incorpore los aciertos y evite los desaciertos de otras herramientas. El tercer captulo trata la propuesta de solucin y su implementacin. Con las bases tericas adquiridas en los captulos previos, se analiza en profundidad cada uno de los aspectos intervinientes en el problema, las alternativas de solucin y la justicacin de cada una de las elecciones. Por ltimo, se presenta un diseo detallado de la solucin y, donde corresponda la comparacin, se contrastan los casos de estudio con la solucin diseada. El cuarto captulo trata acerca de la experimentacin. El primer objetivo de este captulo es validar la solucin diseada en situaciones reales de aplicacin. El segundo objetivo es establecer un anlisis comparativo de resultados entre nuestra solucin y las alternativas actuales, tanto en trminos cualitativos como cuantitativos. Finalmente, el quinto captulo concluye la tesis con las conclusiones. Las conclusiones hacen una retrospectiva de la tesis y ponen en blanco sobre negro los avances logrados as como el avance sobre la solucin del problema. Como cierre de este trabajo planteamos las futuras lineas de investigacin.

1.4.

Algunas convenciones adoptadas

En el desarrollo de esta Tesis vamos a seguir consistentemente estas convenciones:

Referencias Cruzadas: la tesis est dividida en captulos, secciones, subsecciones y apartados. Las referencias cruzadas que haremos a lo largo de este trabajo indicarn el nivel jerrquico del contenido referenciado utilizando estos cuatro niveles. Todas las referencias cruzadas a secciones, ejemplos y guras se indican entre parntesis. Referencias Bibliogrcas: las referencias se indican entre parntesis, utilizando el autor y el ao de la publicacin. Cuando exista ms de una publicacin del autor en el mismo ao, se agregar una letra al nal del ao, tal de desambiguar la referencia en la seccin de bibliografa.

CAPTULO 1.

INTRODUCCIN

Numeracin de Ejemplos: los ejemplos estn numerados secuencialmente de manera interna a la seccin a la que pertenecen. Esto quiere decir que si tenemos cinco ejemplos en el captulo 1 con tres en la seccin 1.1 y dos en la seccin 1.2, la numeracin ser: 1.1.1, 1.1.2, 1.1.3, 1.2.1, 1.2.2 . Cuando expresemos algoritmos, hagamos referencia a un identicador de un lenguaje de programacin, referenciemos clases o expresemos una frase literal utilizaremos la familia tipogrca Sans Serif.

Al nal de este trabajo se incluye tambin un ndice alfabtico de palabras clave.

Para nalizar este captulo introductorio, queremos sealar que previo al desarrollo de esta tesis el autor public un artculo introductorio al problema. Dicho artculo se puede encontrar en la seccin de bibliografa bajo la clave (Klas, 2009).

Captulo 2

Estado del Arte


En este captulo se presentan los conceptos, herramientas y tecnologas necesarias para construir un motor

de bsqueda sobre objetos.


El objetivo de este captulo es plantear el estado del arte en cada uno de los componentes del problema y efectuar un anlisis comparativo entre las herramientas actuales. En la seccin 2.1 presentamos los conceptos y tcnicas utilizadas actualmente en los sistemas de IR. Estas tcnicas sern referenciadas al analizar los casos de estudio as como en el captulo 3 para elegir la mejor alternativa de implementacin para el motor de bsqueda. En la seccin 2.2 introducimos conceptos de diseo de software como: modelo de dominio, framework,

librera, patrones de diseo y de arquitectura, inversin del control e inyeccin de dependencias. Estos
conceptos sern fundamentales para analizar los casos de estudio y disear el motor de bsqueda sobre objetos del captulo 3. En la seccin 2.3 explicamos las tcnicas de persistencia de objetos, las cuales veremos que interactan con los motores de bsqueda sobre objetos e impactan sobre sus diseos. Finalmente, en la seccin 2.4 nos apoyamos en lo visto durante todo el captulo para analizar las herramientas ms importantes de IR sobre texto y objetos. Este anlisis abre la discusin acerca de cmo implementar la solucin al problema planteado, la cual nalmente se desarrollar en el captulo 3. El anlisis de los casos de estudio permitir que nuestra propuesta de motor de bsqueda sobre objetos adopte sus mejores prcticas y evite que repitamos sus errores.

2.1.

Information Retrieval

En esta seccin presentamos los conceptos y tcnicas utilizadas actualmente en los sistemas de IR. Comenzaremos proponiendo una clasicacin para los sistemas de IR (subseccin 2.1.1), para luego presentar los conceptos bsicos de cualquier sistema de IR (subseccin 2.1.2) y las mtricas que determinan su xito en trminos de relevancia (subseccin 2.1.3). El centro de atencin de esta seccin estar en presentar los modelos de IR (subseccin 2.1.4) y las tcnicas que vuelven a los sistemas de IR efectivos y ecientes (subsecciones 2.1.5 y 2.1.6).

2.1.1. Clasicacin de los Sistemas de IR


Como introduccin a los conceptos de Information Retrieval es conveniente realizar una clasicacin

funcional de las herramientas de IR.


Algunos ejemplos de distintos tipos de herramientas de information retrieval:

Para usuarios nales, de uso publico: 7

CAPTULO 2.

ESTADO DEL ARTE

Web Search: pginas web, documentos de ocina, imgenes, etc. Ejemplo: Google Web Search , Yahoo Web Search. Product Search: bienes de uso y consumo en mercados virtuales. Ejemplo: e-Bay, Shopping.com, MercadoLibre. Scientic Publications: sobre publicaciones acadmicas y revistas. Ejemplo: ACM Digital Library, IEEExplore. Legal: acerca de leyes y casos judiciales. Ejemplo: LexisNexis (Lexis Nexis Research, 2009).

Para usuarios nales, de uso privado:

Enterprise Search: sobre pginas web en Internet e intranets, e-mails y documentos en un repositorio corporativo. Ejemplo: Oracle Enterprise Search (Oracle, 2009b ), Google Search Appliance (Google, 2009a ).

Personal Search: sobre contenido en una computadora personal. Ejemplo: Google Desktop, Windows Search.

Para uso en desarrollo de software:

Text Retrieval: framework de indexacin de texto para aplicaciones. Ejemplo: Apache Lucene (Apache, 2009b ) (ver subseccin 2.4.1). Object Search: framework de indexacin de objetos. Es el tipo de framework que analizamos en este trabajo. Ejemplo: Hibernate Search, Compass Project (ver subsecciones 2.4.2 y 2.4.3).

La herramienta que construiremos como solucin al problema propuesto entra en la categora de herramientas para uso en desarrollo de software, ms precisamente en Object Search. En la prxima subseccin vamos a introducir los conceptos bsicos que son comunes a todos estos sistemas.

2.1.2. Deniciones Generales


En esta seccin denimos los conceptos bsicos de IR. Como primer paso, repasemos la segunda de las deniciones de IR que vimos en la subseccin (1.1.1):

Information Retrieval

consiste en encontrar material (usualmente documentos) de naturaleza deses-

tructurada (usualmente texto) que satisfaga una necesidad de informacin sobre grandes colecciones de documentos (usualmente almacenada en computadoras) (Manning et al., 2008).

Esta denicin de Manning est sesgada hacia la indexacin y recuperacin de texto como artculos, libros, etc). Este sesgo responde a los usos clsicos que se les han dado a los sistemas de IR, los cuales tuvieron sus inicios indexando publicaciones cientcas y registros bibliotecarios (Manning et al., 2008). Con cierto sesgo hacia se contexto se denieron entidades y conceptos bsicos como: documento, corpus

y lxico. A continuacin presentamos sus deniciones:

Documentos

son las unidades hacia las que se construye el sistema de IR.

Estructuralmente, los documentos pueden ser de naturaleza homognea o heterognea. Por ejemplo, un sistema orientado a documentos homogneos podra ser un sistema de IR sobre cheros de biblioteca (en este caso los documentos son cheros estructuralmente idnticos). Para el caso heterogneo podemos tomar como referencia al buscador web Google (Google, 2009b ), el cual indexa pginas web, documentos PDF, presentaciones PowerPoint y muchos otros formatos heterogneos. En el problema del Domain Model Search, los documentos son los objetos del dominio de problema, los cuales pueden ser tanto homogneos (objetos de una misma clase) como heterogneos (objetos de distintas clases).

Corpus

es el conjunto de documentos recuperables en el sistema.

2.1.

INFORMATION RETRIEV AL

El corpus se puede caracterizar segn varios criterios, los cuales dependen de la naturaleza del sistema. Un corpus puede ser: Esttico vs. Dinmico: en base a si el contenido de sus documentos cambia o permanece inmutable en el tiempo. Interno vs. Externo: dependiendo si el almacenamiento de los documentos est controlado por el sistema o fuera de su control. Un ejemplo de corpus esttico e interno puede ser el sistema bibliotecario de registro de cheros. Este corpus es esttico porque las chas no cambian en el tiempo e interno porque estn en poder exclusivo del sistema bibliotecario. Un ejemplo de corpus dinmico y externo son las pginas de Internet, cuyo contenido vara en el tiempo sin el control de los sistemas que las indexan. En nuestro problema de IR sobre objetos, el corpus son los objetos persistentes del sistema. Este corpus es interno (normalmente el sistema controla los objetos de su modelo de dominio) y puede ser tanto dinmico como esttico.

Lxico

es el conjunto de trminos presentes en el corpus.

A los nes prcticos, esta denicin deja algunos problemas dependientes de la manera en la cual interpretamos el contenido de los documentos. Por ejemplo el lxico de un corpus de un nico documento

D = procedimiento

ad-hoc puede ser

L = {procedimiento,

ad-hoc}

L = {procedimiento,

ad, hoc}. A

los efectos de nuestro problema, tomamos la denicin de (Manning et al., 2008), la cual dene al lxico en base a los trminos que poblarn el ndice invertido (ver subseccin 2.1.5). Al presentar la denicin de IR mencionamos el concepto de indexacin, el cual podemos denir como:

Indexacin

es el proceso que incorpora los documentos al corpus y actualiza los ndices.

Esta denicin introduce un nuevo trmino: el ndice. Los ndices son estructuras de datos que tienen por objetivo recuperar ecientemente entidades que cumplen con cierto criterio de ltrado u ordenamiento. En la subseccin (2.1.5) estudiaremos los ndices utilizados en sistemas de IR.

2.1.3. Mtricas
Las mtricas en IR son medidas cuyo objetivo es mensurar la percepcin de "xito" del sistema de IR frente a una consulta. Presentemos dos medidas bsicas de IR (Baeza-Yates et al., 1999; Manning et al., 2008):

Recall

es la fraccin de documentos relevantes que ha sido recuperada del total de documentos recuper-

ables.

Precisin

es la fraccin de objetos recuperados que es relevante.

Figura 2.1: Precisin y Recall. Las relaciones entre las cardinalidades de los conjuntos nos dan mtricas de xito del sistema.

10

CAPTULO 2.

ESTADO DEL ARTE

Estas relaciones las podemos visualizar grcamente en el diagrama de Venn presentado en la gura (2.1):

Recall =

|RR| |DR| |RR| |R|

(2.1.1)

P recisin = o

(2.1.2)

Las ecuaciones (2.1.1) y (2.1.2) se pueden ver en una tabla de contingencia:

DR R R
verdadero positivo (vp) falso negativo (f n)

DR
falsos positivos (f p) verdadero negativo (vn)

Cuadro 2.1: Tabla de contingencia para documentos relevantes y recuperados.

ahora redenimos las dos medidas en base a esta tabla:

Recall =

vp (vp + f p) vp (vp + f n)

(2.1.3)

P recision =

(2.1.4)

A continuacin profundizamos los conceptos de recall y precisin con un ejemplo:

Ejemplo 2.1.1.
con

Dado un sistema de IR con un corpus

amos que para una query puntual

q,

el conjunto

C = {di } donde di son sus documentos, supongcontiene 50 documentos relevantes. En base a sus

algoritmos y parmetros, el sistema puede encontrar un conjunto variable de resultados

100,

R = {di }i 0,j los cuales estn ordenados segn la relevancia asignada por el sistema. Para este orden RR = {d1 , d5 , d8 , d12 , d30 , d40 , d59 , d80 }.
de resultados en

asignado, los resultados relevantes son A medida que ampliamos la cantidad esta tabla: Nmero de Resultados(|Rj |) 10 20 30 40 50 60 70 80 90 100

R,

obtenemos curvas de precisin y recall segn

Documentos Relevantes 3 4 5 6 6 7 7 8 8 8

(|RRj |)

Recall

|RRj | |DR|=50

Precisin

|RRj | |Rj | %

6% 8% 10 % 10 % 10 % 14 % 14 % 16 % 16 % 16 %

30 % 20 % 17 % 15 % 12 % 12 % 10 % 10 % 9% 8%

Si gracamos precisin en funcin del recall para segmentos de recall de 1 % de amplitud obtenemos el grco (2.2):

2.1.

INFORMATION RETRIEV AL

11

Figura 2.2:

P recisin(recall) o

. La curva muestra cmo vara la precisin a medida que aumentamos la

cantidad de resultados retornados.

El ejemplo (2.1.1) puso de maniesto una caracterstica de los sistemas de IR: la solucin de compromiso entre encontrar documentos relevantes (recall ) y que stos sean una cantidad signicativa del total de resultados (precisin ). En general estas dos medidas estn relacionadas de manera inversa, es decir, cuando una crece la otra tiene a decrecer. Segn necesitemos favorecer el recall o la precisin, esta relacin inversa nos obligar a tomar decisiones de diseo en cada sistema de IR a construir. Por ejemplo, en un buscador web el objetivo es obtener pginas relevantes entre los primeros 10 resultados a costa de producir falsos negativos (favorece precisin), mientras que en un sistema legal es ms importante abarcar todos los casos que retornar slo verdaderos positivos (favorece recall). Vemos entonces que el balance ptimo entre precisin y el recall es una solucin de compromiso determinada por las caractersticas del problema que resuelve la herramienta de IR (Manning et al., 2008). Una forma de cuanticar la relevancia en un sistema de IR es otorgarle a los documentos una calicacin de relevancia (ranking ) respecto de la bsqueda. Este ranking podra ser un valor real este ranking, podemos denir un nivel

r [0, 1]. Utilizando

a partir del cual:

di RR rdi
Donde

di

es un documento particular y

rdi

su ranking para una query dada.

Notemos que cuando el parmetro si

= 0 RR = DR,

lo que implica un recall del 100 %). En el otro extremo, si

0, estamos favoreciendo el recall por sobre la precisin (en el lmite, 1 tendremos bajo

recall y posiblemente mejoremos la precisin (asumiendo que en general logramos posicionar resultados relevantes entre los primeros lugares del ranking). Continuemos presentando las mtricas de IR con dos medidas adicionales, accuracy y F-measure :

Accuracy

1 Esta medida se dene utilizando los valores de la tabla (2.1):

Accuracy =

tp + tn tp + f p + f n + tn DR
y

Asumiendo la herramienta de IR como un clasicador binario de documentos en las clases (recordemos que la herramienta intenta obtener

DR

R = RR = DR),

es plausible utilizar esta mtrica, la

cual es adecuada para evaluar sistemas de clasicacin automtica. La razn por la que normalmente descartaremos esta medida es porque al estar los datos fuertemente desviados hacia la categora podemos conseguir alto accuracy clasicando todos los documentos como

DR, DR, lo que producira de todos

modos un sistema malo, ya que el usuario preere que retornemos algn documento antes que ninguno. Es decir, los usuarios suelen tolerar algunos falsos positivos en favor de conseguir algunos verdaderos positivos (Manning et al., 2008).

1 En

espaol el trmino reere a cuan "correcto" es el criterio de seleccin de documentos.

12

CAPTULO 2.

ESTADO DEL ARTE

F-measure

se utiliza para establecer una solucin de compromiso entre recall y precisin. La medida F

es la media armnica ponderada de la precisin y el recall:

F =
Donde (

1 P

2 + 1 P R 1 1 = 2P + R + (1 ) R = 1 2 >1

1 y [0, 1]. Para hacer una ponderacin equivalente de precisin y recall tomamos 1). Si quisiramos darle mayor importancia a la precisin utilizaramos < 1 mientras que

prioriza el recall.

Ejemplo 2.1.2.

Para ver por qu la F-measure utiliza la media armnica por sobre la aritmtica veamos

que: recuperando el 100 % de los documentos obtenemos como mnimo un 50 % de media aritmtica por ms que hayamos recuperado 1 documento relevante sobre 10.000 recuperados. Por el contrario, si aplicamos la media armnica obtenemos:

F =

1 1 10000 1 1 1 10000 + 1

= 0,00019 0,02 %

Con este pequeo ejemplo se ve como la media armnica (la cual es siempre menor o igual a la aritmtica) es una mejor medida para la efectividad de un sistema de IR. En esta subseccin hemos presentado las medidas bsicas que nos permiten evaluar en trminos cuantitativos las decisiones que tomamos al disear un sistema de IR. En la prxima subseccin presentaremos distintos modelos de IR, cuya efectividad se mide en trminos de estas mtricas.

2.1.4. Modelos de Information Retrieval


Introduccin
Para explicar qu es un modelo de Information Retrieval podemos utilizar una analoga: Normalmente los fenmenos fsicos se analizan mediante un modelo de la realidad. Este modelo establece suposiciones e idealizaciones que permiten utilizar deducciones para resolver una versin simplicada del problema real. En el campo de las ciencias de la computacin el panorama es muy similar: los problemas de Information Retrieval tambin se resuelven planteando suposiciones e idealizaciones que nos permiten simplicar la complejidad del problema subyacente. Estas suposiciones e idealizaciones forman parte de modelos de

Information Retrieval.
Otro enfoque es el planteado por (Baeza-Yates et al., 1999): el factor central de un sistema de IR es la determinacin de cules son los documentos relevantes para una query. La decisin acerca de la relevancia de los documentos suele estar dada por algoritmos de puntuacin (los mejor puntuados sern los ms relevantes). A su vez, estos algoritmos de puntuacin operan de acuerdo a premisas bsicas respecto de la nocin de relevancia de documentos. sas premisas son las que producen distintos modelos de IR. Dentro de un sistema de IR, quien determina qu es relevante es el modelo de information retrieval. Como se desprende de los prrafos previos (especialmente del segundo enfoque), la decisin de qu modelo de IR utilizar es central al sistema. Esta decisin tiene fuertes implicancias en la indexacin, recuperacin y valoracin de los documentos y determinar buena parte del xito del sistema. En esta subseccin nos dedicamos a formalizar y conocer los modelos ms populares de IR para luego poder analizar cmo se implementan en los casos de estudio y proponer una implementacin para nuestro motor de bsqueda sobre objetos.

Formalizacin
Es posible establecer una formalizacin matemtica acerca de qu es un modelo de IR. La siguiente denicin pertenece a (Baeza-Yates et al., 1999):

Denicin 2.1.1.

Un modelo de Information Retrieval es una 4-upla

[D, Q, F, R (qi , dj )]

donde:

2.1.

INFORMATION RETRIEV AL

13

D Q F

es un conjunto de representaciones de documentos en la coleccin. es un conjunto de representaciones de las necesidades de informacin del usuario llamadas

queries. es un marco de trabajo (framework) para modelar representaciones de documentos, queries y sus

relaciones.

R(qi , dj )
reales.

es una funcin de puntaje

2 con dominio en el conjunto

QD

e imagen en los nmeros

Esta denicin permite unicar los modelos clsicos de IR bajo un mismo marco formal (para mayor detalle se puede consultar Baeza-Yates et al., 1999, p. 24). A continuacin vamos a tratar los llamados modelos clsicos de IR: booleano, vectorial y probabilstico.

Modelo Booleano
El modelo booleano est basado en operaciones de conjuntos entre trminos de la query y los documentos. Las expresiones de bsqueda se convierten en una expresin booleana de trminos (palabras) y operadores AND, OR y NOT. La semntica de estos operadores lgicos se traduce en la expresin debe estar presente en el documento, puede estar presente no debe estar presente. A continuacin veremos un ejemplo de una query en el sistema booleano.

Ejemplo 2.1.3 (Especicacin booleana de consultas).


informacin y consultas booleanas para satisfacerlas.

A continuacin vemos necesidades concretas de

Necesidad de informacin: documentos acerca del emperador Julio Caesar

query = julio AN D caesar


Necesidad de informacin: documentos acerca de Julio Caesar o Brutus

query = (julio AN D caesar) OR brutus


Necesidad de informacin: documentos acerca del emperador Julio Caesar donde no se mencione a Brutus

query = (julio AN D caesar) AN D N OT (brutus)


El modelo booleano clasica los documentos como totalmente relevantes o totalmente irrelevantes segn cumplan con la condicin booleana impuesta en la query. El modelo no incorpora intrnsecamente una medida de relevancia o similitud entre queries y documentos. La nica medida intrnseca es la dicotmica: relevante vs. no relevante. Si bien este modelo ha sido y sigue siendo ampliamente utilizado, estos factores son una de las crticas principales hacia l (Baeza-Yates et al., 1999; Manning et al., 2008).

Denicin 2.1.2.
dj
como:

Para el modelo booleano podemos denir la similitud entre una query

y un documento

Similitud(q, dj ) =

1 0

q se cumple en dj q no se cumple en dj

A continuacin presentamos algunos ejemplos de consultas en el modelo booleano.

Ejemplo 2.1.4.
s y slo si

En este ejemplo resolvemos algunas consultas donde el documento se presenta al usuario

Similitud(q, dj ) = 1. Corpus = {d1 , d2 , d3 }


y la representacin de sus documentos en trminos:

Denimos el conjunto

d1 = {caesar, dictador, romano} d2 = {hijo, caesar, octavianus}


2 El
trmino puntaje se utiliza como equivalente del trmino ranking del ingls.

14

CAPTULO 2.

ESTADO DEL ARTE

d3 = {brutus, conspirador, romano}


Veamos cmo resultaran algunas bsquedas booleanas sobre este corpus:

q1 : brutus {d3 } q2 : caesar AN D brutus {} q3 : brutus OR (hijo AN D caesar) {d2 , d3 } q4 : N OT (brutus) OR (hijo AN D caesar) {d1 , d2 }
Las principales ventajas del modelo booleano son: su simplicidad, el soporte formal por la teora de conjuntos, buen grado de control al especicar la consulta. Las principales desventajas de este modelo nacen de su denicin de similitud: al no contar con nocin de coincidencia parcial, la curva de recall vs. precisin vara bruscamente con la adicin y sustraccin de trminos, necesita tcnicas externas al modelo para ordenar el conjunto de resultados.

El modelo booleano original (el cual utiliza slo AND, NOT y OR) es demasiado limitado para muchas aplicaciones prcticas, por lo cual se ha ido extendiendo para exibilizar la recuperacin. Algunas de estas operaciones extendidas son la bsqueda por proximidad y la utilizacin de comodines (ver subseccin 2.1.5). Estas mejoras en sus capacidades de recuperacin junto a la sensacin de control sobre sus resultados son seguramente los factores que hacen que en la prctica an sea muy utilizado.

Modelo Vectorial
En este apartado exponemos el modelo vectorial propuesto por Gerard Salton (Salton et al., 1975). Entre las limitaciones del modelo booleano, vimos que la ausencia de una funcin de similitud intrnseca al modelo nos impide priorizar gradualmente los documentos en los cuales la query se ve mejor representada. El modelo vectorial resuelve este problema introduciendo la nocin de coincidencia parcial entre queries y documentos. En el modelo vectorial, la funcin de similitud entre una query y un documento permite:

retornar documentos que no contienen todas las palabras de la bsqueda, diferenciar la relevancia de dos documentos que contienen todas las palabras de la bsqueda, calcular la similitud entre documentos.

A continuacin presentamos algunas deniciones necesarias para trabajar en el modelo vectorial (pueden encontrarse mayormente en Baeza-Yates et al., 1999).

Denicin 2.1.3 (Pesos de Relevancia).


dj
denimos:

Sea un lxico de trminos

ki K

, una query

y un documento

wi,q : wi,j :
con

relevancia del trmino relevancia del trmino


+ 0.

ki ki

en la query

q dj

en el documento

Destaquemos dos aspectos de la denicin (2.1.3):

2.1.

INFORMATION RETRIEV AL

15

el modelo vectorial slo permite relevancias

wi,q

wi,j

mayores o iguales a cero,

los trminos documento.

ki

tienen relevancias distintas segn se encuentren en el contexto de la query o del

Enunciemos otra denicin para caracterizar al modelo:

Denicin 2.1.4
mentos, una query

(Representacin Vectorial de Documentos y Queries)

q y un documento dj , (w1,j , w2,j , . . . , wt,j ), donde wi,q y wi,j son en q y dj .

denimos los los respectivos

. Sea un lxico K de t ele = (w , w , . . . , w ) y = vectores q dj 1,q 2,q t,q pesos de relevancia de los trminos ki K

Vemos entonces que en el modelo vectorial las queries y los documentos se representan como vectores en un espacio t-dimensional donde cada componente es la relevancia de cada trmino. Intuitivamente, los documentos que ms se asemejan a una query son los que tienen su vector

dj

ms prximo al vector

q . Esta

correlacin se puede cuanticar utilizando la funcin coseno, la cual otorga un valor nulo para vectores ortogonales (irrelevantes entre s) y un valor unitario para los vectores perfectamente correlacionados (relevantes entre s).

Denicin 2.1.5 (Similitud en el Modelo Vectorial).


documento

Sea un lxico

de

elementos, una query

y un

dj ,

el modelo vectorial dene la similitud entre la query y el documento como:

dj q Similitud (q, dj ) = cos (q, dj ) = = dj q

wi,j wi,q
i=1 t i=1 2 wi,j t j=1 2 wi,q
(2.1.5)

En la denicin (2.1.3) establecimos que vectorial toma valores continuos en el

wa,b + , 0 intervalo [0, 1].

por lo tanto la funcin de similitud del modelo

A diferencia del modelo booleano, el vectorial establece un ranking de grano no que permite ordenar los documentos en forma gradual segn su relevancia. Si bien la funcin de similitud es continua, esto no quita que bien podramos establecer un valor umbral para mostrar nicamente los documentos que cumplen

Similitud(q, dj ) > sumbral .

Es preciso notar que la representacin vectorial no modela el ordenamiento relativo entre trminos dentro de un documento o una query. Esta simplicacin caracteriza al modelo como uno del tipo bag of words (bolsa de palabras).

A continuacin vemos un ejemplo en el que vemos grcamente los vectores y su similitud:

Supongamos un lxico K = {Brutus, Caesar} y dos documentos que contienen dichas 1 4 3 2 palabras con relevancias d1 = 2 ; 5 y d2 = 4 ; 5 . Si efectuamos una query cuyo vector de relevancias 1 4 es q = 3 ; 5 , tenemos un escenario como el de la gura (2.3):

Ejemplo 2.1.5.

16

CAPTULO 2.

ESTADO DEL ARTE

Figura 2.3: Relacin grca entre una query y los documentos en el modelo vectorial.

Grcamente, dado el ngulo que forma cada documento con la query, por simple inspeccin esperamos que

Similitud(q, d1 ) > Similitud(q, d2 ).


2

Efectuando el clculo analtico:

wi,q wi,d1 Similitud q, d1 =


i=1 2 2 wi,q i=1 2 i=1 2 2 wi,d1

1 1 4 4 + 3 2 5 5 2 2 2 4 1 1 + + 3 5 2

4 5

= 0, 9866

wi,q wi,d2 Similitud q, d2 =


i=1 2 2 wi,q i=1 i=1 2 2 wi,d2

1 3 4 2 + 3 4 5 5 2 2 2 1 3 4 + + 3 5 4

2 5

= 0, 7738

A diferencia del modelo booleano, vemos que por ms que los dos documentos contienen ambos trminos, podemos establecer un ranking basado en la relevancia de cada trmino en la query y los documentos.
El modelo vectorial que hemos denido hasta aqu no menciona cmo calcular los pesos de relevancia

wi,q

wi,dj

(de hecho existen muchas frmulas distintas para el clculo de pesos). A continuacin vamos

a denir algunos valores para luego describir una familia de pesos que busca resolver este problema:

Denicin 2.1.6.
c (ki , dj ) c (ki , q) |dj |
y

Dado un documento

dj ,

una query

q,

un lxico

y un trmino

ki K ,

denimos:

: cantidad de apariciones de

ki

en

dj

: cantidad de apariciones de

ki

en

q dj
y la query

|q|

como las longitudes del documento

Nota: si bien las notaciones son similares, es preciso notar que |dj | y |q| no representan las normas eucldeas de un vector sino la cantidad de trminos que encontramos en el texto. Es decir, la longitud del t 2 documento se calcula como |dj | = c (ki , dj ) mientras que la norma es dj = i=1 wi,j . i

Si nos detenemos a analizar la ecuacin (2.1.5) podemos ver que los divisores

dj

cumplen

la funcin de normalizacin por longitud del documento y la query. Dado que en el contexto de una

2.1.

INFORMATION RETRIEV AL

17

bsqueda puntual el valor de

es una constante para todos los documentos, la normalizacin de la

query slo tiene sentido si queremos comparar puntajes entre bsquedas distintas. Por otro lado, el valor de

dj

s es de mayor importancia ya que nos permite diferenciar documentos cuyos valores

c (ki , dj )

son similares pero sus longitudes

|dj |

son muy distintas (es decir, nos ayuda a favorecer los documentos

con concentracin de trminos relevantes). A continuacin presentamos la familia de frmulas TF-IDF (Term Frequency - Inverse Document Frequency), mediante la cual podremos obtener los pesos

wi,j

wi,q : ki
en

Denicin 2.1.7 (Term Frequency).


el documento

Denimos

tfi,dj

como la cantidad de apariciones del trmino

dj :

tfi,dj = c (ki , dj )
El valor de

tfi,dj

(en adelante tambin

tft,d

o simplemente

tf

) nos indica cun importante es un trmino

dentro de un documento

dj .

Esta medida es una heurstica que propone una relacin directa entre la

relevancia de un trmino en un documento y su cantidad de apariciones.

Denicin 2.1.8 (Document Frequency e Inverse Document Frequency).


frequency) de un trmino

Denimos el valor

ki

como el nmero de documentos

dj

que contienen el trmino

dfi ( document ki .

Recprocamente, denimos inverse document frequency como:

idfi = log

N dfi

donde

es el nmero total de documentos en el corpus.

El valor de idfi (en adelante simplemente idf ) se utiliza como heurstica para conocer el poder de discriminacin de un trmino ki . Esto es, si un trmino est presente en muchos documentos, su uso no sirve para discriminarlos (valores bajos de

idf ),

pero si el trmino es muy especco (presente en pocos

documentos) entonces su uso permite discriminar un conjunto de documentos potencialmente relevantes. Utilizando TF-IDF podemos replantear la similitud entre

dj

como:

Similitudtf idf q, dj =
ki q

tfki ,dj idfki

(2.1.6)

Los valores

tf

idf

son ampliamente utilizados para generar frmulas de relevancia. A continuacin

analizaremos variantes de la frmula (2.1.6) que nos permiten controlar mejor sus efectos. La descripcin de estas variantes siguen el desarrollo presente en (Manning et al., 2008).

TF sub lineal
c (ki , d1 ) = 30
y

La denicin (2.1.7) implica que la relevancia de un trmino aumenta linealmente con

la cantidad de veces que ste aparece en un documento. Si tenemos los documentos

d1

d2

; las cuentas

c (ki , d2 ) = 40;

no es intuitivamente lgico que

d2

sea un 25 % ms relevante que

d1 .

Para evitar este problema se plantea una variacin al clculo de

tf :

wfki ,dj =

1 + log tfki ,dj 0

si

tfki ,dj > 0


otro caso

Si reemplazamos

tf

por

wf

en la frmula (2.1.6), obtenemos una nueva frmula de similitud menos

sensible a la repeticin de trminos.

18

CAPTULO 2.

ESTADO DEL ARTE

Normalizacin de TF por Mximos


trminos.

En el prrafo anterior vimos cmo podramos utilizar

wf

para

evitar que la repeticin de trminos produzca serios desajustes en

tf .

Sin embargo,

wf

es una medida

local a cada trmino que no tiene en cuenta la longitud del documento ni la frecuencia del resto de los

Buscando resolver estos problemas denimos una nueva medida:

ntfki ,dj = a + (1 a)

tfki ,dj tfmax(dj )

En este caso introdujimos una variable (por ejemplo de 1 a 2). El valor de

a [0, 1], la cual suaviza el impacto en transiciones leves de tfki ,dj

se ajusta tpicamente en 0,4 (Manning et al., 2008).

La idea de este mtodo es notar que los documentos largos tienen tendencia a repetir los trminos, por lo que deberamos normalizar los valores respecto del trmino con ms apariciones. Este mtodo tiene los siguientes inconvenientes:

cambios en la lista de stop words (ver subseccin 2.1.5) impactan bruscamente en los valores de

ntf ,
un documento puede contener un trmino inusualmente frecuente que no sea representativo del contenido del documento, si un documento tiene una distribucin de frecuencias de trminos uniforme debera ser tratado de forma distinta que uno que acumula frecuencias alrededor de un conjunto de trminos.

Sumado a las caractersticas que enumeramos al comenzar este apartado, a continuacin presentamos algunas ventajas y desventajas del modelo vectorial. Las principales ventajas son (Baeza-Yates et al., 1999):

el esquema de pesos mejora la calidad de la recuperacin respecto del modelo booleano y permite recuperar documentos parcialmente coincidentes con la query, incorpora una funcin de relevancia continua inherente al modelo, permite buscar documentos similares entre s.

Las desventajas del modelo vectorial son:

al igual que el resto de los esquemas clsicos, los trminos del lxico son considerados de manera independiente, es decir no se modelan interdependencias entre trminos (en el prximo apartado ejemplicaremos esto al presentar el modelo de independencia binaria), es ms difcil de mantener que el sistema booleano (requiere que mantengamos datos globales como el nmero de apariciones de los trminos en el corpus).

Si bien el modelo ya tiene veinticinco aos de antigedad, sigue siendo adoptado en muchos sistemas de IR gracias a que da muy buenos resultados con un costo de implementacin aceptable. Es preciso notar que el modelo vectorial no es mutuamente excluyente con el booleano sino que pueden complementarse. En sistemas con corpus extensos, podramos utilizar el modelo booleano para determinar el conjunto de documentos recuperables y luego utilizar el modelo vectorial para ordenarlos y recortarlos segn un umbral. En la subseccin (2.4.1) tomaremos como primer caso de estudio un sistema que utiliza esta estrategia.

2.1.

INFORMATION RETRIEV AL

19

Modelo Probabilstico
El tercer modelo clsico que vamos a mencionar interpreta la relevancia en trminos de probabilidades y es conocido como modelo probabilstico (Robertson y Jones, 1976). Este modelo se tom en cuenta desde principios de la dcada de 1970 por su capacidad de llevar los problemas de IR a un terreno formal rme (Manning et al., 2008). El modelo probabilstico ser presentado brevemente ya que su desarrollo es algo ms extenso que los anteriores y, como veremos ms adelante, no produce resultados muy distantes del modelo vectorial. Persiguiendo esta brevedad seguimos el desarrollo de (Baeza-Yates et al., 1999) el cual es similar al de (Manning et al., 2008) (para ms detalle se sugiere consultar este ltimo o el trabajo original referenciado al principio del apartado). Dentro de los modelos probabilsticos, presentaremos el ms simple conocido como modelo de indepen-

dencia binaria (binary independence model BIM ). Las asunciones del BIM son:
los documentos se representan de forma booleana (esto es, un vector de unos y ceros indicando la presencia/ausencia de un trmino), la ocurrencia de dos trminos distintos es estadsticamente independiente entre s, los trminos que no se encuentran en la query no afectan a los resultados, la relevancia entre documentos es estadsticamente independiente.

Estas simplicaciones son cuestionables ya que existen casos particulares donde fallan. La segunda asuncin es especialmente cuestionada ya que trminos como Hong y Kong New y York estn fuertemente relacionados estadsticamente. Continuando con la presentacin del modelo, asumamos una nocin binaria de relevancia tal que un documento slo puede pertenecer a uno de dos grupos: relevantes no relevantes. Bajo esta asuncin podemos denir una variable aleatoria:

R(d, q) =
Es decir,

1 0

d es relevante para la query q d no es relevante para la query q R(d, q)


simplemente como

R(d, q)

es una variable aleatoria bidiscreta binaria, la cual no es nula slo para los documentos

relevantes para la query. En adelante nos referimos a

R.

Dada una necesidad de informacin puntual, la propuesta del modelo es presentar a los documentos por orden decreciente de probabilidad de relevancia en la siguiente asuncin (Robertson, 1977):

P (R = 1|d, q).

El modelo probabilstico se basa entonces

Principio Probabilstico del Puntaje

3 Si la respuesta de un sistema de IR a cada pedido de un

usuario es una lista de documentos puntuados por orden decreciente de probabilidad de relevancia para quien efectu el pedido, donde las probabilidades se estiman de la forma ms precisa posible en la base de los datos que estaban disponibles al sistema para este propsito, entonces la efectividad general del sistema para este usuario ser la mejor que se pueda obtener en base a sos datos.

Este principio tiene el inconveniente de que no nos da un indicio acerca de cmo calcular esta probabilidad de relevancia, por lo que tenemos que buscar otra medida de similitud (Baeza-Yates et al., 1999). Dada una query

q,

el modelo asigna a cada documento

Odds(dj

relevante para

dj P (dj relevante para q) . q) = P (dj no relevante para q)

una medida de similitud dada por la relacin

Denicin 2.1.9.

Sean:

un conjunto de trminos

q, R
y su complemento

el conjunto de documentos inicialmente relevantes

R,

3 La

versin original del ingls se puede encontrar tanto en (Robertson, 1977) como en (Manning et al., 2008).

20

CAPTULO 2.

ESTADO DEL ARTE

los pesos binarios la probabilidad la probabilidad

wi,j

wi,q

tal que

wi,j [0, 1], wi,q [0, 1] dj dj

(ver denicin 2.1.3),

P R|dj P R|dj

de que un documento de que un documento

sea relevante para la query

q, q,

no sea relevante para la query

entonces el modelo probabilstico dene la similitud del documento

dj

con la query

como:

P R|dj Similitud (dj , q) = P R|dj


Utilizando la regla de Bayes sobre la ecuacin (2.1.7) obtenemos:
(2.1.7)

P dj |R P (R) Similitud (dj , q) = P dj |R P R


donde y

P dj |R
y

se interpreta como la probabilidad de obtener

dj

al azar entre los documentos relevantes

P (R)

como la probabilidad de que un documento tomado al azar sea relevante. Como es de esperar,

P dj |R
Dado que

P R
y

son los respectivos complementos.

P (R)

P R

no varan documento a documento, podemos tomarlos como una constante y

quitarlos de la frmula de similitud obteniendo:

P dj |R Similitud (dj , q) P dj |R
A continuacin utilizamos la asuncin de independencia entre trminos del BIM, lo que nos permite expandir la ecuacin anterior en una productoria trmino a trmino:

Similitud (dj , q) P (ki |R)


g (dj )=1

g (dj )=0

P ki |R P ki |R ki

P (ki |R)

P ki |R

g (dj )=1
donde

g (dj )=0
est presente en un documento

se interpreta como la probabilidad de que el trmino

al azar tomado de presentes.

R

g dj

vale

para los trminos que estn en la query y

para los que no estn

Si tomamos logaritmos y consideramos que como:

P (ki |R) + P ki |R = 1, esta expresin puede ser reformulada

Similitud (dj , q)
i=1

wi,q wi,j log

1 P ki |R P (ki |R) + log 1 P (ki |R) 1 P ki |R

la cual es una expresin clave para el clculo de relevancia en el modelo probabilstico (Baeza-Yates et al., 1999). Dado que inicialmente no conocemos el conjunto y

P ki |R

. Existen diferentes mtodos para computar estos valores, una forma es asumir que (a)

R, para calcular la similitud necesitamos estimar P (ki |R) P (ki |R)

2.1.

INFORMATION RETRIEV AL

21

es constante para todos los trminos del ndice y (b) inferir que la mayora de los documentos sern no relevantes para aproximar

P ki |R

con la estadstica global, lo que se traduce en:

P (ki |R) = 0, 5 ni N ki
y

P ki |R =
donde

ni

es el nmero de documentos que contienen el trmino

el nmero total de documentos

en el corpus. Si bien no queremos profundizar ms en el tema, cabe destacar que existen mejores mtodos para estimar

P (ki |R)

P ki |R

as como existen otros modelos adems del BIM que producen frmulas de similitud

similares a las del modelo vectorial (Manning et al., 2008). Las principales ventajas del modelo probabilstico son:

se basa en un marco terico rme, incorpora una funcin de relevancia continua inherente al modelo.

Las desventajas del modelo probabilstico son:

la necesidad de conjeturar la separacin inicial entre documentos relevantes y no relevantes, para el caso de utilizar el BIM, asunciones como la independencia entre trminos pueden ser poco realistas.

En la prctica ocurre que algunos modelos comienzan siendo vectoriales y luego migran al probabilstico efectuando algunas variaciones en las frmulas de similitud (Manning et al., 2008).

Otros Modelos de IR
Existen muchos otros modelos de IR derivados de los que hemos presentado. Algunos de ellos son: modelo booleano extendido, modelo vectorial generalizado, fuzzy sets, latent semantic indexing (LSI), redes neuronales y bayesianas. Estos modelos pueden reemplazar a los clsicos una vez que estamos convencidos que los primeros no son adecuados para resolver el problema. Adelantndonos a la explicacin de los modelos a elegir para la propuesta (captulo 3), podemos decir que los modelos clsicos proveen una buena base para construir el motor de bsqueda sobre objetos, por lo que preferimos profundizar en tcnicas de matching o priorizacin y no en sosticar los modelos de IR. Respecto de las frmulas de similitud; Fang, Thao y Zai proponen comparar las frmulas de relevancia surgidas de distintos modelos de IR deniendo un conjunto de criterios funcionales a satisfacer (Fang

et al., 2004). Estos criterios o premisas son similares a las que hemos propuesto durante la exposicin
del modelo vectorial al describir TF sub lineal y normalizacin por mximos. Las premisas se formalizan principalmente en trminos de TF, IDF y otras estadsticas para luego evaluar frmulas de relevancia vectoriales y probabilsticas, analizando el grado de cumplimiento de las premisas. Las conclusiones a las que arriban los autores es que cada modelo tiene una parametrizacin ligada a criterios funcionales concretos que determinan un rango de validez para sus parmetros.

2.1.5. Tcnicas de Matching y Acceso a Datos


En las subsecciones previas clasicamos los sistemas de IR y presentamos sus mtricas y modelos ms importantes. En esta subseccin vamos a explicar las distintas tcnicas que nos permiten implementar estos sistemas y modelos de IR.

22

CAPTULO 2.

ESTADO DEL ARTE

ndices Invertidos
Si tuviramos que procesar la query caesar AND brutus del ejemplo (2.1.4), la forma ingenua de hacerlo sera recorrer lnea por lnea todos los documentos del corpus, quedndonos con aquellos que contienen las dos palabras. Esta forma de solucionar el problema equivale a procesar los documentos uno a uno con el comando grep de Unix. Otra solucin similar sera utilizar consultas like de SQL sobre una tabla de un RDBMS, cuyos campos contengan el cuerpo del documento. Si el problema a resolver es pequeo o surge de una consulta ad-hoc que slo necesita ejecutarse una vez, el modelo grep o el like puede ser suciente. Ahora, si queremos recuperar informacin rpidamente en colecciones de millones de documentos, efectuar consultas avanzadas (por ejemplo: Caesar a 5 palabras de distancia de Brutus) y establecer un puntaje para los resultados como en el modelo vectorial, necesitaremos de un ndice invertido (Manning et al., 2008). Un ndice invertido o archivo invertido es una estructura de datos similar a un mapa cuya clave es un trmino y su valor es una lista de identicadores de documentos. Las claves del ndice invertido forman el lxico diccionario mientras que los valores de cada clave son las posting lists. Cada documento de la posting list es un posting. En la gura (2.4) podemos ver la estructura del ndice invertido:

Figura 2.4: Diccionario y Posting Lists. A la izquierda se ven los trminos y a la derecha la lista de documentos coincidentes.

Los ndices invertidos se utilizan principalmente para recuperar y valorizar los documentos de forma eciente. A continuacin presentamos un ejemplo de construccin del ndice invertido:

Ejemplo 2.1.6.

Construyamos un ndice invertido para los documentos del ejemplo (2.1.4). Para con-

struir el ndice necesitamos llevar a cabo estos pasos: 1. Transformar las palabras del documento mapa

dj ki , ki+1 , . . . ,ki+Nj 1

donde

dj en trminos ki pertenecientes al lxico K obteniendo Nj es el nmero de trminos distintos en dj . ki dj , dj+1 , . . . ,dj+Mj 1


donde

un

2. Invertir el mapa obteniendo un nuevo mapa / ndice: nmero de documentos donde aparece el trmino

Mj

es el

ki .

Apliquemos estos pasos sobre los documentos del ejemplo (2.1.4): 1.

(d1 {caesar; dictador; romano} ; d2 {caesar; hijo; octavianus} , d3 {brutus; conspirador; romano})

2. Invertimos las listas:

caesar (d1 , d2 ) dictador (d1 ) romano (d1 , d3 ) hijo (d2 ) octavianus (d2 ) brutus (d3 ) conspirador (d3 )

2.1.

INFORMATION RETRIEV AL

23

Si ahora quisiramos efectuar la consulta sectar y unir listas del ndice:

caesar AND brutus OR conspirador

vemos que basta con inter-

[caesar = (d1 , d2 ) brutus = (d3 )] conspirador = d3

El objetivo del ndice es entonces acelerar la recuperacin de documentos, permitindonos acceder rpidamente a la lista de documentos que contienen un trmino. Dependiendo cmo est implementado el ndice, el costo de acceso a los posting lists vara desde el simple acceso a un archivo hasta tcnicas complejas que involucran compresin, front coding, rboles B, etc. A continuacin presentamos algoritmos para la construccin del ndice y algunas variantes para su implementacin.

Construccin del ndice


Dependiendo de modelo de IR, debemos considerar distintos componentes en la construccin del ndice. Para el modelo booleano nos alcanza con un ndice como el del ejemplo (2.1.6), esto es, un mapa de trminos a documentos. En el modelo booleano, para acelerar la interseccin entre conjuntos, es conveniente construir el ndice ordenando las posting lists por identicador de documento (docID). Si la posting list est ordenada, la interseccin se puede efectuar mediante el siguiente algoritmo:

Algoritmo 2.1 Interseccin de dos posting lists cuando los docID estn ordenados de forma ascendente.
public

L i s t <DocID> listA listB

intersect ( String = new = =

k1 ,

String

k2 )

L i s t <DocID> L i s t <DocID> L i s t <DocID>


int int

results

A r r a y L i s t <DocID >() ;

g e t P o s t i n g L i s t ( k1 ) ; g e t P o s t i n g L i s t ( k2 ) ;

indexA = 0 ; indexB = 0 ; l i s t A . s i z e ( ) && i n d e x B < l i s t B . size () ) {

while ( indexA <

// docID1 == docID2
docID1 = docID2 =

l i s t A . get ( indexA ) ; l i s t B . get ( indexB ) ; {

i f ( docID1 . e q u a l s ( docID2 ) )

r e s u l t s . add ( docID1 . c l o n e ( ) ) ; i n d e x A ++; } } } }


return else

// i d n t i c o a h a c e r docID2 . c l o n e ( ) ;
{

i n d e x B ++;

i f ( docID1 . g r e a t e r T h a n ( docID2 ) )

i n d e x B ++;
else

i n d e x A ++;

results ;

Este algoritmo aprovecha el ordenamiento de las claves para avanzar el puntero sobre la posting list que an puede aportar coincidencias (si una lista se acaba con un docID menor al de la otra lista, la segunda no necesita seguir siendo recorrida) y no requiere recorrer completamente todas las posting lists. Sin embargo, si los documentos no estn ordenados, podramos resolver la interseccin mediante un algoritmo como el siguiente:

24

CAPTULO 2.

ESTADO DEL ARTE

Algoritmo 2.2 Interseccin de dos posting lists cuando estas no estn ordenadas por docID.
L i s t <DocID> intersect ( String results listA listB = = = new k1 , String k2 ) { L i s t <DocID> L i s t <DocID> L i s t <DocID> A r r a y L i s t <DocID >() ;

g e t P o s t i n g L i s t ( k1 ) ; g e t P o s t i n g L i s t ( k2 ) ; largest ; shortest = listA ;

L i s t <DocID> s h o r t e s t ,

i f ( l i s t A . s i z e ( )< l i s t B . s i z e ( ) ) else

shortest

listB ; H a s h S e t <DocID >() ; i ++) { r e s u l t s . add ( l a r g e s t . g e t ( i ) ) ;

S e t <DocID> s m a l l S e t=new
while ( int

smallSet . addAll ( shortest ) ; i =0; i <l a r g e s t . s i z e ( ) ;


i f ( smallSet . contains ( l a r g e s t . get ( i ) ) )

}
return

results ;

Notemos que a diferencia del caso previo, el algoritmo (2.2) obliga a leer completamente las posting lists pero no requiere ordenarlas (lo cual puede ser costoso). Estos algoritmos son similares a los utilizados para resolver juntas en una base de datos. En particular, el segundo es conocido como hash-join. Si queremos optimizar un ndice para un modelo de IR con puntajes como el vectorial, podemos almacenar los puntajes de los documentos en el ndice mismo, ordenando las posting lists por estos puntajes. Dado que el usuario suele recibir slo una pequea porcin de los resultados totales, podemos acelerar la bsqueda recuperando los

documentos de mejor puntaje y trabajar con esas listas reducidas de hasta

elementos.

Otras estadstica que podemos almacenar en el ndice son los valores de las frmulas TF-IDF. Para esto podemos almacenar insertar el valor de

df

a la cabeza de cada trmino (notar que

df

es la longitud del posting list) e

tf

junto a cada posting. Para usos como las bsquedas por proximidad (ver subseccin

2.1.5), tambin es conveniente almacenar junto a cada posting el conjunto de posiciones donde ocurri la coincidencia. Esta ltima tcnica tambin es til para mostrar un resumen del texto con la coincidencia resaltada (esto es conocido como Keyword In Context o KWIC ). Para la construccin fsica del ndice se pueden utilizar una variedad de mtodos que dependen de: el mtodo de almacenamiento del ndice (archivos, bases de datos, etc), tipo de acceso al ndice (slo lectura vs. lectura y escritura), la escala del sistema (corpus, hardware, nivel de concurrencia, etc). Para resolver el problema del almacenamiento del ndice, se debe implementar una estructura de datos conocida como diccionario. El diccionario acta como un mapa de trminos a posting lists. Los candidatos para almacenar un diccionario son mapas hash y arboles B. Si el sistema es relativamente pequeo, el ndice se puede cargar en memoria y luego refrescarlo peridicamente. Otra alternativa es utilizar una base de datos, la cual resuelve los problemas de concurrencia y almacenamiento fsico de los posting lists (normalmente utilizando rboles B). Por otro lado, cuando el ndice es de cierta envergadura, se suele almacenar en archivos ad-hoc. A continuacin veremos algunas tcnicas de construccin de ndices en archivos, las cuales pueden adaptarse para almacenar el ndice en un RDBMS. Para generar el ndice normalmente se utilizan variantes de dos algoritmos que presentaremos a continuacin: Indexacin por Ordenamiento en Bloques

5 Memoria (algoritmo 2.4).


4 Traduccin 5 Traduccin

4 (algoritmo 2.3) e Indexacin por Barrido Simple en

del ingls Block sort-based indexing. del ingls Single-pass in-memory indexing.

2.1.

INFORMATION RETRIEV AL

25

Algoritmo 2.3 Pseudocdigo Java para el mtodo de Indexacin por Ordenamiento en Bloques.
/
R e c o r r e una n i c a v e z l o s d a t o s y g e n e r a p a r e s <termID , docID> Mantiene en memoria un mapa [ t e r m i n o > termID ]

I n d e x a c i n p o r Ordenamiento en B l o q u e s .

1 . R e c o r r e r l a l i s t a de documentos 1 . 1 T o k e n i z a r e l documento g e n e r a n d o p a r a cada t r m i n o un termID nico 1 . 2 A g r e g a r a l b l o q u e l o s p a r e s <termID , docID>


2. 3. /
public

S i p r o c e s a m o s ms de ' m a x B l o c k S i z e ' documentos o no tenemos ms p a r a p r o c e s a r e n t o n c e s almacenamos e l b l o q u e en d i s c o y renovamos l a s e s t r u c t u r a s de d a t o s C o n s o l i d a r l o s b l o q u e s e s c r i t o s en e l n d i c e f i n a l


void

i n d e x ( L i s t <Document> d o c L i s t , i d x B l o c k = new it IndexBlock () ;

int

maxBlockSize )

HashMap<S t r i n g , IndexBlock

I n t e g e r > termMap = new HashMap<S t r i n g ,

I n t e g e r >() ;

f o r ( I t e r a t o r <Document>

= docList . i t e r a t o r ()

i t . hasNext ( )

){

i d x B l o c k . a d d P a i r s ( t o k e n i z e ( i t . n e x t ( ) , termMap ) ) ;
i f ( i d x B l o c k . g e t S i z e ( )>=m a x B l o c k S i z e

// ordenamos p o r termID y l u e g o p o r docID // y c r e a l a s p o s t i n g l i s t s


idxBlock . sortAndInvert () ;

||

i t . h a s N e x t ( )== f a l s e )

// grabamos e l b l o q u e a d i s c o y l o r e g e n e r a m o s
idxBlock . saveToDisk () ; idxBlock . reset () ; } } saveTermMap ( termMap ) ; m e r g e B l o c k s I n t o I n d e x ( termMap ) ; }

El algoritmo (2.3) es simple pero tiene el problema de que requiere almacenar en memoria principal la correspondencia entre trminos e identicadores de trminos, lo cual puede ser excesivo en algunos corpus. Para evitar esto, existe una tcnica conocida como Indexacin por Barrido Simple en Memoria (ver pseudocdigo Java en algoritmo 2.4):

26

CAPTULO 2.

ESTADO DEL ARTE

Algoritmo 2.4 Pseudocdigo Java para el mtodo de Indexacin por Barrido Simple en Memoria.
/
I n d e x a c i n de S i m p l e B a r r i d o en Memoria R e c o r r e una n i c a v e z l o s d a t o s No u t i l i z a i d e n t i f i c a d o r e s de t r m i n o s Genera i n d i c e s c o m p l e t o s p a r c i a l e s que l u e g o s e c o n s o l i d a n 1 . R e c o r r e r l a l i s t a de documentos 1 . 1 Para cada t o k e n b u s c a r su p o s t i n g l i s t s y a l m a c e n a r su docID 2 . S i a l c a n z a m o s e l l m i t e de memoria almacenamos e l n d i c e i n v e r t i d o p a r c i a l en un a r c h i v o y renovamos l a s e s t r u c t u r a s de d a t o s 3 . C o n s o l i d a r l o s n d i c e s p a r c i a l e s en e l n d i c e f i n a l /
void

public

i n d e x ( L i s t <Document> d o c L i s t , partialIndex it = new

int

maxPostings ,

int

maxDictSize )

{ InvertedIndex InvertedIndex () ; ; i t . hasNext ( ) ; ){

f o r ( I t e r a t o r <Document>

= docList . i t e r a t o r ()

Tokenizer

t o k e n s = new

DocumentTokenizer ( i t . next ( ) ) ; {

while ( tokens . hasMoreElements ( ) )

p a r t i a l I n d e x . a d d P o s t i n g ( t o k e n s . n extE lemen t ( ) , tok . getDocID ( ) ) ;


i f ( p a r t i a l I n d e x . g e t P o s t i n g C o u n t ( )>=m a x P o s t i n g s

||

p a r t i a l I n d e x . g e t D i c t i o n a r y S i z e ( )>=m a x D i c t S i z e ) { p a r t i a l I n d e x . saveToDisk () ; partialIndex . reset () ; } } } mergePartialIndexes () ; }

Para que el algoritmo (2.4) sea eciente, se debe almacenar cada bloque con su diccionario y posting lists ordenadas. De esta manera el paso de consolidacin puede recorrer secuencialmente todos los archivos en una nica iteracin (podra hacerse en etapas si fueran demasiados) y consolidar las listas trmino a trmino. Si las posting lists estn ordenadas, consolidarlas ser ms simple ya que slo requerir comparar valores avanzando secuencialmente sobre todas al mismo tiempo.

Tal como fueron presentados, los algoritmos (2.3) y (2.4) son esencialmente centralizados porque no balancean la carga de la indexacin entre varias computadoras. Adems de estos algoritmos centralizados, en corpus extensos podemos utilizar algoritmos de indexacin distribuida.

Para efectuar una indexacin distribuida es posible utilizar un modelo de programacin llamado MapReduce (Dean y Ghemawat, 2008). Este modelo consiste en dividir un gran trabajo en pequeas tareas similares, las cuales pueden llevarse a cabo en paralelo por muchas computadoras. El algoritmo (2.5) implementa la indexacin distribuida utilizando MapReduce:

2.1.

INFORMATION RETRIEV AL

27

Algoritmo 2.5 Pseudocdigo Java para indexacin distribuida con MapReduce.


/
I n d e x a c i n D i s t r i b u i d a u t i l i z a n d o MapReduce . E l p r o c e s o comprende l o s s i g u i e n t e s p a s o s : 1 . D i v i s i n de documentos en N mappers 2 . P r o c e s a m i e n t o d e l documento en l o s mappers 3 . D i s t r i b u c i n de l o s p a r e s ( t e r m i n o , docID ) h a c i a l o s r e d u c e r s 4 . Merge y s o r t de l o s p a r e s ( t e r m i n o , docID ) p o r t r m i n o ( y o p c i o n a l m e n t e p o r docID ) 5 . R e d u c c i n de l o s p a r e s ( t e r m i n o , docID ) a ( t e r m i n o , l i s t a de docID ) / La f u n c i n Map r e c i b e documentos , l o s d i v i d e en t o k e n s y e m i t e p a r e s ( t e r m i n o , docID ) /
void

public

Map ( I n p u t <Document> i n p u t , token : tokens ) {

O u t p u t<S t r i n g ,

Integer > output )

L i s t <S t r i n g > t o k e n s = t o k e n i z e ( i n p u t . g e t E l e m e n t ( ) ) ;
for ( String

o u t p u t . add ( t o k e n , doc . g e t I d ( ) ) ; } }

E l r e d u c e r e c i b e t o d a s l a s e m i s i o n e s ( docID ) de una misma c l a v e ( t r m i n o y g e n e r a e l p o s t i n g l i s t en l a forma ( t e r m i n o > [ docId1 , . . . , docIdN ] ) /

public

void

R e d u c e ( I n p u t <S t r i n g , {

I t e r a t o r <I n t e g e r > > input ,

O u t p u t<S t r i n g ,

L i s t <I n t e g e r > > output ) String I t e r a t o r <I n t e g e r > L i s t <I n t e g e r >

term = i n t p u t . getKey ( ) ; docIdIterator = new { = input . getValue () ; L i n k e d L i s t <I n t e g e r >() ; postingList

while ( d o c I d I t e r a t o r . hasNext ( ) )

p o s t i n g L i s t . add ( i t . n e x t ( ) ) ; } o u t p u t . add ( term , p o s t i n g L i s t ) ; }

Para implementar el algoritmo anterior debemos contar con un framework que implemente MapReduce como Hadoop (Apache, 2010). Al tratar la indexacin oine de nuestra propuesta de solucin, veremos que es factible indexar un dominio en forma distribuida sin utilizar MapReduce o Hadoop.

Indexacin Dinmica
Al abordar los algoritmos para la construccin del ndice, no nos hemos preocupado por saber qu ocurre cuando el sistema se encuentra en funcionamiento y ya existe un ndice productivo. El problema de indexar documentos y agregarlos a un ndice existente se conoce como indexacin dinmica. La indexacin dinmica es de nuestro especial inters porque al indexar objetos se debe considerar su frecuencia de creacin, actualizacin y eliminacin. Si el ndice se mantiene en una base de datos, su actualizacin no presenta ningn inconveniente ya que

28

CAPTULO 2.

ESTADO DEL ARTE

las propiedades ACID nos permiten agregar y eliminar documentos independientemente de las consultas que se hagan a la tabla. Por el contrario, si decidimos almacenar el ndice en archivos, debemos considerar cmo actualizarlos en caliente de forma tal que las tareas de bsqueda no intereran con las de indexacin. Veamos algunas formas de resolver el problema de la indexacin dinmica sobre archivos:

Reindexacin Completa

Esta es la solucin ms simple y consiste en regenerar el ndice completa-

mente desde cero. Esta solucin tiene como principal ventaja su simplicidad pero requiere de espacio suciente para mantener el ndice actual mientras se genera la nueva versin. Adems debemos considerar que el tiempo para generar el ndice puede ser prohibitivo en corpus grandes. Esta opcin es viable en los casos en los que la frecuencia de actualizacin del corpus es baja y el retardo en hacer visibles los nuevos documentos es aceptable (Manning et al., 2008).

ndices Auxiliares y Generacionales

Este mtodo consiste en mantener un ndice principal que

contiene la mayor cantidad de documentos y disponer pequeos ndices auxiliares para agregar los nuevos documentos. Para manejar las eliminaciones sin requerir la actualizacin fsica del ndice, se pueden utilizar vectores de invalidacin (bit vectors ), los cuales utilizan el bit

para indicar si el documento

dj

existe. Peridicamente se fusionan los ndices principales y los auxiliares y se eliminan los documentos marcados en el vector de invalidacin. En la subseccin (2.4.1) veremos que Apache Lucene aplica una estrategia similar.

Archivos Indexados

En este caso se generan un archivo ndice (posiblemente implementado con r-

boles B) y un archivo de datos con las posting lists. Este esquema permite actualizar el ndice con facilidad pero puede ser costoso de implementar (equivale a resolver problemas tpicos de un RDBMS). Un anlisis completo de esta alternativa se presenta en (Cutting y Pedersen, 1990).

Operaciones Extendidas
La bsqueda de trminos en un ndice invertido es una forma eciente de encontrar documentos cuando somos efectivos en escoger los trminos que producirn mayor relevancia. Sin embargo, hay casos en los que no estamos seguros de cules son los mejores trminos y necesitamos de cierta ayuda adicional. A continuacin presentamos algunas tcnicas que exibilizan la tarea de recuperacin.

Bsquedas de proximidad

Consiste en especicar la distancia mxima entre dos trminos. Por ejem-

plo, la bsqueda Caesar AND/5 Brutus retornara el documento Brutus fue hijo de Caesar pero no el documento Caesar fue asesinado por el senado con la ayuda de Brutus. El objetivo de esta tcnica es recuperar documentos donde las palabras se encuentran en un mismo contexto. Las bsquedas por proximidad se pueden resolver utilizando un ndice posicional, el cual mantiene junto a cada posting las posiciones donde podemos ubicar el trmino en el documento original. Otra variante de implementacin es efectuar una bsqueda lineal sobre los documentos recuperados, ltrando los que no cumplan con el criterio de proximidad. Esta variante tiene peor rendimiento pero requiere menor espacio de almacenamiento en el ndice y disminuye tanto su complejidad como la del proceso indexador.

Phrase Queries

Este tipo de bsquedas son conocidas tambin como bsquedas literales. Las bsquedas

literales pueden verse como un caso particular de bsquedas de proximidad en el cual se deben cumplir: la proximidad entre los trminos de la query es exactamente uno la proximidad se aplica slo hacia adelante (es decir, la query rosa salmn no equivale a salmn rosa). La implementacin de las phrase queries se basa nuevamente en ndices posicionales o en ltrado de documentos.

2.1.

INFORMATION RETRIEV AL

29

Wildcards

Los wildcards son smbolos que nos ayudan a buscar todos los trminos que siguen un patrn

especco. Por ejemplo, en SQL los wildcards se especican mediante el smbolo %, mientras que en un lesystem, es comn especicarlos con el smbolo *. En un search engine los wildcards se utilizan cuando conocemos la forma de una parte del trmino de bsqueda pero no podemos especicarlo completamente. Utilizando wildcards, queries como bol* retornan documentos que contienen las palabras bolsa, bolero, bola, etc. Las bsquedas por wildcards se pueden resolver utilizando ndices permuterm (Gareld, 1976) n-gram (ver Zobel y Dart, 1995).

Edit distance

Cuando la query contiene pequeos errores de ortografa, podemos reconvertirla buscan-

do trminos cercanos al original. Para lograrlo, podemos utilizar una medida de distancia entre trminos del lxico llamada edit distance Levenshtein distance (Levenshtein, 1965). La idea general detrs del edit distance es calcular cuntas inserciones, modicaciones y eliminaciones hay que efectuar sobre dos strings para que uno se convierta en el otro. El edit distance se puede calcular fcilmente utilizando programacin dinmica. Un procedimiento para corregir una query por medio de edit distance es correr el algoritmo sobre los trminos del lxico y la query, suplantando sta por los trminos de menor edit distance. Una vez obtenidos los candidatos de menor edit distance, se accede al ndice invertido utilizando el conjunto ampliado de trminos. Para que este procedimiento no sea excesivamente costoso existen heursticas como asumir que las primeras

letras de la query son correctas y calcular el edit distance slo sobre los trminos del lx-

ico que comienzan con esas letras. Una variante a los edit distance es la utilizacin de un tesauro. Esta tcnica la veremos en las prximas subsecciones.

Range Queries

Las bsquedas por rango o range queries consisten en especicar un criterio (rango),

el cual debe cumplirse en el documento para que ste sea recuperado. Ejemplos: 2009 to 2010, Brutus to Caesar (aqu el rango es por orden lexicogrco) Bares en Rivadavia al 1000 to 1900. Este tipo de bsquedas se pueden resolver de distintas formas. Una forma de resolver el problema consiste expandir la query en forma de una conjuncin dentro del rango. Esta solucin tiene como principal problema la granularidad de la expansin ya que queries como 1,1 to 1,999 1 to 1.000.000 sern demasiado costosas de implementar. Otra opcin de implementacin es recorrer el lxico y ltrar los trminos que cumplen con el criterio del rango. Para lxicos moderados esta puede ser una opcin factible. Una tercera va de solucin consiste en utilizar un ndice de bsqueda como los utilizados en un RDBMS. Por supuesto tambin podemos resolver este problema mediante pos ltrado de resultados. Este esquema requiere eliminar los trminos de la disyuncin (en caso de recuperacin booleana) y luego recorrer los resultados ltrando los documentos. Para resolver este problema, ciertos motores no utilizan el operador to o el hasta de nuestros ejemplos sino que el usuario debe explicitar cmo efectuar la bsqueda dando una ayuda acerca del tipo de datos del rango y su granularidad. Las bsquedas literales, wildcards, por rangos y edit distance son soportadas en Apache Lucene (ver casos de estudio en subseccin 2.4.1).

Bsquedas Facetadas

Tradicionalmente han coexistido dos modelos de bsqueda, el modelo de nave-

gacin y el modelo de bsqueda directa (SIGIR, 2006).


En el modelo de navegacin, el usuario especica iterativamente el tema de inters navegando a travs de una taxonoma (cuyas categoras no necesitan ser necesariamente excluyentes entre s). Ejemplos de este modelo se implementan en Google Directory (http://directory.google.com), Yahoo! Directory (http://dir.yahoo.com) y Open Directory Project (http://www.dmoz.org/). Por otro lado, en el modelo de bsqueda directa el usuario escribe una bsqueda en lenguaje natural para luego navegar a travs

30

CAPTULO 2.

ESTADO DEL ARTE

de pginas de resultados o renar iterativamente los trminos de bsqueda. Los ejemplos de bsqueda directa son los buscadores de Google (http://www.google.com) y Yahoo! (http://www.yahoo.com). La combinacin de estos dos modelos de bsqueda han dado lugar a un tercer modelo, la bsqueda facetada o faceted search. En la bsqueda facetada el usuario comienza una bsqueda directa y el motor de bsqueda presenta los resultados junto a una categorizacin por caractersticas ortogonales entre s. En la gura (2.5) vemos un ejemplo de bsqueda facetada en el marketplace e-Bay (http://www.ebay.com).

Figura 2.5: Bsqueda Facetada. Al buscar un ipod, podemos cortar los resultados en distintas facetas o dimensiones. En este caso las facetas son el tipo de producto, la condicin, capacidad y color. Otras facetas podran ser el precio, la garanta, etc.

Si bien en el caso de la gura (2.5) se efectu una bsqueda directa, bien podramos llegar al mismo landing

6 utilizando el modelo de navegacin (el cual suele permitirse en los sitios de comercio electrnico

como e-Bay). La diferencia principal reside en que el landing obtenido por navegacin no es un modelo mixto sino que es una navegacin a travs de una taxonoma. Un desafo que se presenta al implementar las facetas es el hecho de que los resultados pueden ser muy heterogneos, por lo cual la eleccin de facetas como el color de un reproductor de msica slo podran aparecer cuando eliminamos otros resultados que no admiten dicha faceta (como por ejemplo una fuente de alimentacin). La bsqueda facetada no es implementada directamente por ninguno de los casos de estudio de la seccin (2.4), sin embargo, s es implementada por una derivacin del proyecto Lucene conocida como Solr (http://lucene.apache.org/solr/). En nuestra propuesta de solucin vamos a retomar este tipo de bsquedas.

Stemming y Lematizacin
Si bien las operaciones extendidas nos permiten mejorar la coincidencia entre la query y los trminos del lxico, siguen operando sobre un espacio de alta dimensionalidad (segn el modelo vectorial de la

6 El

trmino landing se utiliza para referir a la pgina donde se llega luego de una bsqueda.

2.1.

INFORMATION RETRIEV AL

31

subseccin 2.1.4). Si reducimos las dimensiones del problema proyectando los trminos sobre un espacio de menor orden, posiblemente obtengamos un mayor recall. La proyeccin de un espacio sobre otro de menores dimensiones implica necesariamente prdida de informacin, la cual naturalmente se traducir en peor precisin. A continuacin vamos a explicar las tcnicas de stemming y lematizacin, las cuales buscan reducir el nmero de dimensiones del lxico con la menor prdida de informacin posible.

Lematizacin

El proceso de lematizacin busca remover las formas exivas de las palabras para obtener

una versin cannica del trmino llamado lema. La lematizacin es un proceso complejo que requiere llevar una palabra del diccionario a otra palabra del diccionario, reconociendo correctamente cul es el lema del trmino ingresado (normalmente esto requiere reconocer el POS

7 del trmino).

Veamos un caso prctico en el siguiente ejemplo:

Ejemplo 2.1.7.

Efectuemos la canonizacin de algunas exiones del verbo

escribir:

lema(escribiendo)=escribir lema(escrito)=escribir lema(escrib)=escribir


El proceso de lematizar trminos es una solucin de compromiso entre recall y precisin que puede ser ms o menos til dependiendo del lenguaje. De los casos de estudio que tomamos en la seccin (2.4), ninguno utiliza por defecto un lematizador. Un caso prctico de lematizacin automtica se describe en (Galceran, 2006), donde adems se concluye que la distribucin de lemas en un texto promedio se encuentra muy concentrado alrededor de unos pocos lemas. Un ejemplo de lematizador online se puede encontrar en (Grupo de Estructuras de Datos y Lingstica Computacional, 2006).

Stemming

El proceso de stemming consiste en transformar palabras con el n de colisionar trminos

de semntica similar en un mismo trmino (el cual no necesita ser una palabra del diccionario como ocurra con el lema). El resultado de aplicar stemming a una palabra es un stem . A continuacin vemos algunos ejemplos de stemming en espaol.

Ejemplo 2.1.8.
ms adelante):

Efectuamos el stemming de una lista de palabras utilizando un stemmer Snowball (ver

stem(tornado)=torn stem(tornados)=torn stem(tornar)=torn


Como podemos ver en el ejemplo anterior, el stemming logra colisionar en torn los trminos de semntica similar tornado y tornados. Un problema que debe observarse en el ejemplo anterior es que tornado (cuya acepcin principal podra referir al fenmeno meteorolgico) colisiona en su stem con el de tornar (cuya semntica reere al acto de convertir una cosa en otra). Este problema derivado de la heurstica empleada para buscar los stems es conocido como overstemming. Implementativamente, los stemmers son un conjunto de reglas aplicadas en orden para transformar y eliminar sujos de palabras. Al igual que el lematizador, el stemmer es una herramienta que incrementa el recall a costa de la precisin. Normalmente, un stemmer es ms agresivo que el lematizador en cuanto a las colisiones que genera ya que se basa en heursticas y no en un anlisis morfolgico de las distintas inexiones del vocabulario.

7 El 8 El

trmino POS (part of speech) del ingls se utiliza para referir a la identicacin de una palabra como verbo, adjetivo, trmino stem se traduce al espaol como raz, lo cual maniesta la intencin del stemming de encontrar una

sustantivo, adverbio, etc. Por ejemplo, los POS de la frase escribiendo el libro son (verbo,artculo,sustantivo). raz entre palabras similares semanticamente. No se debe confundir la raz obtenida del stemming con la verdadera raz del lenguaje correspondiente, ya que la segunda s es una palabra del diccionario.

32

CAPTULO 2.

ESTADO DEL ARTE

Existen implementaciones de stemmers para muchos lenguajes, para el ingls la ms conocida es la versin de Porter (Porter, 1980), mientras que para lenguajes como el castellano contamos con stemmers derivados de los algoritmos snowball que describiremos en el prximo apartado.

Es preciso notar que el stemming no es aplicable a todos los lenguajes. Un ejemplo de esto es el chino, el cual no permite el simple truncado sus palabras. El stemming tampoco tiene la misma efectividad en todos los lenguajes. Por ejemplo, en lenguajes como el ingls el stemming es menos efectivo que en espaol o francs ya que estos ltimos son ms exivos (Porter, 2001).

Stemmers Snowball

Snowball es un lenguaje para la generacin automtica de algoritmos de stem-

ming (Porter, 2001). El propsito de snowball fue crear un lenguaje comn a partir del cual poder especicar stemmers para distintos lenguajes.

A partir de snowball han surgido stemmers para lenguajes como ingls, francs, espaol, portugus, italiano, rumano, alemn y muchos otros.

Los casos de estudio que vamos a analizar en la seccin (2.4) utilizan stemmers construidos mediante snowball.

Expansin de Consultas
A pesar de nuestros esfuerzos de matching mediante stemming o lematizacin, el problema subyacente a la tarea de recuperacin es complejo por las distintas formas de expresin y las ambigedades que surgen del uso del lenguaje.

A continuacin denimos y ejemplicamos estas relaciones del lenguaje, las cuales presentamos grcamente en la gura (2.6).

Sinnimo

Dicho de un vocablo o de una expresin: Que tiene una misma o muy parecida signicacin

que otro. (RAE, 2006). Los sinnimos son palabras que comparten la misma semntica. Ejemplos: despus vs. luego, comenc vs. empec, violonchelo vs. cello.

Parnimo

Se dice de cada uno de dos o ms vocablos que tienen entre s relacin o semejanza, por su

etimologa o solamente por su forma o sonido. (RAE, 2006). En general los parnimos son palabras con pronunciaciones iguales o similares pero semntica distinta. Ejemplos: maya vs. malla, concejo vs. consejo, vaya vs. valla (en particular estos parnimos adems son homfonos).

Mernimo y Holnimo

Cuando en dos palabras una de ellas constituye semanticamente la parte de un

todo representado por la otra, la parte es llamada mernimo y el todo es conocido como holnimo.
Ejemplos: dedo es mernimo de su holnimo mano, pas es holnimo de su mernimo provincia.

Hipernimo e Hipnimo

Cuando en dos palabras una de ellas constituye semanticamente un concepto

particular y la otra representa un concepto general, el concepto particular es llamado hipnimo y el concepto general es el hipernimo.

2.1.

INFORMATION RETRIEV AL

33

automvil
holnimo

hiponimo hipernimo

vehculo

mernimo

mernimo sinnimos

butaca

asiento (sust.)
parnimos

asiento (verbo)
Figura 2.6: Relaciones entre palabras. En este ejemplo vemos la sinonimia, paronimia, meronimia e hiperonimia.

Estas relaciones del lenguaje traen consecuencias al motor de bsquedas, quien debe poder diferenciar entre parnimos, asociar sinnimos y contextualmente tratar de forma adecuada mernimos, holnimos, hipnimos e hipernimos.

Por ejemplo, si nos encontramos en el contexto de un buscador de avisos clasicados, es comn que exista una diferencia de vocabulario entre quien publica avisos y quien busca servicios. La persona que ofrece sus servicios como mecnico de autos puede publicar el aviso reparacin de Mercedez-Benz, Audi y Volkswagen, mientras que la persona que busca puede escribir la query servicio de chapa ste un modelo particular de la lnea Volkswagen).
y

pintura de Passat (siendo

Las herramientas que poseen los motores de bsqueda para mejorar su conocimiento y capacidad de tratar expresiones son los tesauros. Un tesauro es una coleccin de relaciones entre palabras y conceptos que ayudan al sistema a encontrar la forma adecuada de mejorar la respuesta ante una query. En un tesauro podemos modelar las relaciones entre palabras, permitiendo expandir consultas utilizando sinnimos o formas cannicas de un concepto.

Denicin 2.1.10 (Expansin de Consultas).


una query inicial

El proceso de expansin de consultas consiste en convertir

q0

en una nueva query

q1

de forma tal que el conjunto de mtricas asociadas el xito

del sistema mejoren sus indicadores.

La denicin (2.1.10) es intencionalmente general porque (a) la eleccin de las mtricas que indican el xito del sistema es un problema en s mismo con distintas soluciones (ver subseccin 2.1.3) y (b) la expansin de consultas normalmente se da mediante tesauros o relevance feedback.

En la actualidad existe una herramienta que modela las relaciones entre palabras conocida como WordNet (Princeton, 2010). Esta herramienta ha sido portada a varios lenguajes y puede ser til para resolver los problemas de sinonimia, meronimia, etc. En la gura (2.7) podemos ver la versin web de WordNet 3.0.

34

CAPTULO 2.

ESTADO DEL ARTE

Figura 2.7: Versin web de WordNet 3.0. Para la palabra soccer del ingls obtenemos conjuntos de sinnimos y otras relaciones.

Si bien WordNet es una herramienta muy til, el modelado de un dominio particular suele tener complicaciones adicionales como palabras en otros lenguajes o marcas comerciales como sony o notebook, lo cual hace difcil usarlo tal como se presenta. Adems, en la gura (2.7) podemos ver que si quisiramos expandir la consulta soccer (ftbol) utilizando relaciones como header, seguramente perjudicaramos la precisin debido a las relaciones de sinonimia de esta ltima (header se puede utilizar para referirse a encabezados de documentos).

Caches
Dependiendo de los volmenes de datos y niveles de concurrencia del sistema de IR, es comn que la bsqueda o la indexacin de documentos utilicen intensivamente recursos como disco, red o el RDBMS. Las respuestas a operaciones repetitivas pueden reutilizarse para ahorrar recursos y mejorar los tiempos de respuesta del sistema. Esta reutilizacin se implementa por medio de memorias cach. Existen distintos niveles de cach que responden a distintas granularidades de acceso a la informacin. En la capa ms externa, de grano grueso, tenemos caches de pginas de resultados. Cuando la query del usuario es idntica a otra query efectuada recientemente, los caches de pginas de resultados retornan una versin servida con anterioridad. Es preciso notar que si las bsquedas se sirven de forma personalizada, la clave del cach (tpicamente la URL) debe contener informacin que identique al usuario, de forma de no servir a un usuario A un listado hecho a medida de un usuario B. Un nivel ms abajo, podemos tener un cach de resultados del ndice invertido, el cual responde cuando un usuario busca un conjunto de trminos que ya ha sido buscado por el resto de los usuarios. Este tipo de caches suele ser muy efectivo ya que la entradas del ndice invertido no deberan depender de un usuario particular, permitiendo alto reuso de las entradas en cach. Si el nmero de objetos a almacenar es muy grande, podemos utilizar un cach externo como Memcached (Memcached, 2009). La utilizacin de un cach externo permite aumentar la tasa de aciertos (hit ratio) en caso de que las bsquedas o procesos de indexado corran en paralelo en varios equipos.

2.1.

INFORMATION RETRIEV AL

35

Es preciso notar que el cach de grano grueso como el de pginas de resultados tiene un hit ratio menor a uno de grano no (como el del ndice invertido). Sin embargo, el cach de pginas tpicamente agrega el trabajo de confeccin del listado. Estos temas se discuten extensamente en (Baeza-Yates et al., 2008). Para el caso de las bsquedas, debemos tener en cuenta que el nivel de uso concurrente del sistema suele ser una variable difcil de controlar, por lo que debemos estar preparados para utilizar caches donde sea necesario. Como veremos al hablar de mapeos objeto relacionales (ORM, ver subseccin 2.3.7) y al tratar Hibernate Search y Compass (subsecciones 2.4.2 y 2.4.3), el hecho de recuperar objetos desde un ndice requiere obtener todos sus atributos mediante un proceso llamado hidratacin . Si la hidratacin se implementa utilizando el ORM, es importante disponer de un cach que evite comunicacin innecesaria con el RDBMS. Para esto, los ORM de mayor envergadura suelen implementar un cach a nivel de sesin (cach L1) y otro compartido entre sesiones (cach L2).

2.1.6. Tcnicas de Puntaje y Relevancia


En esta subseccin vamos a analizar tcnicas para generar ordenamientos de documentos aplicables a nuestro motor de bsqueda sobre objetos. En particular nos interesa saber cmo:

puntuar documentos ms all de la nocin de relevancia dada por el modelo de IR, indexar objetos cuya estructura excede la del texto plano, utilizar tcnicas de puntuacin por relacin entre documentos (PageRank y HITS), mejorar la relevancia por medio de anlisis de query logs y realimentacin por parte del usuario.

Reglas de Negocio
Los modelos de IR que hemos analizado en la subseccin (2.1.4) estn orientados a recuperar y puntuar los documentos desde el punto de vista de la relevancia. Sin embargo, cuando se construye un sistema de IR se debe tener en cuenta que el xito del mismo excede la capacidad de asociar documentos u objetos con queries. Las frmulas de puntajes derivadas de las reglas del negocio son las que tienen la ltima palabra acerca de cmo se presentan los resultados al usuario. Para esto se suelen utilizar variables de negocio (antigedad del resultado, pago por posicionamiento, etc) como fuentes adicionales de puntaje, las cuales complementan la relevancia del modelo de IR. Las distintas fuentes de puntajes se introducen en frmulas matemticas que determinan el orden nal de los resultados. Mas all del tipo de frmula a utilizar, nos encontraremos con dos tipos de reglas:

clusterizacin y posicionamiento. Las reglas de clusterizacin separan documentos en clases, mientras


que las reglas de posicionamiento priorizan documentos de forma interna a un cluster. Este tipo de reglas tambin se las puede conocer como reglas duras y reglas blandas. Los atributos del documento y la query se suelen utilizar como variables de entradas a algoritmos de puntuacin. Esas variables de entradas se suelen llamar proxys. A continuacin presentamos un ejemplo de este modelo de puntajes.

Ejemplo 2.1.9 (Reglas duras y blandas).


las siguientes reglas de negocio:

Un sistema de clasicados online prioriza sus avisos mediante

Los avisos se dividen en dos sectores: pagos y gratis. Los avisos pagos aparecen siempre primero que los avisos gratis. La relevancia dada por el modelo de IR es un valor entre 0 y 1 que se pondera como el 60 % del puntaje nal del aviso. La antigedad del aviso pondera el 40 % restante del puntaje, siendo este valor igual a Los avisos de ms de 1 ao de antigedad no suman puntaje en este proxy.

meses antiguedad . 12

36

CAPTULO 2.

ESTADO DEL ARTE

Figura 2.8: Reglas duras y blandas. En este ejemplo generamos dos clusters: avisos pagos y gratuitos. Dentro de cada cluster opera la formula descripta en el ejemplo.

Para cumplir con la primera restriccin podemos sumar un valor unitario a los avisos pagos y luego ponderar segn la segunda y tercera restriccin:

Score (q, dj ) = 1 AvisoP ago (dj ) + 0, 6 Similitud (q, dj ) + 0, 4 1


Donde:

Antigedad (dj ) u 12

AvisoP ago (dj ) {0, 1} Similitud (q, dj ) [0, 1]

segn si el aviso es pago o no. segn denido en la implementacin del modelo de IR. representando los meses del ao.

Antigedad (dj ) {0; 1; . . . ; 12} u

En el diseo de la propuesta que presentaremos en el captulo 3 tendremos en cuenta las reglas duras y blandas, proveyendo las herramientas necesarias para implementarlas en cada dominio.

Zonas y Campos
Usualmente, los documentos suelen contener meta datos o estructuras de mayor organizacin que el simple texto libre. Un ejemplo podra ser un documento que contiene una fecha de creacin, un autor y un cuerpo principal. Estos meta datos o estructuras son conocidos como campos y zonas (Manning et al., 2008). Manning propone distinguir estos dos conceptos llamando campo a un breve fragmento de meta datos y zona a un campo de texto libre de mayor tamao. El hecho de contar con campos y zonas genera la oportunidad de efectuar queries ms precisas sobre distintas partes de la estructura del documento. Por ejemplo, podramos efectuar bsquedas por rangos (ver subseccin 2.1.5) sobre ciertos campos y bsquedas booleanas sobre determinadas zonas.

Ejemplo 2.1.10.

publish-date, autor, title

Supongamos que contamos con un sistema que almacena noticias estructurndolas en: y

content.

Si contamos con la posibilidad de efectuar consultas booleanas sobre el

corpus de noticias, podemos pensar en las siguientes consultas:

autor:(Kevin*) AND publish-date:(2009) AND content:(taiwan china conict) publish-date:(2001 to 2009) AND content:(stock market IPO)
Al introducir campos y zonas debemos replantearnos cmo valorizar los documentos en cada una de las frmulas de similitud de los modelos de IR. En adelante, sin prdida de generalidad, vamos a asumir que los campos se utilizan para ltrado y slo necesitamos incluir la zonas en el clculo de similitud del modelo de IR.

2.1.

INFORMATION RETRIEV AL

37

Denicin 2.1.11

(Similitud Booleana para Zonas)

Para el caso del modelo booleano, redenimos la

similitud como la suma ponderada de la relevancia booleana en cada zona (Manning et al., 2008):

SimilitudBoolZones (q, dj ) =
i

gi SimilitudBool (q, dj [i])

(2.1.8)

donde:

gi [0, 1] es un valor que pondera la importancia de la zona i (constante para todos los documentos), gi = 1,
i

mento

SimilitudBool (q, dj [i]) {0; 1} dj .

representa la similitud binaria de la query

en la zona

del docu-

La denicin (2.1.11) introduce valores

gi

asociados a la importancia de cada zona en un documento,

pero no explicita cmo se deben escoger dichos pesos. El problema de elegir el valor de los pesos crucial ya que afecta de manera determinante al xito del sistema.

gi

es

Para escoger dichos valores, podemos utilizar un mtodo de aprendizaje supervisado en el cual etiquetamos pares pares relevantes entre si y cercanos a 0 para pares poco relevantes. Utilizando los

(qn , dj ) mediante la funcin de entrenamiento (qn , dj ) [0, 1] , la cual da valores cercanos a 1 para (qn , dj ), podemos obtener pesos gi G planteando una funcin de costo G , (qn , dj ) para luego resolver el problema de

optimizacin:

arg m n
G


n,j

G , (qn , dj ) = arg m n G
n,j

[ (qn , dj ) SimilitudBoolZones (qn , dj )]

n,j 2

= arg m n
gi

(qn , dj )
i

gi SimilitudBool (qn , dj [i])

(2.1.9)

Ejemplo 2.1.11.

Obtengamos el valor ptimo de los pesos

resultados de una funcin

gi para documentos de 2 zonas (i binaria (slo toma los valores 0 y 1).

= 2)

y los

Para resolver el problema es conveniente realizar algunas deniciones y simplicaciones a la notacin: establecemos

SimilitudBool (qn , dj [0]) = s0 (qn , dj ) = s0

SimilitudBool (qn , dj [0]) = s1 (qn , dj ) =

s1 Rij = {R00 ; R01 ; R10 ; R11 } para indicar la cantidad de casos en los que y a su vez hubo/no hubo coincidencia booleana en la zona i y j (R00 es el caso en el que no hubo coincidencia en ninguna zona, R10 indica que hubo coincidencia en la primera zona y no en
denimos las variables

=1

la segunda, etc). las variables dado que

Nij = {N00 ; N01 ; N10 ; N11 }

de forma idntica a

Rij ,

pero para el caso en el que

= 0.

g0 + g1 = 1,

podemos simplicar deniendo una nica variable

g/g0 = g g1 = 1 g

Entonces debemos reemplazar estas variables en la ecuacin (2.1.9):


2

(qn , dj )
n,j i

gi SimilitudBool (qn , dj [i])

total =
n,j

{ [s0 g + s1 (1 g)]}

(2.1.10)

Vemos las contribuciones aportadas en cada caso:

38

CAPTULO 2.

ESTADO DEL ARTE

cuando s0 = 0 y s1 = 0 se produce una contribucin [0 g + 0 (1 g)] = . Variando para sus valores 0 y 1 se obtiene una contribucin de R00 (ver que estamos sumando R00 veces el valor = 1).

s0 = 0 y s1 = 1 2 N01 (g 1) s0 = 1 s0 = 1 N11 .
y y

produce una contribucin

[ (1 g)]
2

. Variando

se expande en

R01 g 2 +
2

s1 = 0 s1 = 1

produce una contribucin

( g)

. Variando

se expande en
2

R10 (1 g) + N10 g 2
se obtiene

produce una contribucin

{ [g + (1 g)]} = ( 1)

. Variando

Entonces reescribimos la ecuacin (2.1.10) como:

total = R01 g 2 + N01 (g 1) + R10 (1 g) + N10 g 2 + R00 + R11


Utilizando el hecho de que

(g 1) = (1 g)

total = (N01 + R10 ) (1 g) + (R01 + N10 ) g 2 + R00 + R11


Diferenciando respecto de

e igualando a cero obtenemos:

dtotal = 2 (N01 + R10 ) (1 g) + 2 (R01 + N10 ) g = 0 dg N01 + R10 N01 + R10 + R01 + N10
que minimiza el error cuadrtico para el conjunto de

goptimo =
De esta manera obtenemos el estimador entrenamiento.

goptimo

Cuando las funciones

(qn , dj )

Similitud (qn , dj )

no asumen valores binarios, el problema del ejemplo

(2.1.11) se vuelve ms difcil de resolver analticamente. Para estos casos es necesario utilizar otros mtodos para minimizar los errores de clasicacin. Al estudiar Apache Lucene (subseccin 2.4.1) veremos que la heurstica que utiliza para priorizar zonas (en la terminologa de Lucene se habla de campos) es una alteracin de la frmula de puntajes muy similar a la ecuacin (2.1.8). La diferencia en el caso de Lucene es que los pesos arbitrarios. Un caso adicional a contemplar es cuando los documentos son heterogneos. Este es el caso del buscador sobre objetos que propondremos en el captulo 3, siendo que las soluciones para dicho caso las posponemos hasta tratar la propuesta de solucin.

gi

pueden tomar valores

PageRank y HITS
Los modelos de IR que hemos tratado hasta ahora ignoraban las inter relaciones entre documentos. En casos como la bsqueda web, es benecioso tener en cuenta la relacin entre documentos como una medida de la autoridad que tiene una pgina como fuente de informacin relevante. En esta seccin describiremos dos algoritmos muy conocidos que generan mtricas de relevancia basndose en la estructura del grafo que interconecta entes del dominio del problema, para luego en el captulo 3 analizar la factibilidad de incluir estos algoritmos en nuestro motor de bsqueda sobre objetos. Para ser consistentes con la bibliografa, en esta subseccin vamos a dejar de hablar momentneamente de documentos para pasar a hablar de pginas. Mas all de que este ltimo trmino denota el uso de estos algoritmos en los buscadores web, no hay mayores diferencias entre una pgina y un documento.

2.1.

INFORMATION RETRIEV AL

39

PageRank

El algoritmo PageRank descripto en (Page et al., 1998) fue utilizado como fuente de rel-

evancia para el algoritmo de bsqueda del buscador web Google . A continuacin vamos a explicar los conceptos detrs de PageRank as como su mecnica de clculo basndonos en (Austin, 2006). La idea principal detrs de PageRank es dejar que las pginas se voten entre s mediante hipervnculos. Para explicar este proceso es necesario introducir algunas deniciones.

Denicin 2.1.12 (PageRank).


tancia

Sea una pgina puntual

I (Pj ),

cada una con lj hipervnculos apuntando a

Pi y un conjunto de pginas Pj Bi Pi , entonces denimos el valor: I (Pj ) lj

de impor-

P ageRank (Pi ) = I (Pi ) =


Pj Bi

(2.1.11)

Segn la denicin (2.1.12), cada

Pj

que apunte a

Pi

emite un voto proporcional a su importancia

(PageRank) e inversamente proporcional al nmero de enlaces presentes en ella. Lo primero que notamos al analizar esta denicin es que para calcular el PageRank de una pgina debemos conocer el de todas las que enlazan a ella. Otro aspecto a notar de la denicin (2.1.12) es que los valores de

I (Pj )

tienen sentido slo en trminos relativos a las pginas que entraron en el clculo y

no representan valores absolutos de importancia para todo el universo. A lo largo de este apartado veremos cmo calcular simultneamente los valores de matricial y teora de probabilidades. Comencemos con algunas deniciones:

I (Pi ) mediante clculo H = [Hij ]


de la

Denicin 2.1.13
siguiente forma:

(Matriz de Hipervnculos)

Denimos la matriz de hipervnculos

Hij =

1/lj 0 H

si

Pj Bi (esto

es,

Pj apunta

Pi )

otro caso

Preventivamente podemos pensar en azar de una pgina

como una matriz que expresa la probabilidad de que pasemos al

Pj

a una

Pi .

Utilicemos la matriz

para redenir

I (Pi ):
cuyas componentes son los

Denicin 2.1.14
= 1.

(Vector de PageRank)

PageRank de cada pgina

Pi

tal que

I = HI .

Denimos el vector Esto es,

I = [I (Pi )]

es un autovector de

cuyo autovalor es

Este tipo de autovectores cuyo autovalor es unitario se conoce como autovector estacionario.

El problema al que nos enfrentamos ahora es cmo obtener

I.

Para esto podemos utilizar un mtodo

estndar para la obtencin de autovectores conocido como el mtodo de potencias:

I k+1 = HI k
Para utilizar el mtodo de potencias debemos proponer un vector inicial diferencia entre pasos menor a un valor umbral. El siguiente problema con el que nos encontramos ahora es cmo asegurar que este procedimiento:

I0

e iterar hasta obtener una

1. sea convergente,

2. no dependa del vector inicial

I0,

3. nos entregue la informacin que estamos buscando.

9 Google

no ha dado a conocer cul es la incidencia que hoy en da tiene PageRank en el puntaje de una pgina.

40

CAPTULO 2.

ESTADO DEL ARTE

Con la formulacin de incondicionalmente.

que hemos hecho a priori, ninguno de estos tres requerimientos se cumple

Estos problemas se pueden resolver replanteando el modelo en un esquema de navegacin al azar (random

surfer, Page et al. 1998). Este modelo supone un usuario que sigue al azar los lj hipervnculos de
proponen considerar el PageRank como el tiempo promedio que se pasa en una pgina las distintas pginas

Pj ,

saltando aleatoriamente de pgina en pgina. Dado este esquema de navegacin al azar, los autores

Pi

llegando desde

Pj .

Sin embargo, la navegacin al azar tiene problemas al encontrarse con un sub grafo de la web que acta como sumidero. Si el grafo web contiene un sumidero (totalmente factible), una vez que navegamos dentro de l no podremos salir (de hecho los sumideros producen PageRank nulos para las pginas fuera del sumidero). Para resolver esta situacin se plantea una operacin adicional de teleportacin. La teleportacin se implementa jando un valor a las columnas nulas de hacia cualquier pgina del grafo web. Formalizando:

H,

modelando un salto aleatorio

Denicin 2.1.15.
la matriz

Sea la matriz

H Rnn

como en la denicin (2.1.13), entonces denimos:

A Rnn

cuyos valores sern nulos excepto para las columnas donde

sea nula, caso

en el que los elementos de la matriz

tomarn el valor

1/n.

S Rnn /S = H + A A representa una probabilidad uniforme de teleportarnos desde una pgina sumidero S es una nueva versin de H que S
y asegurarnos que el proceso sea tanto convergente

Vemos entonces que

hacia cualquier otra pgina del grafo web. En consecuencia, la matriz no sufre del problema de PageRank nulos debido a sumideros. Para poder utilizar el mtodo de las potencias con como correcto, necesitamos que

sea estocstica y primitiva (Austin, 2006). La condicin de estocstica

se cumple fcilmente porque la matriz cuenta con entradas positivas y la suma de sus columnas es unitaria. La condicin de primitiva requiere que para algn (esto se traduce en que luego de con probabilidad no nula). La solucin nal al problema se da introduciendo una dualidad en el comportamiento del navegante:

m se cumpla que Sm

tenga todas sus entradas positivas

iteraciones podremos navegar desde una pgina hacia cualquier otra

Denicin 2.1.16
matriz de Google:

(Google Matrix)

Sea la matriz estocstica

de la denicin (2.1.15), denimos la

G = S + (1 ) 1
con

[0, 1] . G
incorpora el conocimiento de probabilidades surgido de los enlaces del grafo web ms

La nueva matriz

un comportamiento aleatorio de teleportacin regulado por

(1 ).

El valor de

no slo tiene que ver

en el grado de aleatoriedad introducido al modelo de navegacin, sino que es responsable de la velocidad de convergencia del mtodo (esto se relaciona con el mtodo de las potencias y la magnitud del segundo autovalor de

S). G es una suma de matrices estocsticas, esta tambin lo es. Adicionalmente, G tambin es primitiva. Estas dos propiedades nos aseguran la I k+1 = GI k

Con esta denicin, dado que

como todas sus entradas son positivas,

convergencia por el mtodo de las potencias, permitindonos calcular el PageRank mediante la frmula:

(2.1.12)

En conclusin, PageRank es un modelo heurstico de puntajes con sustento en una matemtica rme que nos permite obtener un puntaje esttico dependiente de la estructura de enlaces del dominio (en este caso, pginas web). Los autores han calculado el PageRank para 322 millones de links aproximando por

I 52

obteniendo un mnimo margen de error (Page et al., 1998).

La explicacin que acabamos de dar muestra los conceptos y pasos ms importantes para su clculo. Nuestro inters en presentar PageRank es considerar estos conceptos para dar valor a la relacin entre objetos del dominio. En el captulo 3 se retomar este problema para analizar qu grado de soporte podemos dar a este tipo de tcnicas. Para profundizar acerca del clculo de PageRank se puede consultar (Austin, 2006).

2.1.

INFORMATION RETRIEV AL

41

HITS
Search).

Adems del PageRank que acabamos de estudiar, existen otros mtodos que tienen en cuenta

la estructura de links de las pginas web. Un mtodo muy conocido es HITS (Hyperlink-Induced Topic

Conceptualmente, este mtodo plantea que existen dos clases de pginas importantes: los hubs (concentradores) y

authorities

(autoridades, en el sentido de referente acerca de un tema). La propuesta es

entonces asignar a cada pgina un puntaje como hub y otro como authority. Las autoridades son pginas que contienen informacin de calidad acerca de un tema. Por ejemplo, si buscamos el trmino Ingeniera, algunas autoridades podran ser http://www..uba.ar (Facultad de Ingeniera de la UBA), http://www.ieee.org (IEEE) o http://www.cai.org.ar (Centro Argentino de Ingenieros). Por otro lado, existen pginas concentradoras que no son en si mismas una fuente nal de informacin sino que apuntan a autoridades mediante un listado de enlaces acerca de un tema (un directorio como los que vimos en la subseccin 2.1.5 sera un caso de concentrador). La heurstica que podemos aplicar para valorizar pginas es pensar que un buen concentrador apunta a

buenas autoridades y una buena autoridad es apuntada por buenos concentradores.


A continuacin mostramos brevemente el procedimiento matemtico para luego obtener el algoritmo HITS basndonos en el desarrollo propuesto en (Manning et al., 2008).

Denicin 2.1.17 (Puntaje de Hub y Authority).


denimos los puntajes hub

Dada una pgina como:

que enlaza a una pgina

yi /v yi ,

h (v)

y authority

a (v)

h (v) =
vyi

a (yi ) h (yi )
vyi
(Vector de Hub y Authority)

a (v) =

h = (h1 , . . . , hn )

Denicin 2.1.18
y

= (a , . . . , a ), a 1 n

Para una web de

pginas, denimos los vectores

donde cada componente de los vectores son los puntajes respectivos

de cada pgina como hub y authority.


Conceptualmente, una pgina incrementa su puntaje como concentrador si enlaza pginas con alto puntaje de autoridad. Recprocamente, una pgina es una buena autoridad cuando esta enlazada por buenos concentradores.

Denicin 2.1.19 (Matriz de Adyacencia).


Aij
vale uno si la pgina

Denimos la matriz de adyacencia

A,

donde la componente

enlaza a la pgina

y cero en otro caso.

Ahora estamos en condiciones de reescribir las ecuaciones de la denicin (2.1.17) utilizando la matriz de adyacencia:

h a

A a T A h

(2.1.13)

Dado que el trmino izquierdo de la ecuacin (2.1.13) forma parte del derecho, podemos proponer un clculo iterativo y reescribirla como:

h a
Si en la ecuacin (2.1.14) reemplazamos el signo autovectores de los autovectores

AAT h AT A a

(2.1.14)

por un =, entonces h y seran respectivamente los a

AA y A A . Utilizando este ltimo hallazgo reescribimos la frmula (2.1.14) asumiendo h y a :

42

CAPTULO 2.

ESTADO DEL ARTE

h a

= =

(1/h ) AAT h (1/ ) AT A a


a

(2.1.15)

Las actualizaciones iterativas de la frmula frmula (2.1.14) pueden ser escaladas por el autovalor apropiado, lo que equivale a utilizar el mtodo iterativo de las potencias para encontrar los autovectores de

AAT

valores

AT A (Manning et al., 2008). Dado que el autovector de h y a no solo son nicos sino que son estacionarios

principal de

AAT

AT A

es nico, los

y slo dependen la estructura de enlaces

de la web considerada (Manning et al., 2008). Cuando estudiamos PageRank vimos que dicha medida no dependa de la query en particular

10 , sin em-

bargo, para aplicar el concepto de concentrador y autoridades, el puntaje de Hubs y Authorities debe

calcularse para un tpico en particular. Para esto existe un paso adicional que implica seleccionar un
subconjunto de la web que es potencialmente concentradora o autoridad acerca de un tpico para luego generar vectores

respecto de dicho tpico. Existen distintas heursticas para elegir este subcon-

junto, las cuales exceden el tratamiento que queremos dar a este sistema de puntajes. Al igual que con PageRank, la combinacin de los puntajes entregados por el modelo de IR, reglas de negocio y el anlisis estructural (en este caso de enlaces) depende de la aplicacin particular. Para un anlisis exhaustivo acerca de HITS puede consultarse (Kleinberg, 1999).

Relevance Feedback y Query Log Mining


Las tcnicas de relevance feedback (en adelante tambin retroalimentacin o simplemente de RF ) buscan involucrar al usuario en el proceso de recuperacin para mejorar el conjunto nal de resultados (Manning

et al., 2008).
En general el ciclo de RF tiene los siguientes pasos:

1. El usuario especica una query simple 2. El sistema retorna un conjunto inicial de resultados 3. El usuario marca qu resultados son relevantes y cules no lo son 4. El sistema computa una nueva representacin de la necesidad del usuario y corrige el conjunto inicial efectuando una nueva recuperacin que tiene en cuenta la retroalimentacin.

Existen tcnicas de RF que requieren que el usuario indique explcitamente qu documentos son relevantes as como tcnicas menos intrusivas que se nutren de la relevancia implcita que surge de la interaccin con el sistema. Esos dos modelos se llaman respectivamente RF explcito y RF implcito.

RF Explcito y Algoritmo de Rocchio


pasos:

Dentro del modelo vectorial de IR, Rocchio propuso un

algoritmo que reformula la query del usuario buscando mejorar su efectividad (Rocchio, 1971). Este algoritmo utiliza la clasicacin explcita de relevancia provista por los usuarios y comprende los siguientes

1. El usuario inicia la bsqueda con una query inicial

q Dr
para documentos rel-

2. El usuario clasica los resultados explcitamente, creando dos conjuntos: evantes y

Dnr

para los no relevantes

3. El sistema expande la query inicial

en una nueva query

qopt

10 Existen

adaptaciones que calculan el PageRank para tpicos particulares.

2.1.

INFORMATION RETRIEV AL

43

Los conjuntos

Dr

Dnr

son una aproximacin de los verdaderos conjuntos

Rq

Rq

(relevantes y no

relevantes). Si conociramos estos ltimos y asumiendo un modelo vectorial de IR, tendramos que buscar acercar la query

al centroide del conjunto

Rq ,

alejndolo del centroide de

Rq .

Esto equivale a resolver

el problema de optimizacin:

= arg mx Similitud (q, R ) Similitud q, R q a opt q q


q
Bajo la frmula de similitud del coseno, la separacin ptima se da cuando (Manning et al., 2008):

1 = arg mx qopt a |R | q q

dj

dj Rq

1 Rq

dj Rq

dj

(2.1.16)

El algoritmo propuesto por Rocchio vara la frmula (2.1.16) para tener en cuenta que no conocemos los conjuntos

Rq

Rq

sino que tenemos sus aproximaciones

Dr

Dnr .

Teniendo esto en cuenta llegamos a

la frmula:

= + q q0 opt |Dr |
Donde

dj

dj Dr

|Dnr |

dj

(2.1.17)

dj Dnr

(, , ) [0, 1] [0, 1] [0, 1] / + + = 1, q0

es la query inicial del usuario y

q opt

es un

estimador de la query ptima de la ecuacin (2.1.16). En los casos en los que un componente de resulta negativo, ste se ignora (es decir, se iguala a cero). La frmula (2.1.17) produce una mezcla entre la query inicial de

q
opt

y los trminos presentes en los documentos q0

Dr

Dnr .

Es decir, si los documentos relevantes para la query glaciares suelen contener el trmino

antrtida, entonces la versin modicada de la query dar mayor exposicin a los documentos acerca de este ltimo trmino. Hagamos algunas consideraciones prcticas acerca de este mtodo: En la prctica se ha encontrado que el feedback positivo (asignacin de documentos a utilidad que el feedback negativo (asignacin a

Dr )

es de mayor

Dnr )

(Manning et al., 2008). Si queremos ajustar la

frmula (2.1.17) para reejar este hecho, debemos escoger Tambin debemos notar que normalmente

0. dj
agregar poten-

q0

tiene pocos trminos, mientras que

cialmente muchos trminos a la nueva query (adems de que estamos agregando varios documentos, stos tienden a ser ms largos que las queries). Al agregar trminos debemos efectuar ms accesos al ndice invertido, lo cual seguramente degrade el rendimiento del sistema. Para contener este problema podemos expandir la query solo con los

trminos de mayor score en

dj .

RF Indirecto y Query Log Mining

Comnmente los usuarios buscan satisfacer sus necesidades de

informacin en el menor tiempo posible, siendo muy difcil que se detengan a proveer feedback explcito sobre los resultados (sobre todo cuando los benecios de hacerlo no son claros). Para poder obtener feedback en un contexto donde el usuario no provee una clasicacin explcita, tenemos que modelar las acciones del usuario como actos de clasicacin. Este modelado se traduce en interpretar como seales de relevancia la concentracin de clics en ciertos resultados o nodos de una taxonoma. Por otro lado, podemos interpretar hechos como abandono de la sesin, inactividad por periodos extensos, reformulacin sistemtica de queries o bajo CTR (click-thru

rate o tasa de clics sobre impresiones ) como seales de ausencia de resultados relevantes.
El mtodo de inferir la clasicacin utilizando la actividad indirecta del usuario se conoce como RF

implcito o indirecto.
En la prctica, los mtodos derivados del RF indirecto son menos conables que los del RF explcito, donde el usuario juzga explcitamente los documentos (Manning et al., 2008). Esto es intuitivo ya que siempre que haya un uso honesto de la herramienta, los juicios explcitos de relevancia tienen mayor delidad que un modelado mediante timeouts, abandonos y CTR.

44

CAPTULO 2.

ESTADO DEL ARTE

Para efectuar el RF indirecto necesitamos tcnicas de anlisis del ujo de queries (tambin conocido como

query log analysis o clickstream mining ). Estos logs deben ser sucientemente expresivos para permitirnos
modelar el uso del sistema. Es decir, si vamos a trabajar con medidas de CTR, debemos poder ordenar los registros secuencialmente por usuario, lo que requiere contar con marcas de tiempo, identicadores de sesin y la accin que efectu el usuario. Los logs de queries tambin tienen usos que van mas all del relevance feedback como ser la generacin de tesauros, anlisis de uso del sistema, etc. En nuestra propuesta del captulo 3 retomaremos este tema para analizar cmo se puede incluir este tipo de herramientas al hacer IR sobre objetos.

En este punto hemos completado la descripcin necesaria del estado del arte en cuanto a Recuperacin de Informacin. Sobre el nal de este captulo (seccin 2.4), retomaremos estos temas para describir y comparar las herramientas del estado del arte, profundizando nuevamente durante los captulos de desarrollo de la propuesta y experimentacin.

2.2.

Modelos de Dominio

Esta segunda seccin trata la segunda componente de nuestro problema: el diseo de software. Dado que estamos interesados en generar un framework de indexacin y recuperacin, es necesario que establezcamos bases objetivas sobre las cuales analizar las alternativas de diseo y construir nuestra propuesta. La subseccin 2.2.1 presenta los conceptos sobre los que tratar esta seccin: modelos de dominio, frame-

works, arquitecturas empresariales y patrones de arquitectura. Luego de sentar estas bases, en las subsecciones (2.2.2) y (2.2.3) profundizamos acerca de criterios de implementacin.

2.2.1. Deniciones Generales


Las prximas subsecciones hablan de frameworks (qu son, tipos y caractersticas), arquitecturas em-

presariales (sobre las cuales vamos a obtener el mayor provecho del motor de bsqueda sobre objetos), patrones de diseo y arquitectura (los que utilizaremos como conocimiento de base para discutir criterios e
implementaciones) , modelos de dominio (patrn de arquitectura utilizado para construir las aplicaciones que vamos a indexar), inversin del control e inyeccin de dependencias (tcnicas que diseo que tienen consecuencias sobre los frameworks como el que queremos construir).

Frameworks y Libreras
Para proponer el framework de indexacin de objetos, primero debemos preguntarnos qu es un framework.

Denicin 2.2.1

(Framework)

Un framework es un conjunto de clases que encarnan un diseo ab-

stracto para solucionar una familia de problemas relacionados soportando reutilizacin en una mayor granularidad a la de las clases (Johnson y Foote, 1988).
Un framework nace a partir de la observacin y aprendizaje de un dominio de problema particular (Roberts y Johnson, 1996). La experiencia acumulada en un dominio de problema nos permite generalizar y crear abstracciones que resolvern un problema concreto. Por ejemplo: persistencia, rendering, remotizacin o indexacin. A continuacin clasicamos los frameworks en dos clases principales: caja negra y caja blanca (Johnson y Foote, 1988; Roberts y Johnson, 1996). El tipo de framework en el que debemos proveer el comportamiento especco de nuestra aplicacin mediante subclasicacin es conocido como de framework de caja blanca. Para dar el comportamiento propio de nuestra aplicacin, debemos subclasicar clases del framework, implementando mtodos en

2.2.

MODELOS DE DOMINIO

45

forma polimrca. Los frameworks de caja blanca no pueden ser utilizados directamente sino que requieren que creemos clases especcas para utilizarlos. Este proceso de creacin de clases requiere que tambin sepamos cmo funciona el framework, por lo que son ms difciles de aprender (respecto de los de caja negra que explicaremos en el prximo prrafo). Dos ejemplos de frameworks de caja blanca podran ser (a) servlets de Java y (b) variantes del MVC en las que aportamos nuestro comportamiento especco extendiendo una clase Controller. Por otro lado, existen frameworks en los cuales la comunicacin se da mediante componentes que entienden un protocolo especco. Estos frameworks son los de caja negra. El usuario de este tipo de framework provee comportamiento a travs de colaboracin entre objetos. Los frameworks de caja negra no requieren de la subclasicacin, por lo que introducen menor acoplamiento y requieren menor conocimiento acerca de cmo est construido el framework . En los frameworks de caja blanca, el estado de cada instancia se encuentra implcitamente disponible a todos los mtodos del framework como si fueran variables globales, mientras que en los de caja negra, los parmetros se deben declarar e intercambiar explcitamente. Adems, los frameworks de caja blanca implementan reglas internas la jerarqua de subclasicacin, mientras que en los de caja negra las reglas son protocolares. La madurez de un framework est dada por una transicin que comienza con frameworks de caja blanca hasta convertirse en un diseos reusables de caja negra (Roberts y Johnson, 1996). Es importante poder distinguir un framework de una librera. Fowler dene una librera como un conjunto de funciones (hoy en da organizadas en clases) a las que uno puede llamar para luego retomar el ujo de control (Fowler, 2005). Segn Fowler, la diferencia principal entre una librera y un framework es la

inversin de control (ver subseccin 2.2.3).


En esta seccin comentaremos algunos aspectos relacionados con los frameworks, para luego retomar el tema al analizar los casos de estudio (subseccin 2.4) y el comportamiento como framework de la propuesta de solucin.

Aplicaciones Empresariales
Las aplicaciones empresariales, tipo enterprise enterprise applications son uno de los distintos tipos de sistemas posibles de construir. Este tipo de aplicaciones se desarrollan para soportar la actividad de una organizacin, ya sea ejecutando directamente el negocio o soportando sus procesos y ujos de trabajo. Las aplicaciones de este tipo se denen por ciertas caractersticas: Envergadura: suelen ser grandes, costosas de construir y mantener; requieren de un equipo de trabajo dedicado. Poseen mltiples pantallas para interactuar con usuarios. El volumen de informacin procesada y almacenada es relativamente grande. Transversales: interconectan procesos y datos de distintas reas y departamentos de la organizacin (Ej: contable, legal, atencin al cliente, etc). Integradores: suelen interconectar sistemas heterogneos (de mltiples vendedores) y heredados. Concurrentes y Distribuidos Clusterizados: soportan el acceso de mltiples usuarios concurrentes y pueden estar distribuidos geogrcamente o clusterizados para soportar altos niveles de concurrencia. Transaccionales: suelen funcionar realizando transacciones sobre un RDBMS. Multicapa: requieren un diseo de mltiples capas (tier

11 ).

Multiperl: hay usuarios y roles diferenciados (Ejemplo: usuarios frontend que utilizan el sistema y usuarios backend que lo administran). Seguridad y Certicacin: al ser sistemas abiertos y que operan con datos sensibles se disean con la seguridad en mente. Dependiendo de las caractersticas de la organizacin, el diseo del sistema puede estar sujeto a certicacin de normas como SOX (SOX, 2002) y/o PCI (PCI, 2006).

11 La

traduccin de capa es layer y no tier (cuya traduccin es feta). Sin embargo, a menos que sea necesario

distinguir entre tiers y layers, utilizamos los trminos de manera intercambiable.

46

CAPTULO 2.

ESTADO DEL ARTE

Algunos ejemplos de sistemas empresariales:

reserva online de tickets areos, banca electrnica, voto electrnico, tienda online de productos electrnicos, sistemas de atencin al pblico

Ejemplos de sistemas que no son enterprise:

juegos, compiladores, suites de dibujo y animacin, navegador web

Estamos especialmente interesados en indexar los objetos de aplicaciones enteprise por las siguientes razones:

El volumen de informacin da lugar a la necesidad de hacer bsquedas de texto libre, tienen diversidad de entidades, favoreciendo la necesidad de hacer bsquedas horizontales sobre los datos (multi esquema), tienen requerimientos particulares en materia de seguridad y distribucin.

Vemos entonces que, siendo nuestro framework un husped de este tipo de aplicaciones, el motor de bsqueda que construiremos debe funcionar en sintona con estos requerimientos.

Patrones de Diseo y Arquitectura


Para comenzar con este apartado, recordemos la denicin de patrn de diseo :

Denicin 2.2.2 (Patrn de Diseo).

Son descripciones de objetos y clases comunicadas que se person-

alizan para resolver un problema general de diseo en un contexto particular (Gamma et al., 1995). Ampliando esta denicin, podemos decir que los patrones de diseo son soluciones reutilizables y probadas para problemas recurrentes en el diseo de software.
As como los patrones de diseo solucionan problemas de diseo comunes del desarrollo de software, existen problemas recurrentes desde el punto de vista de la estructura o arquitectura de un sistema, los cuales tambin pueden ser resueltos aplicando soluciones estndar. Una pregunta importante que surge al analizar los patrones de arquitectura es Qu es la arquitectura

de un sistema ?
Lo que caracteriza a la arquitectura de un sistema es (Fowler, 2002):

las decisiones de alto nivel acerca de cmo dividir una aplicacin en partes, las deniciones acerca de las bases de una aplicacin, decisiones que uno quiere tomar lo antes posible, elecciones difciles de cambiar una vez establecido el patrn de arquitectura, tienen efectos a largo plazo en el diseo,

2.2.

MODELOS DE DOMINIO

47

deniciones que eventualmente determinan qu responsabilidades se asignan a cada parte de la aplicacin.

En base a los puntos anteriores se catalogan soluciones bien conocidas en un conjunto amplio de escenarios llamados patrones de arquitectura. Como vemos, no es fcil denir con precisin qu es arquitectura en una aplicacin ni tener la ltima palabra acerca de si un patrn cumple con los puntos enumerados anteriormente. Lo que hoy cumple con estos criterios puede dejar de hacerlo (por ejemplo, siendo simple de modicar) y plantearnos la duda acerca de si realmente era una decisin de arquitectura. Los patrones que reunen mayor consenso acerca de su pertenencia a esta clase son: patrones de lgica

de dominio (domain model, table module y transaction script ), el service layer, la arquitectura en layers
y los de patrones de presentacin (model view controller y front controller ). Seguramente los patrones que tratan acerca de cmo mantener conversaciones con los medios de persistencia tambin pueden considerarse patrones de arquitectura: Table Data Gateway, Row Data Gateway, Active Record y Data

Mappers.
As como originalmente los patrones de diseo fueron clasicados en creacionales, estructurales y de comportamiento (Gamma et al., 1995), los patrones arquitecturales pueden clasicarse segn el tipo de problema que resuelven o la capa de la aplicacin donde aplican (Fowler, 2002). En el prximo apartado se trata el patrn de arquitectura domain model, el cual constituye una parte fundamental del problema a resolver ya que sus miembros (objetos de negocio) son los objetivos a indexar por el motor de bsqueda.

Modelos de Dominio
En el captulo 1 denimos la nocin de modelo de dominio por Fowler y luego enunciamos una versin algo ms rigurosa. Vamos a repasar brevemente la segunda denicin que representa mejor nuestras convicciones:

Domain Model

es un diseo de objetos que representa un dominio de problema de la realidad.

Este enfoque nos permite ver a los objetos como verdaderos modelos de entes de un dominio de problema. Para cerrar esta denicin profundizamos sobre las nociones de dominio de problema y realidad :

Realidad

comprende cualquier tipo de idea que podamos concebir (un objeto concreto, el amor, el odio,

la nada, etc).

Dominio de problema

es una porcin de la realidad que vamos a modelar.

Algunos ejemplos de dominios de problema podran ser las cuentas bancarias, un lesystem o la sincronizacin entre procesos. Los modelos de dominio no son un concepto nuevo en el diseo de software, sino que implementan las premisas bsicas del diseo orientado a objetos. Dentro de un dominio particular se efecta un anlisis segn el cual se modelan entes de negocio junto a sus responsabilidades, protocolo y colaboraciones. En un domain model encontraremos objetos como productos, personas, pagos, pginas web, etc. El contexto de arquitecturas empresariales, Fowler propone al domain model como un patrn de arqui-

tectura. Las alternativas en dicho contexto son el transaction script y el table module (Fowler, 2002). A
continuacin vamos a ejemplicar construyendo un pequeo modelo de dominio:

Ejemplo 2.2.1.

En este ejemplo presentamos un modelo de dominio para una aplicacin que implementa

una red de contactos. Este modelo incluye las entidades fundamentales, sus relaciones y su comportamiento no trivial (esto es, excluimos operaciones como los set y get de atributos).

48

CAPTULO 2.

ESTADO DEL ARTE

Figura 2.9: Modelo de Dominio para una red social.

En este ejemplo se modelaron entidades de inters para el negocio junto con las operaciones que son necesarias. Veamos que la relacin entre clases puede afectar la manera en la que un motor de bsqueda presentara los resultados de una consulta. Por ejemplo, ante la bsqueda Viaje a Pars podemos priorizar los objetos

Story

que han sido ms votados entre los usuarios o los

PhotoAlbum

aparezcan fotos de Pars.

Es preciso mencionar algunos aspectos relacionados al comportamiento de los objetos:

Los modelos de dominio implementan las reglas de negocio de la aplicacin. Estas reglas de negocio entran en accin al ejecutar servicios de negocio lgica de aplicacin. Estos servicios de negocio son ejecutados por consumidores clientes del negocio. Para desacoplar los consumidores del modelo mismo, es posible utilizar el patrn Service Layer (Fowler, 2002). El service layer presenta una API bien denida hacia los consumidores, actuando como un Faade (Gamma et al., 1995). Una variante de esta implementacin de interfaz na entre los consumidores y el modelo es cuando el service layer acta como objeto de negocio, orquestando la secuencialidad en la invocacin de los objetos de dominio. En la gura (2.10) vemos grcamente cmo se organizan estas capas.

>resU<tsiL :sihTsekiltnetnoc-*

de contactos donde

yrotS

noitacilppAiniM

)(dne+ )(trats+

atsug el

azilitu

nicacilbup eliforP :eliforp>mublAotohP<tsiL :smublAotohp>noitacilppA<tsiL :sppa- * >yrotS<tsiL :seirots*

etaD :noitaerc>egamI<tsiL :tsiLegami-

1 1

mubl AotohP

resU

*
*

otcatnoc 1 * >resU<tsiL :sresUdeggateltitodateuqite 1

egamI

eliforP

stseretniboj-

2.2.

MODELOS DE DOMINIO

49

Figura 2.10: Organizacin de capas en una aplicacin enterprise con Service Layer, Domain Model y Data Access Layer.

Habiendo comentado acerca de los datos y comportamiento en un modelo de dominio, podemos adelantarnos al anlisis del problema y decir que, a los efectos del motor de bsqueda que vamos a construir, nos interesa el estado de los objetos (valores de los atributos persistentes de la instancia) y no su com-

portamiento (mtodos de la clase).


Los modelos de dominio expresan relaciones entre objetos por medio de subclasicacin y colaboraciones. Estas dos relaciones deben ser tenidas en cuenta en la recuperacin de objetos ya que introducen complejidades que no estn presentes en sistemas clsicos de IR. Tanto la subclasicacin como las colaboraciones presentan situaciones ante las que debemos decidir cmo indexar los objetos. Veamos algunas de ellas: Consolidacin de la Jerarqua: cuando se indexa un objeto cuya jerarqua dene mltiples atributos, es necesario consolidar la lista de los atributos indexables de dicha jerarqua. Relaciones Todo-Parte: si un objeto de tipo Persona contiene un objeto indexable de tipo Nombre, al efectuar una bsqueda que produce una coincidencia en los atributos de la clase Nombre, posiblemente queramos recuperar el objeto de tipo Persona. Este problema se maniesta en relaciones todo-parte, donde las partes son indexables pero el objeto recuperable es el todo. Colecciones: si tenemos una clase Receta que contiene una lista de objetos Ingrediente, probablemente estemos interesados en indexar los objetos de la lista pero no la lista en s misma. Para esto es necesario diferenciar las colecciones de las relaciones todo-parte del caso anterior. Referencias Circulares: si distintos objetos se referencian entre s, debemos cuidar que la indexacin no caiga en bucles innitos. Identidad. para que un objeto indexable pueda ser hidratado

12 debe proveer una identidad. En

ocasiones esta identidad es un objeto complejo en s mismo. Cuando esto sucede, si el motor de bsqueda necesita interactuar con el ORM para hidratar el objeto, debe ser capaz de almacenar la clave de forma de poder reconstruirla al momento de recuperarlo. Para resolver las tareas que estuvimos mencionando, es necesario que el lenguaje de programacin cuente con capacidades de meta programacin. En el caso del lenguaje en el cual desarrollaremos nuestro framework (Java), la meta programacin est mayormente soportada mediante reection.

12 La hidratacin

de un objeto del ndice consiste en completar su contenido, el cual a priori slo contiene su clave principal,

con el resto de sus atributos. Este concepto lo revisaremos apropiadamente en las prximas secciones.

50

CAPTULO 2.

ESTADO DEL ARTE

Estos ltimos prrafos son una primera muestra de los problemas que aparecen al considerar la indexacin de objetos cuya estructura y relaciones son de mayor riqueza que la del texto plano. La respuesta acerca de cmo resolver estos problemas se diere hasta el captulo 3, donde haremos propuestas concretas teniendo tambin en cuenta las soluciones aportadas por los casos de estudio (seccin 2.4).

2.2.2. Independencia del Modelo de Dominio


A medida que evolucionan las necesidades del negocio, el modelo de dominio deber reejar los cambios en ste. Dichos cambios generan la necesidad de actualizarlo y probarlo aisladamente. Estas dos actividades requieren el desacoplamiento entre el modelo de dominio y otras capas del sistema (Dahan, 2009). Para entender mejor el problema veamos un caso concreto: en una aplicacin enterprise la capa de presentacin puede ser especialmente voltil. Supongamos que con el paso del tiempo cambiamos nuestro framework de presentacin, dejando de lado tecnologas de reemplazos de strings para pasar a herramientas como JSP. Si nuestro modelo de dominio es independiente, seguramente no tendremos mayores problemas en migrar. Ahora, si nuestro modelo estaba acoplado a las vistas, la tarea de migracin requerir un esfuerzo de desacoplamiento. Para este caso, si la lgica de negocio fue mezclada con la lgica de presentacin, generar una nueva vista (por ejemplo para dispositivos mviles) requerir migrar cdigo que no estuvo correctamente encapsulado. Los conceptos subyacentes en el ejemplo anterior son la cohesin y desacoplamiento, quienes favorecen la reutilizacin y

portabilidad del modelo. Para lograr estas premisas, necesitamos que los frameworks

que interactan con el modelo permitan la independencia del modelo. A los efectos del motor de bsqueda que plantearemos en el captulo 3, la independencia del modelo es un aspecto que queremos respetar para ser buenos ciudadanos en el mundo de los frameworks. A continuacin vemos distintos ejemplos donde aparecen dependencias entre el modelo y los frameworks que componen la aplicacin:

Ejemplo 2.2.2.

Tomando el modelo de dominio del ejemplo (2.2.1), presentaremos una porcin de cdigo

dependiente del esquema de persistencia y otro independiente:

public c l a s s
/
/

User {

// a t r i b u t o s , get , s e t . . . En e s t e mtodo s e i n t r o d u c e n d e p e n d e n c i a s e n t r e e l d o m i n i o y e l framework de p e r s i s t e n c i a . E x i s t e un f u e r t e a c o p l a m i e n t o e n t r e e l modelo de d o m i n i o y e l esquema de b a s e de d a t o s y l a d e m a r c a c i n de t r a n s a c c i o n e s . i n s e r t ()

public void try {

throws

ModelPersistException {

TransactionManager . s t a r t T r a n s a c t i o n () ; M y S q l I n s e r t i n s e r t = new M y S q l I n s e r t ( "INSERT INTO SOCIALNET . USER VALUES ( ? , ? , ? , ? ) " ) ; P r o f i l e prof = getProfile () ; i f ( p r o f == n u l l ) prof . i n s e r t () ; ... i n s e r t . execute () ; T r a n s a c t i o n M a n a g e r . commit ( ) ; } catch ( P e r s i s t E x c e p t i o n e ) { TransactionManager . r o l l b a c k () ; throw new M o d e l P e r s i s t E x c e p t i o n ( "No f u e p o s i b l e i n s e r t a r e l u s u a r i o " , e) ; }

2.2.

MODELOS DE DOMINIO

51

public c l a s s U s e r S e r v i c e L a y e r { public void addUser ( UserDTO dto ) throws B u s i n e s s E x c e p t i o n { try { U s e r u = new U s e r ( dto . getName ( ) , dto . g e t E m a i l ( ) , new P r o f i l e ( dto .

g e t P r o f i l e I n f o () ) ) ; user . i n s e r t () ; } catch ( M o d e l P e r s i s t E x c e p t i o n mpe ) { throw new B u s i n e s s E x c e p t i o n ( " E r r o r a l i n s e r t a r e l u s u a r i o " + u + " a p a r t i r d e l DTO " + dto , mpe ) ; }

En el caso anterior introdujimos responsabilidades sobre el modelo de dominio que lo acoplaron respecto del esquema y motor de bases de datos as como la demarcacin de transacciones. En el siguiente ejemplo utilizamos un motor de persistencia que se responsabiliza de estos tres factores, dejando al modelo de dominio desacoplado de ellos:

public c l a s s public
}

User { // a t r i b u t o s , get , s e t U s e r ( S t r i n g name , S t r i n g e m a i l , P r o f i l e p r o f i l e ) { setEmail ( email ) ; setName ( name ) ; setProfile ( profile ) ;

public c l a s s U s e r S e r v i c e L a y e r public void addUser ( UserDTO try {

{ dto )

throws

BusinessException {

PersistenceFrameworkSession pfs = PersistenceFrameworkFactory . getSession () ; U s e r u = new U s e r ( dto . getName ( ) , dto . g e t E m a i l ( ) , new P r o f i l e ( dto . g e t P r o f i l e I n f o () ) ) ; pfs . startTransaction () ; pfs . save (u) ; p f s . commit ( ) ; } catch ( M o d e l P e r s i s t E x c e p t i o n mpe ) { pfs . rollback () ; throw new B u s i n e s s E x c e p t i o n ( " E r r o r a l i n s e r t a r e l u s u a r i o " + u + " a p a r t i r d e l DTO " + dto , mpe ) ; }

La preocupacin acerca de la independencia del modelo suele surgir en el contexto de modelos que interactan con frameworks. En los de caja blanca debemos esperar una baja independencia del modelo, ya que estamos obligados a subclasicar. Por el contrario, en los frameworks de caja negra contamos con un encapsulamiento que nos garantiza un mayor grado de independencia.

2.2.3. Inversin del Control e Inyeccin de Dependencias


La inversin de control y la inyeccin de dependencias son dos aspectos que han ganado gran aceptacin ya que ayudan a desacoplar servicios, generalizar implementaciones y facilitar las pruebas unitarias.

52

CAPTULO 2.

ESTADO DEL ARTE

La inyeccin de dependencias nace en el contexto del consumo de servicios por parte de un cliente. Un problema comn en el desarrollo de aplicaciones enterprise es cmo atar (tambin llamado wiring ) los componentes para que cooperen entre s (Fowler, 2004). Veamos un ejemplo:

Ejemplo 2.2.3.
1 2 3 4 5 6 7 8 9 10 11 12 13 14

En este ejemplo se presenta el problema del wiring de componentes. El siguiente cdigo

no utiliza inyeccin de dependencias:

public c l a s s I n d e x e r { public i n d e x ( Document P a r s e r p a r s e r = new

document ) { TextParser () ; I n d e x W r i t e r w r i t e r = new S q l I n d e x W r i t e r ( ) ; T e x t N o r m a l i z e r n o r m a l i z e r = new S p a n i s h T e x t N o r m a l i z e r ( ) ;

L i s t <S t r i n g > t o k e n s = p a r s e r . p a r s e ( document . g e t T e x t ( ) ) ; = document . getDocumentID ( ) ; token : tokens ) { S t r i n g normalizedToken = n o r m a l i z e r . normalize ( token ) ; w r i t e r . w r i t e ( docId , n o r m a l i z e d T o k e n ) ; }

long d o c I d for ( S t r i n g

En las lneas 3,4 y 5 se instancian explcitamente clases que se ocupan de interpretar, normalizar y almacenar las palabras de un documento a indexar. En esta implementacin, una vez compilado el programa, no se permite variar la implementacin de los servicios

Parser, IndexWriter

TextNormalizer.

Para resolver los problemas respecto de cmo desacoplar el consumidor de un servicio respecto del implementador, se utilizan tcnicas de inyeccin de dependencias. Estas tcnicas consisten en utilizar un componente externo que se ocupa de inyectar el implementador del servicio en el consumidor.

Ejemplo 2.2.4.

En este ejemplo resolvemos el problema del ejemplo (2.2.3) utilizando buenas prcticas

de inyeccin de dependencias:

public c l a s s I n d e x e r { private P a r s e r p a r s e r ; private I n d e x W r i t e r w r i t e r ; private T e x t N o r m a l i z e r n o r m a l i z e r ; public void public void public void
setParser ( Parser parser ) { this . parser = parser ;} setIndexWriter ( IndexWriter writer ) { this . writer = writer ;} setTextNormalizer ( TextNormalizer normalizer ) { this . normalizer = normalizer ;}

// g e t s p a r a l o s a t r i b u t o s . . .

public void

i n d e x ( Document document ) { L i s t <S t r i n g > t o k e n s = p a r s e r . p a r s e ( document . g e t T e x t ( ) ) ; long d o c I d = document . getDocumentID ( ) ; for ( S t r i n g t o k e n : t o k e n s ) { S t r i n g normalizedToken = n o r m a l i z e r . normalize ( token ) ; w r i t e r . w r i t e ( docId , n o r m a l i z e d T o k e n ) ; }

public c l a s s B u s i n e s s W o r k f l o w { public s t a t i c void main ( S t r i n g [ ]

args ) { W i r i n g F a c t o r y wf = WiringFramework . g e t F a c t o r y ( " i n j e c t i o n . xml " ) ;

Document doc = Document . r e a d ( "mydoc . t x t " ) ;

2.2.

MODELOS DE DOMINIO

53

I n d e x e r i d x = ( I n d e x e r ) wf . g e t I n s t a n c e ( " i n d e x e r " ) ; i d x . i n d e x ( doc ) ;

Archivo

injection.xml:

< i n j e c t i o n> <w i r i n g i d=" i n d e x e r " c l a s s="com . mydomain . s e r v i c e s . I n d e x e r "> <p r o p e r t y i n j e c t i o n p r o p e r t y=" p a r s e r " i m p l="com . mydomain . p a r s e r . S p a n i s h P a r s e r "/> <p r o p e r t y i n j e c t i o n p r o p e r t y=" w r i t e r " i m p l="com . mydomain . i n d e x . w r i t e r . S q l I n d e x W r i t e r "/> <p r o p e r t y i n j e c t i o n p r o p e r t y=" n o r m a l i z e r " i m p l="com . mydomain . i n d e x . t e x t . S p a n i s h N o r m a l i z e r "/> </ w i r i n g> </ i n j e c t i o n>
En este ejemplo utilizamos una clase

injection.xml

WiringFactory

que se ocupa de leer el archivo de conguracin

para hacer el wiring de los objetos. Con este esquema desacoplamos el servicio de quien lo

implementa, facilitando la eleccin dinmica de la implementacin y el testeo unitario.


En el ejemplo (2.2.4) utilizamos la inyeccin de los servicios mediante atributos de la clase. Esto tambin se puede llevar a cabo inyectando las dependencias en el constructor. La eleccin entre un mtodo y otro se basa en criterios acerca de si es correcto construir un objeto que no tiene resueltas sus dependencias (de hecho no lo es, por lo que este criterio favorece el mtodo de inyeccin en constructor) versus la posibilidad de reinyectar las dependencias sobre un objeto construido (variando su comportamiento en tiempo de ejecucin). Esta discusin aparece en (Spring, 2008). Adems de la inyeccin de dependencias, otra prctica que utilizaremos en la construccin del motor de bsqueda es la inversin de control (tambin conocido como inversion of control IoC ). La inversin del control se basa en poner el locus de control en el framework que se est utilizando y dejar que la lgica de aplicacin sea llamada cuando es necesario. Esto se conoce como el hollywood principle:

Don't call us, we'll call you (Johnson y Foote, 1988). El IoC se complementa con la inyeccin de
dependencias. Por ejemplo, si tenemos un framework que implementa un motor de bsqueda, podemos inyectar plugins en forma de dependencias, lo que permitir extender la forma en la que el motor de bsqueda procesa los documentos. Veamos un ejemplo:

Ejemplo 2.2.5.
/

A continuacin se utiliza inyeccin de dependencias e inversin del control para auditar

qu documentos se indexan.

E s t a c l a s e implementa l a i n v e r s i n de c o n t r o l l l a m a n d o a t o d o s l o s r e g i s t r a d o s p a r a r e c i b i r l a n o t i f i c a c i n de un nuevo documento i n d e x a d o /

manejadores

public c l a s s

NewIndexEventHandler

implements

EventHandler {

// c o n s t r u c t o r , a t r i b u t o s y mtodos p a r a m a n e j a r // l o s e v e n t o s de un nuevo documento que s e i n d e x a . .

private

L i s t <D o c u m e n t I n d e x L i s t e n e r > l i s t e n e r s = D o c u m e n t I n d e x L i s t e n e r >() ;

new

ArrayList <

// con e s t e mtodo s e r e g i s t r a n q u i e n e s s e r n l l a m a d o s a l o c u r r i r un evento public void r e g i s t e r N e w L i s t e n e r ( D o c u m e n t I n d e x L i s t e n e r n e w L i s t e n e r ) { t h i s . l i s t e n e r s . add ( n e w L i s t e n e r ) ; }

54

CAPTULO 2.

ESTADO DEL ARTE

// d e s p a c h a l o s e v e n t o s implementando l a i n v e r s i n de c o n t r o l public void h a n d l e E v e n t ( ) { Document d = getDocument ( ) ; EventContext ctx = getIndexContext () ; L i s t <D o c u m e n t I n d e x L i s t e n e r > l i s t e n e r s = g e t L i s t e n e r s ( ) ; indexer . index (d) ;

for ( D o c u m e n t I n d e x L i s t e n e r
} } }

dil : listeners ) { d i l . onDocumentIndex ( d , c t x ) ;

public c l a s s
}

Indexer { // como en e l e j e m p l o p r e v i o , s l o que cuando i n d e x a un documento a v i s a a l NewIndexEventHandler

// e s t a c l a s e hace l a a u d i t o r i a de cada nuevo documento que i n g r e s a a l ndice public c l a s s F i l e A u d i t L o g g e r implements D o c u m e n t I n d e x L i s t e n e r { public S t r i n g onDocumentIndex ( Document doc , E v e n t C o n t e x t c t x ) { // e s c r i b i r a un a r c h i v o l o s d a t o s i m p o r t a n t e s } }
En este ejemplo el control lo tiene un hilo de ejecucin que recibe el evento de indexacin y sabe (por conguracin externa) que debe instanciar un

NewIndexEventHandler,

programado para orquestar el resto o el

de los pasos. En este ejemplo se ve claramente que es fcil crear tests unitarios ya que podemos utilizar objetos mock (Mackinnon et al., 2001) que simulan ser el

NewIndexEventHandler

FileAuditLogger.

Estos breves ejemplos muestran benecios de las tcnicas de inyeccin de dependencias e inversin de control. Dichos benecios harn que las utilicemos en la construccin del framework de bsqueda e indexacin de objetos.

2.3.

Persistencia de Modelos de Dominio

Information Retrieval y Persistencia


En sistemas de IR como los buscadores web, los documentos estn persistidos de manera que son recuperables tanto por el proceso indexador del motor de bsqueda como por el browser que utiliza el usuario. Cuando los documentos son objetos de una aplicacin el panorama no es distinto: necesitamos accederlos para indexarlos y visualizarlos. Si calculramos puntajes estructurales como PageRank, tambin necesitaramos acceder a los objetos para calcularlo. Adicionalmente, la eliminacin de objetos se debera reejar eventualmente en los ndices del motor de bsqueda para no recuperar objetos innecesarios y degradar su rendimiento. Por estas razones, para llevar a cabo las actividades del motor de bsqueda, necesitaremos interactuar con el mecanismo de persistencia que utiliza la aplicacin para sincronizar el ndice con el estado de la aplicacin. La interaccin entre el sistema de persistencia y el motor de bsqueda puede ser:

Manual

(estilo librera)

el programador indica que se debe invocar al motor de bsqueda luego

de interactuar con el ORM.

2.3.

PERSISTENCIA DE MODELOS DE DOMINIO

55

Automtica

(estilo framework)

el motor de bsqueda intercepta los eventos CRUD

13 generados

por la aplicacin y delega en el usuario si es necesario. El modelo manual es simple de implementar ya que slo requiere que el motor de bsqueda exponga una API genrica hacia las aplicaciones. Esa simplicidad redunda en una solucin de bajo nivel, cuyos costos asociados sern cdigo duplicado y los errores propios de ste. El modelo automtico requiere poder suscribirse a los eventos CRUD manejados por la herramienta de persistencia, lo que requiere proveer conectores especcos.

Organizacin de esta Seccin


Las siguientes subsecciones explican brevemente los distintos mecanismos de persistencia del lenguaje Java. En las subsecciones (2.3.2) y (2.3.3) se explican los dos estilos principales de persistencia: manual vs administrada. En las subsecciones siguientes se muestran las tecnologas a las que haremos referencia al presentar la propuesta en el captulo 3. Dada la gran adopcin de las bases de datos relacionales en la en la industria del software, pondremos especial atencin sobre las herramientas que mapean objetos hacia/desde los RDBMS. Como se explic en el Plan de Tesis (seccin 1.3), el software desarrollado est construido en Java, por lo que los desarrollos tecnolgicos se harn sobre este lenguaje de programacin. Sin embargo, el anlisis sigue siendo vlido en otros lenguajes orientados a objetos que disponen de mecanismos de persistencia similares.

2.3.1. Persistencia y Ciclos de Vida en Aplicaciones Enterprise


En aplicaciones enterprise los objetos del dominio tienen ciclos de vida y ubicaciones que dependen de patrones de diseo y arquitectura propios de este tipo de aplicaciones. En estos entornos es posible que encontremos conviviendo un conjunto de procesos, los cuales no forman parte de una misma unidad de compilacin, sino que son independientes e interactan mediante IPC (Inter-Process Communication), RPC (Remote Procedure Call), colas de mensajes, bases de datos, web services o archivos. Adems, es frecuente que estos procesos y componentes provengan de proveedores diferentes que utilizan distintos medios para el almacenamiento de la informacin. An siendo todos los mdulos desarrollados con las mismas tecnologas, es muy posible encontrarse con almacenamientos mixtos, por ejemplo: archivos y bases de datos. En este entorno dependemos de la capacidad de interrogar e interpretar fuentes de datos de distintas naturalezas, lo que complejiza el acceso a la informacin. Este acceso a la informacin es importante a la hora de disear los mtodos de indexacin, recuperacin y visualizacin de los objetos del dominio (ver seccin 2.1). Para resolver este problema es crucial conocer los mecanismos por los cuales los objetos se vuelven persistentes.

2.3.2. Persistencia Manual


Cuando la persistencia se administra de forma manual, es responsabilidad del programador manejar el ciclo de vida de los objetos as como las tcnicas de almacenamiento. El esquema manual otorga la mayor exibilidad posible a cambio de un esfuerzo mayor de programacin. En este esquema el programador utiliza las APIs provistas por el lenguaje para serializar/deserializar los objetos, acceder al medio de almacenamiento, instanciar y destruir los objetos (en el caso de Java hablamos de desreferenciar). Para tener un motor de bsqueda sobre objetos, es necesario sincronizar el ciclo de vida de los objetos con el motor de bsqueda. Dado que la persistencia manual puede implementarse de muchas maneras distintas, en este esquema de trabajo los eventos CRUD son difciles de interceptar por cualquier herramienta externa.

13 CRUD:

siglas en ingls para crear, leer, actualizar y eliminar objetos (create, read, update y delete).

56

CAPTULO 2.

ESTADO DEL ARTE

Si bien es cierto que necesitamos conocer los eventos para sincronizar la aplicacin y el motor de bsqueda, en un esquema de persistencia manual se puede modicar la aplicacin para dar aviso de los eventos CRUD programaticamente o soportar cierto grado de divergencia entre la aplicacin y el motor de bsqueda. Como ejemplo de divergencia controlada entre el motor de bsqueda y la aplicacin tomemos el caso de los buscadores web, los cuales desconocen cundo se genera, actualiza o elimina una pgina web. Sin embargo, el webmaster puede indicar por dnde comenzar la indexacin y generar meta datos que indican cmo recorrer el sitio web que est indexando, as como es posible descubrir pginas y sitios web por los enlaces presentes en el HTML. Para el caso de un grafo de objetos, tambin podemos iniciar el recorrido por nodos bien conocidos o por un lugar indicado manualmente y luego navegar las relaciones entre objetos de forma de indexar los que vamos descubriendo.

2.3.3. Persistencia Administrada


Dada la complejidad de desarrollo de un esquema de persistencia manual, existen soluciones que administran la persistencia de objetos de manera automtica. Existen muchas advertencias acerca del costo de mapear a mano un modelo de dominio a un RDBMS (una de ellas se puede encontrar en Fowler, 2002). Muchas de estas herramientas se presentan como frameworks que persisten objetos en bases de datos relacionales. Algunos ejemplos son Hibernate Core, iBATIS, JDO y JPA (Hibernate, 2009a ; Apache, 2009c ; JCP, 2006b ,a ). Eventualmente tambin hay mecanismos de persistencia sobre archivos como BerkeleyDB (Oracle, 2009a ). El objetivo de estas herramientas es asistir al programador en el manejo del ciclo de vida de los objetos, facilitando el traslado entre la memoria principal y secundaria. Estos frameworks adems colaboran en tareas ms complejas como las transacciones y la optimizacin de consultas. Los frameworks de persistencia administrada introducen distintos grados de dependencia entre el modelo de dominio y el framework, as como tambin permiten distintos grados de transparencia respecto del esquema de base de datos. Los ORMs (mapeadores objeto-relacionales object-relational mappers) de ms bajo nivel slo proveen una API para transformar consultas SQL en objetos y vice versa, mientras que los ORM de ms alto nivel nos abstraen completamente del mecanismo de persistencia (a cambio de que especiquemos cmo persistir los objetos con una buena cantidad de metadatos). En las prximas subsecciones analizamos distintos mecanismos de persistencia que pueden utilizarse tanto en un esquema de persistencia manual como administrada.

2.3.4. Binaria
El lenguaje Java incluye entre sus bibliotecas estndar la capacidad de convertir objetos en una forma serializada, el cual es tanto transmisible por un canal como almacenable en memoria secundaria. La persistencia binaria en Java consiste en enviar los datos necesarios hacia un ujo de salida

14 para

luego reconstruir el objeto a partir de un ujo de entrada sobre sos datos. Java almacena a la salida el nombre y rma de la clase as como los campos no transientes ni estticos de la misma (Sun, 2008). Para poder persistir un objeto, es necesario que algn ancestro en la jerarqua de clases implemente la interfaz java.io.Serializable.

Ejemplo 2.3.1.
1 2 3 4

Una adaptacin del ejemplo de persistencia binaria en Java presente en (Sun, 2008):

F i l e O u t p u t S t r e a m f o s = new F i l e O u t p u t S t r e a m ( " payment 1258302209. d a t " ) ; O bj ec tO u tp ut S tr ea m oos = new O bj ec tO u tp ut S tr ea m ( f o s ) ; oos . w r i t e O b j e c t ( new C r e d i t C a r d P a y m e n t ( i t e m I n f o r m a t i o n , c r e d i t C a r d ) ) ; oos . c l o s e ( ) ;

La lnea nmero 2 del ejemplo (2.3.1) genera un ujo de escritura de objetos sobre el ujo denido en la lnea nmero 1. La lnea 3 genera un objeto que contiene informacin de pago de una tarjeta de crdito (asumiendo que los parmetros se generan previamente) y persiste el objeto

CreditCardPayment en el disco.

El sistema de persistencia binario de Java permite congurar otros aspectos del proceso como:

14 Hablar

de ujos de salida es ms general que hablar de archivos. Los ujos de salida pueden ser valores de retorno

de una llamada a procedimiento remoto, un canal TCP, un archivo o cualquier otro almacenamiento fsico medio de transmisin.

2.3.

PERSISTENCIA DE MODELOS DE DOMINIO

57

protocolos propios de serializacin/deserializacin control de versiones seguridad

La informacin detallada del sistema de persistencia binaria se encuentra en (Sun, 2004). En conclusin, el sistema de serializacin binaria permite serializar un grafo de objetos serializables a travs de un ujo. Si bien esto es muy til, este sistema no nos da ninguna facilidad respecto de:

transacciones recuperacin eciente de datos (ndices) inspeccin y manipulacin fuera de linea de los objetos generacin de reportes ad-hoc / clculo de agregaciones sobre campos integridad referencial control de unicidad

En las prximas subsecciones analizaremos los sistemas ms populares de persistencia, los cuales solucionan algunos de estos problemas.

2.3.5. Ad-Hoc
Es posible evitar problemas de la persistencia binaria (ver subseccin 2.3.4) utilizando un mtodo de persistencia ad-hoc. Si bien en el extremo podramos decir que todos los sistemas de persistencia que no son binarios son adhoc, vamos a referirnos a la persistencia ad-hoc como el mtodo de serializacin utilizado para resolver la persistencia de un conjunto de clases de una aplicacin determinada. Algunos ejemplos de persistencia ad-hoc:

conversin a texto delimitado por comas (CSV), serializacin a texto plano con cifrado AES, en texto plano hacia archivos indexados.

La serializacin ad hoc puede ser adecuada si queremos mantener compatibilidad con futuros cambios a los objetos persistentes. Otro caso donde conviene generar nuestro propio serializador es cuando tenemos que persistir gran cantidad de objetos y queremos optimizar el espacio utilizado. Con un serializador propio podemos aprovechar nuestro conocimiento acerca de los datos para obtener estadsticamente mejoras en el espacio utilizado (comprimiendo enteros, cadenas de texto, etc.). En Java se puede utilizar un esquema hbrido entre persistencia binaria y ad-hoc implementando la interfaz java.io.Externalizable. Al implementar esta interfaz podemos utilizar las clases ObjectOutputStream y ObjectInputStream para leer y escribir de los ujos, pero seremos nosotros quienes programemos el protocolo de serializacin. A continuacin vemos un ejemplo en el que se utiliza este sistema.

Ejemplo 2.3.2.

Serializacin Ad-Hoc implementando

java.io.Externalizable.

Al ejecutar este cdigo se

imprime en la pantalla la misma informacin que se persisti en el archivo.

58

CAPTULO 2.

ESTADO DEL ARTE

public

class

CreditCardPayment

implements

Externalizable

private private

ItemInformation CreditCard

itemInformation ;

creditCard ;

// C o n s t r u c t o r e s , get , s e t y t o S t r i n g . . // C a l l b a c k p a r a l a s e r i a l i z a c i n
public void

w r i t e E x t e r n a l ( ObjectOutput

out )

throws

IOException

out . w r i t e I n t ( i t e m I n f o r m a t i o n . g e t I t e m I d ( ) ) ; String
for

cipherVersion i = 0; i <

= creditCard . cipher () ; cipherVersion . length () ; i ++) out . writeChar (

( int

c i p h e r V e r s i o n . charAt ( i ) ) ; }

// C a l l b a c k p a r a l a d e s e r i a l i z a c i n
public void

readExternal ( ObjectInput { = new

in )

throws

IOException ,

ClassNotFoundException
this . itemInformation this . creditCard

ItemInformation ( in . readInt () ) ;

= new

CreditCard () ;
c h a r [ C r e d i t C a r d . NUMBER_LENGTH ] ;

char [ ] for

c i p h e r C h a r s = new i = 0; i <

( int

C r e d i t C a r d . NUMBER_LENGTH ;

i ++)

cipherChars [ i ] = in .

readChar () ;
t h i s . c r e d i t C a r d . s e t C i p h e r N u m b e r ( new

String ( cipherChars ) ) ;

// Ejemplo de uso
public static void

main ( S t r i n g [ ] { original

args )

throws

IOException , ItemInformation

ClassNotFoundException CreditCardPayment (10) ,


new

= new

C r e d i t C a r d P a y m e n t ( new

C r e d i t C a r d (321654987456L ) ) ; f o s = new F i l e O u t p u t S t r e a m ( " payment

FileOutputStream

1258302209. dat " ) ;

ObjectOutputStream oos . c l o s e ( ) ; FileInputStream fis

o o s = new

ObjectOutputStream ( f o s ) ;

oos . w r i t e O b j e c t ( o r i g i n a l ) ;

= new

F i l e I n p u t S t r e a m ( " payment

1258302209. dat " ) ;

ObjectInputStream CreditCardPayment ois . close () ;

ois

= new

ObjectInputStream ( f i s ) ;

r e s t a u r a d o = ( CreditCardPayment ) o i s . readObject () ;

System . out . p r i n t l n ( r e s t a u r a d o ) ; } }

En el ejemplo (2.3.2) se persisti una versin cifrada del nmero de tarjeta de crdito para no transmitir la versin original en texto plano. Si no se desea implementar java.io.Externalizable, se puede hacer persistencia ad-hoc mediante reection de Java.

Respecto del manejo de los eventos CRUD, la serializacin ad-hoc es muy similar a la binaria ya que no hay un mecanismo estndar de noticacin de estos eventos. La noticacin de estos eventos queda en manos del programador.

2.3.

PERSISTENCIA DE MODELOS DE DOMINIO

59

2.3.6. XML
La serializacin XML es un tipo de serializacin ad-hoc que tiene algunas ventajas:

interoperabilidad con otros lenguajes legible y editable por un humano herramientas que soportan lectura y escritura de XML, DTD y Schema

Estas ventajas tienen el costo de no tener la misma exibilidad de la serializacin ad-hoc. Una herramienta que se ocupa de la serializacin XML es XStream (XStream, 2009). A continuacin vemos una adaptacin de un ejemplo presente en la documentacin de esta herramienta:
public class

CreditCardPayment

private private

ItemInformation CreditCard

itemInformation ;

// C o n s t r u c t o r y mtodos . . .
}
public static void

creditCard ;

main ( S t r i n g

args [ ] )

throws

Exception

XStream

x s t r e a m = new X S t r e a m ( new

DomDriver ( ) ) ;

x s t r e a m . a l i a s ( " payment " , xstream . a l i a s ( " item " , xstream . a l i a s ( " c r e d i t CreditCardPayment (10) , String } Esto produce el XML: <p a y m e n t> <i t e m> < i t e m I d>1 0</ i t e m I d> </ i t e m> <c r e d i t
new

CreditCardPayment . c l a s s ) ; CreditCard . class ) ; C r e d i t C a r d P a y m e n t ( new ItemInformation

ItemInformation . class ) ;

c a r d " ,

original

= new

C r e d i t C a r d (321654987456L ) ) ;

x m l = x s t r e a m . toXML ( o r i g i n a l ) ;

c a r d> c a r d>

<n u m b e r>3 2 1 6 5 4 9 8 7 4 5 6</ n u m b e r> </ c r e d i t </ p a y m e n t> La deserializacin es tambin muy simple: CreditCardPayment r e s t a u r a d o = ( C r e d i t C a r d P a y m e n t ) x s t r e a m . fromXML ( x m l ) ;

Es preciso notar que para el caso de XStream, el framework toma responsabilidades avanzadas como el

mapeo en jerarquas de herencia y agregaciones (XStream, 2009).


En muchos casos la serializacin XML puede ser una mejor alternativa que los mtodos ad-hoc por las ventajas que hemos comentado, sin embargo, existen algunos aspectos a resolver: transacciones, control de unicidad e integridad referencial, acceso eciente y generacin de reportes. Este tipo de problemas pueden abordarse mejor con el respaldo de una base de datos, por lo que en las prximas secciones vamos a abordar las tcnicas que utilizan RDBMS como parte de la persistencia de objetos.

2.3.7. Object Relational Mapper (ORM)


Los RDBMS han sido la base para miles de sistemas por ms de 30 aos. Asimismo, la gran masa de esfuerzo en desarrollo de software se orienta a la programacin orientada a objetos.

60

CAPTULO 2.

ESTADO DEL ARTE

Basndose en estos dos hechos, la industria del software ha buscado combinar tanto la programacin orientada a objetos como los RDBMS. Sin embargo, a pesar del xito de estos dos modelos existe un problema entre ellos llamado desajuste de impedancia (Fowler, 2002) desajuste son: Tipos de Datos: no existe un mapeo 1:1 entre los tipos de datos primitivos de los lenguajes de programacin y los de las bases de datos. Algunos ejemplos en Java y Oracle: String vs. Varchar e Integer vs. Number. Herencia y Polimorsmo: son fciles de implementar en un lenguaje orientado a objetos, mientras que en un RDBMS requieren elegir cuidadosamente la estrategia de implementacin. Recuperacin de Datos y Junta: el mapeo entre relaciones y clases debe generar resultsets compatibles con las clases, ya que el esquema del resultset se genera dinmicamente dependiendo las columnas que especique en la consulta. La navegacin entre asociaciones en un mundo de objetos consiste en iterar a travs de colecciones, mientras que en una base de datos puede requerir una junta, la cual no se corresponde con una clase real del modelo de objetos o bien ejecutar consultas adicionales para obtener los objetos agregados. Orden de Creacin: en un esquema de base de datos podemos tener dos tablas cuyas relaciones se referencian entre s, lo cual puede ser un problema al momento de la creacin de objetos, ya que un objeto depende del otro para su creacin, dando lugar a la pregunta de quin debe crearse primero. Esquema Duplicado: estamos obligados a conservar una estructura de datos en el modelo de dominio y otra en las tablas de la base de datos. En las consideraciones de diseo no debe perderse el balance entre los dos esquemas y se debe tener en mente tcnicas para que la navegacin de objetos no genere consultas excesivas en el RDBMS. Identidad vs. Equivalencia: en los lenguajes de programacin como Java es factible que a.equals(b) sea cierto pero que a==b no lo sea, mientras que en una relacin no pueden existir dos tuplas diferentes con la misma clave. Reglas de Acceso: el modelo de objetos tiene atributos pblicos y privados, mientras que los RDBMS tienen permisos. Si bien es posible plantear otros desajustes entre los dos modelos, los expuestos dan un panorama del problema de conciliar dos modelos exitosos por separado pero diciles de reunir. Dado el esfuerzo que requiere persistir objetos en bases de datos relacionales, se ha desarrollado una amplia gama de herramientas que asisten al programador en esta tarea. Estas herramientas son los ORM. Los ORM varan desde wrappers de bajo nivel de las API del lenguaje hasta herramientas de alto nivel que permiten abstraernos del esquema y el SQL. A continuacin presentamos pequeos casos de estudio de ORM bsicos, donde el programador tiene un rol activo en resolver los desajustes de impedancia y ORM Completos, donde el framework asiste al programador en resolver estos desajustes.

15 . Algunos de los tems que componen este

ORM Bsicos
A continuacin vemos dos ejemplos de ORM bsicos donde debemos resolver la mayora de los problemas de impedancia: JDBC y Apache iBATIS.

JDBC (Java DataBase Connectivity)


de consultas sobre el RDBMS.

JDBC es la API de Java para estandarizar el dilogo con los

distintos RDBMS. Esta API establece las primitivas de manejo de conexiones, transacciones y ejecucin

En los casos en los que se quiere hacer el esfuerzo de codicar una capa propia de persistencia, normalmente se construyen las clases del framework conectndolas con JDBC para la ejecucin de consultas. En rigor

15 Si

bien Fowler efectivamente utiliza el trmino impedance mismatch en su obra, pueden encontrarse otras notas,

artculos o libros donde se reere al tema con la misma frase, por lo que no podemos asegurar cul sera la cita ms adecuada.

2.3.

PERSISTENCIA DE MODELOS DE DOMINIO

61

JDBC no es un ORM en s mismo sino que es la herramienta que stos utilizan para dialogar con el RDBMS. Al utilizar JDBC se obtiene una gran exibilidad, pero queda en manos del desarrollador resolver todos los problemas de impedancia. Los eventos CRUD no se notican por ningn medio estndar ya que su implementacin es totalmente ad-hoc.

Ejemplo 2.3.3.
{

A continuacin vemos un caso en el que hacemos un mapeo bsico entre la base de datos

y un objeto utilizando JDBC.

public s t a t i c void

main ( S t r i n g a r g s [ ] )

throws

SQLException

L o c a l e . s e t D e f a u l t ( L o c a l e . ENGLISH ) ; D r i v e r M a n a g e r . r e g i s t e r D r i v e r ( new o r a c l e . j d b c . d r i v e r . O r a c l e D r i v e r ( ) ) ; C o n n e c t i o n conn=D r i v e r M a n a g e r . g e t C o n n e c t i o n ( " j d b c : o r a c l e : t h i n : @ l o c a l h o s t : 1 5 2 1 : XE" , " u s u a r i o " , " p a s s w o r d " ) ; S t a t e m e n t stmt = conn . c r e a t e S t a t e m e n t ( ) ;

int u s e r I d = 1 0 ; R e s u l t S e t r s e t = stmt . e x e c u t e Q u e r y ( "SELECT f i r s t _ n a m e , last_name , l o w e r ( nickname ) FROM u s e r WHERE i d="+u s e r I d ) ; while ( r s e t . n e x t ( ) ) { System . out . p r i n t l n ( new com . mydomain . U s e r ( u s e r I d , r s e t . g e t S t r i n g ( 1 ) , r s e t . getString (2) , r s e t . getString (3) ) ; } stmt . c l o s e ( ) ; conn . c l o s e ( ) ;

Como se ve en este fragmento de cdigo, el usuario se ocupa de la conexin y recuperacin de datos desde la base, mapeando el esquema de relacin a los objetos del dominio en forma manual.

Apache iBATIS

Existen herramientas populares que facilitan las tareas rutinarias de persistencia con

JDBC sin obligarnos a ceder el control total de la persistencia. Una herramienta muy popular en este sentido es Apache iBATIS (ver Apache, 2009c ). En iBATIS 3 podemos denir las operaciones que queremos realizar sobre la base de datos mediante interfaces. Estas interfaces reciben y devuelven objetos de dominio o en su defecto objetos de transferencia

de datos (data transfer objects DTO ). Las reglas acerca de cmo insertar, actualizar, eliminar o recuperar
objetos desde el RDBMS las debemos congurar explcitamente mediante archivos de conguracin, los cuales contienen el SQL necesario. A continuacin vemos un ejemplo.

Ejemplo 2.3.4.
cualquiera.

En este ejemplo vemos cmo manejar la persistencia de un objeto

Person de un dominio

Clase del dominio:

public c l a s s

Person {

private long i d ; private S t r i n g f i r s t N a m e ; private S t r i n g lastName ; private S t r i n g e m a i l ; private L i s t <Person> c o n t a c t s ; private Company company ;

62

CAPTULO 2.

ESTADO DEL ARTE

public
}

Person () { }

// get , s e t , . . .

Interfaz de mapeo:

public interface PersonMapper { public P e r s o n s e l e c t P e r s o n ( int i d ) ; public L i s t <Person> selectByCompany ( long public void i n s e r t P e r s o n ( I n s e r t P e r s o n D t o
Person.xml
con el SQL de mapeo:

id ) ; insertDto ) ;

Archivo

<? xml version =" 1 . 0 " e n c o d i n g="UTF8" ?> <!DOCTYPE mapper PUBLIC " // i b a t i s . apache . o r g //DTD Mapper 3 . 0 / /EN" " h t t p : // i b a t i s . apache . o r g / dtd / i b a t i s 3mapper . dtd "> <mapper namespace="com . mydomain . PersonMapper "> <r e s u l t M a p i d=" p e r s o n R e s u l t M a p " t y p e=" P e r s o n "> <c o n s t r u c t o r> <i d A r g column=" i d " j a v a T y p e=" l o n g " /> <a r g column=" f i r s t _ n a m e " j a v a T y p e=" S t r i n g " /> <a r g column=" last_name " j a v a T y p e=" S t r i n g " /> <a r g column=" e m a i l " j a v a T y p e=" S t r i n g " /> </ c o n s t r u c t o r> <i d p r o p e r t y=" i d " column=" i d " /> < r e s u l t p r o p e r t y=" f i r s t N a m e " column=" f i r s t _ n a m e " /> < r e s u l t p r o p e r t y=" lastName " column=" last_name " /> < r e s u l t p r o p e r t y=" e m a i l " column=" e m a i l " /> < a s s o c i a t i o n p r o p e r t y=" company " column=" company_id " j a v a T y p e="Company" s e l e c t="com . mydomain . CompanyMapper . s e l e c t C o m p a n y " /> < c o l l e c t i o n p r o p e r t y=" c o n t a c t s " j a v a T y p e=" A r r a y L i s t " column=" i d " ofType=" P e r s o n " s e l e c t=" s e l e c t C o n t a c t s " /> </ r e s u l t M a p> < s e l e c t i d=" s e l e c t P e r s o n " parameterType=" i n t " r e s u l t T y p e=" P e r s o n " r e s u l t M a p=" p e r s o n R e s u l t M a p "> select i d , f i r s t _ n a m e , last_name , e m a i l , company_id from MYAPPSCHEMA. P e r s o n where i d = #{i d } </ s e l e c t> < s e l e c t i d=" s e l e c t C o n t a c t s " parameterType=" i n t " r e s u l t T y p e=" P e r s o n " r e s u l t M a p=" p e r s o n R e s u l t M a p "> select p . i d , p . f i r s t _ n a m e , p . last_name , p . e m a i l from MYAPPSCHEMA. C o n t a c t c , MYAPPSCHEMA. P e r s o n p where c . from_id = #{i d } and c . to_id = p . i d </ s e l e c t> < s e l e c t i d=" selectByCompany " parameterType=" i n t " r e s u l t T y p e=" P e r s o n " r e s u l t M a p=" p e r s o n R e s u l t M a p ">

2.3.

PERSISTENCIA DE MODELOS DE DOMINIO

63

select i d , f i r s t _ n a m e , last_name , e m a i l from MYAPPSCHEMA. P e r s o n where company_id = #{i d } </ s e l e c t> < i n s e r t i d=" i n s e r t P e r s o n " parameterType="com . mydomain . dto . I n s e r t P e r s o n D t o "> <s e l e c t K e y o r d e r="BEFORE" r e s u l t T y p e=" j a v a . l a n g . Long " k e y P r o p e r t y=" person . id " > SELECT NEXT VALUE FOR MYAPPSCHEMA. p e r s o n _ i d FROM DUAL AS ID </ s e l e c t K e y> INSERT INTO MYAPPSCHEMA. PERSON ( ID , FIRST_NAME, LAST_NAME, PASSWORD, EMAIL , COMPANY_ID ) values ( #{p e r s o n . i d , jdbcType=BIGINT } , #{p e r s o n . f i r s t N a m e , jdbcType=VARCHAR} , #{p e r s o n . lastName , jdbcType=VARCHAR} , #{password , jdbcType=VARCHAR} , #{p e r s o n . e m a i l , jdbcType=VARCHAR} , #{p e r s o n . company . i d , jdbcType=BIGINT} ) </ i n s e r t> </ mapper>
Finalmente vemos caso de uso de ejemplo

RegisterPerson:

public c l a s s R e g i s t e r P e r s o n { private s t a t i c void i n s e r t P e r s o n ( Company

company , S t r i n g f i r s t N a m e , S t r i n g lastName , S t r i n g e m a i l , S t r i n g p a s s w o r d ) throws BusinessException { S t r i n g r e s o u r c e = "com/mydomain/ p e r s i s t e n c e / C o n f i g u r a t i o n . xml " ; Reader r e a d e r = R e s o u r c e s . g e t R e s o u r c e A s R e a d e r ( r e s o u r c e ) ; S q l S e s s i o n F a c t o r y s q l M a p p e r = new S q l S e s s i o n F a c t o r y B u i l d e r ( ) . b u i l d ( reader ) ;

try

S q l S e s s i o n s e s s i o n = sqlMapper . openSession () ; { PersonMapper personMapper = s e s s i o n . getMapper ( PersonMapper . c l a s s ) ; I n s e r t P e r s o n D t o dto = new I n s e r t P e r s o n D t o ( ) ; P e r s o n p = new P e r s o n ( f i r s t N a m e , lastName , e m a i l ) ; p . setCompany ( company ) ; dto . s e t P e r s o n ( p ) ; dto . s e t P a s s w o r d ( p a s s w o r d ) ; personMapper . i n s e r t P e r s o n ( dto ) ;

} } }

s e s s i o n . commit ( ) ; finally { session . close () ;

En este ejemplo vimos los actores que intervienen en la persistencia con iBATIS. Para nalizar el ejemplo vamos a enumerarlos y describir sus responsabilidades:

64

CAPTULO 2.

ESTADO DEL ARTE

Objetos de dominio (Person): implementan la lgica de negocio, no tienen dependencias explcitas hacia el ORM. Interfaz de acceso a datos (PersonMapper): dene las operaciones de persistencia sobre el objeto a mapear. Permite proveer implementaciones alternativas al ORM. Archivo de conguracin del mapeo (Person.xml): dene la lgica de mapeo entre el esquema de base de datos y el modelo. Objeto de negocio (RegisterPerson): implementa la secuencialidad del caso de uso.
iBATIS evita que escribamos y dupliquemos buenas cantidades de cdigo ad-hoc para la transformacin de datos entre el esquema de base de datos y el modelo de clases. Adems ayuda a resolver desajustes de impedancia de conversin de tipos de datos, herencia y polimorsmo. Entre las ventajas de utilizar este ORM est la provisin de caches de objetos que evitan consultas innecesarias a la base de datos, lo cual es conveniente para hidratar objetos recuperados.

ORM Completos
Los ORM completos buscan resolver integralmente los desajustes de impedancia entre modelos. Estos ORM son herramientas administradas de mayor complejidad que los ORM bsicos. El primer caso de estudio es el estndar JPA (Java Persistence API, JCP, 2006a ). Este es el estndar de Java para persistencia objeto-relacional. El segundo caso de estudio es JDO, un estndar ms antiguo que JPA pero que tiene varias implementaciones y usuarios. El tercer caso de estudio es una herramienta de persistencia no estandarizada por un JSR

16 llamada

Hibernate (ver Hibernate, 2009a ). Este ejemplo es especialmente signicativo ya que el mismo grupo de desarrollo provee un motor de bsqueda para el ORM llamado Hibernate Search (ver Hibernate, 2009b ), el cual tomaremos como caso de estudio en la seccin (2.4.2).

JPA (Java Persistence API)

Es un estndar de persistencia objeto-relacional introducido en (JCP,

2006a ). La intencin de este estndar es simplicar el desarrollo de aplicaciones que requieren persistencia objeto-relacional y unicando a los usuarios detrs de una sola API. JPA impone algunos requerimientos sobre el modelo de dominio:

debemos anotar las clases con el annotation

@Entity

la clase debe tener al menos un constructor pblico o privado sin argumentos ni la clase, ni sus mtodos o variables persistentes de instancia pueden ser declarados para ciertos usos, la clase debe implementar la interfaz

final

java.io.Serializable

los clientes deben acceder al estado a travs de mtodos de acceso (get/set) mtodos de negocio (calcularSaldo, etc).

A cambio de estas restricciones, JPA es capaz de mapear jerarquas de clases hacia tablas, generar claves primarias y mapear tipos de datos entre Java y el RDBMS. Adems del SQL estndar que siempre podemos ejecutar sobre el RDBMS, JPA permite consultas sobre objetos en un lenguaje similar a SQL (JPA-QL), lo que facilita la recuperacin y mapeo de objetos. La implementacin de referencia de JPA es Oracle TopLink (Oracle, 2008). Adems de esta implementacin de referencia, existen otras como OpenJPA y Hibernate (a travs de mdulos adicionales). Nuestro inters principal en JPA es mostrar su importancia en el ecosistema de persistencia y contarlo como posible actor en la relacin de las aplicaciones con nuestro motor de bsqueda.

16 Java

Specication Requests (JSR): son descripciones tcnicas propuestas en el marco del Java Community Process

(JCP). Funcionan como propuestas de estndares hasta eventualmente incorporarse a la especicacin Java.

2.4.

CASOS DE ESTUDIO

65

JDO (Java Data Objects)

La especicacin de este sistema de persistencia para objetos conocido

como se public inicialmente en el JSR-12 (2002), previamente a JPA. Ms tarde, el JSR-243 (2006) especica la versin 2 de JDO, la cual cuenta con las siguientes caractersticas:

soporte para mltiples data stores (puede almacenar objetos fuera de un RDBMS), no requiere modicar los objetos de dominio (Plain Old Java Objects POJO ), generacin automtica del esquema, auto generacin de claves primarias, no requiere escribir cdigo relacionado a JDBC.

Tcnicamente, dado que JDO persiste objetos hacia otros medios adems de un RDBMS, no es un ORM sino que es una herramienta de persistencia transparente. A pesar de esto tomamos el caso de particular en que el data store es un RDBMS y lo tratamos como un ORM. En JDO el proceso de compilacin requiere un tratamiento de post-compilacin llamado enhancer (potenciador). El enhancer le permite al framework reconocer los cambios de estado en un objeto para manejar su persistencia. JDO dispone de mltiples implementaciones como JPOX y DataNucleus as como una implementacin de referencia (ver JCP, 2006b ). As como en JPA, nuestro inters en JDO pasa por tenerlo en cuenta como un posible actor con el cual interactuar en la construccin del motor de bsqueda.

Hibernate

El mdulo base de Hibernate es el framework de persistencia no estndar ms difundido

entre los ORM. Como ya hemos comentado anteriormente, Hibernate es una suite de productos construidos alrededor de Hibernate Core (mdulo autnomo base del ORM) e implementa el estndar JPA mediante mdulos opcionales. Hibernate es muy similar a JPA y JDO en el sentido de que impone algunos requerimientos bsicos sobre el modelo de dominio (constructor sin argumentos) y se ocupa de transparentar la persistencia de objetos al RDBMS. Este ORM tiene la particularidad de que avanz en la solucin del problema de IR sobre objetos mediante un mdulo adicional llamado Hibernate Search (Hibernate, 2009b ). En la subseccin (2.4.2) ampliaremos acerca de ste.

2.3.8. Bases de Datos Orientadas a Objetos


Tras muchos aos de existencia, las Bases de Datos Orientadas a Objetos (Object Oriented DataBase

Management System OODBMS ) han atravesado distintos esfuerzos de estandarizacin sin lograr una
adopcin masiva. Si bien en ciertos campos del conocimiento pueden ser una muy buena solucin (se suele citar el CAD/CAM como campo de aplicacin), tienen bajo nivel de adopcin en el ambiente de aplicaciones empresariales (donde planteamos mayormente el campo de aplicacin del motor de bsqueda). Por estas razones excluimos los OODBMS como caso de interaccin con el motor de bsqueda, siendo que las aplicaciones que efectivamente utilicen un OODBMS debern comunicarse mediante una API genrica (tal como si utilizaran persistencia manual).

2.4.

Casos de Estudio

En esta seccin estudiamos tres herramientas que representan el estado del arte en materia de IR para uso en desarrollo de software. stas herramientas son de especial inters a la hora de realizar un anlisis comparativo y extraer las mejores prcticas para generar la herramienta de IR que construimos.

66

CAPTULO 2.

ESTADO DEL ARTE

La primera herramienta es Apache Lucene (Apache, 2009b ). Lucene est orientado a la indexacin y recuperacin de documentos de texto generales. La segunda y tercera herramienta son respectivamente Hibernate Search y Compass Project. Estas dos herramientas son sosticados envoltorios de Lucene (lo utilizan como motor de indexacin y recuperacin) que intentan resolver los problemas de utilizarlo directamente como indexador de objetos (ver subseccin 1.1.3). Para la categorizacin de sistemas de IR que hemos hecho en la subseccin (2.1.1), dentro de la categora de IR para desarrollo de software, Lucene entra en la sub categora de Text Retrieval mientras que Hibernate Search y Compass pertenecen a la sub categora de Object Search.

2.4.1. Apache Lucene


Apache Lucene es un sistema maduro de indexacin y recuperacin de textos de cdigo abierto para Java (existen traducciones a otros lenguajes como C, C++, Perl, Python, etc). Este sistema se presenta al programador por medio de una API extensible y permite efectuar la indexacin y recuperacin de documentos en cualquier aplicacin. En los prximos apartados analizamos los conceptos bsicos de Lucene y vemos ejemplos de su utilizacin.

Documentos y Campos
En Lucene el diseador debe denir las entidades a indexar mediante la denicin de un objeto de clase Document. Los documentos aplican los conceptos de campos y zonas (ver subseccin 2.1.6) mediante objetos de tipo Field, los cuales se implementan como pares clave/valor sin un tipo de datos especco (en rigor se implementan como Strings). Lucene diferencia un campo y una zona mediante parmetros que permiten especicar si el Field se debe almacenar y/o indexar. A continuacin vemos un ejemplo de esta estructura.

Ejemplo 2.4.1.

Denicin de un documento que representa una pgina web.

Document doc = new Document ( ) ; doc . add ( new F i e l d ( "URL" , " h t t p : / /www. f i . uba . a r " , S t o r e . YES , I n d e x .NOT_ANALYZED )); doc . add ( new F i e l d ( "TITLE" , " F a c u l t a d de I n g e n i e r a U n i v e r s i d a d de Buenos A i r e s " , S t o r e . YES , I n d e x . ANALYZED) ) ; doc . add ( new F i e l d ( "BODY" , "<body><h1>B i e n v e n i d o a . . . " , S t o r e . YES , I n d e x . ANALYZED) ) ;

Antes de almacenar el texto en el ndice debemos especicar si queremos preprocesarlo o efectuar un almacenamiento literal. Los campos que elegimos preprocesar son tomados por objetos Analyzer que efectan tareas como: fragmentacin del texto, conversin a minsculas y eliminacin de stopwords. En el ejemplo (2.4.1) utilizamos un campo para almacenar la URL de la pgina web y elegimos no preprocesarlo porque estamos interesados en usarlo slo para bsquedas literales (de hecho como comentamos anteriormente, podramos almacenarlo sin indexarlo, lo que hara que no haya coincidencia aunque se lo busque literalmente). Por el contrario, para los campos TITLE y BODY s queremos un preprocesamiento que facilite la coincidencia con el documento, por lo que los marcamos con el parmetro Index.ANALYZED. Como comentamos en al prrafo anterior, adems de procesar los campos podemos almacenarlos en forma literal. En el ejemplo (2.4.1) indicamos que bamos a almacenar todos los campos al crearlos utilizando el parmetro Store.YES. Si almacenamos los datos luego podremos recuperar la versin literal del texto indexado (sin preprocesamientos). El almacenamiento es til para construir un vnculo entre el pseudoesquema construido en los campos de Lucene y el esquema del documento original.

ndices, Lectores y Escritores


La indexacin y la recuperacin de documentos se da a travs de lectores y escritores del ndice (IndexSearcher e IndexWriter). Los lectores y escritores son partes fundamentales de la API de Lucene, siendo que una implementacin bsica no necesita conocer mucho que estas interfaces.

2.4.

CASOS DE ESTUDIO

67

Consultas y Analizadores
Como comentamos en apartados previos, Lucene trata las bsquedas y documentos a indexar mediante extensiones de la clase abstracta Analyzer. El objetivo de los analizadores es almacenar los trminos en el ndice utilizando las tcnicas de matching y relevancia que vimos en la subseccin (2.1.5). Lucene cuenta con un lenguaje propio para especicar las bsquedas, el cual se interpreta para construir un objeto de tipo Query. Este lenguaje permite, entre otros, denir conjunciones y disyunciones de trminos, impulsar campos (boosting), bsquedas por proximidad y edit distance. Para generar las consultas es posible utilizar un QueryParser, el cual interpreta la bsqueda, la analiza (utilizando el analizador denido) y construye el objeto de tipo Query. El boosting al que referimos en al prrafo anterior es la implementacin de Lucene de los conceptos de campos y zonas presentes en la subseccin (2.1.6). Cuando revisemos la frmula de relevancia utilizada por Lucene veremos cmo se implementa el boosting.

Directorios
En Lucene existe la posibilidad de almacenar el ndice en memoria RAM, lesystems, bases de datos y otros. Esta capacidad de variar la implementacin de la capa de acceso a datos se da a travs de descendientes de la clase abstracta Directory. Esta capa de acceso a datos es extensible, permitiendo disear implementaciones particulares que permitiran funcionalidades no estndar como cifrar los datos. A continuacin vemos un ejemplo sinttico de indexacin y recuperacin en Lucene que integra los conceptos que hemos expuesto en los apartados anteriores.

Ejemplo 2.4.2.

En este ejemplo generamos un mtodo de indexacin y uno de recuperacin. Para la

indexacin creamos un documento que describe personas, siendo que utilizamos un campo para su tesis y otro campo para otros trabajos.

p r i v a t e s t a t i c void index ( ) throws IOException { D i r e c t o r y d i r = N I O F S D i r e c t o r y . g e t D i r e c t o r y ( new F i l e ( "/ l u c e n e / l u c e n e t e s t / " ) ) ; I n d e x W r i t e r w r i t e r = new I n d e x W r i t e r ( d i r , new S t a n d a r d A n a l y z e r ( ) , M a x F i e l d L e n g t h . LIMITED ) ;

Document doc = new Document ( ) ; doc . add ( new F i e l d ( "AUTHOR" , " J u l i n K l a s " , S t o r e . YES , I n d e x . ANALYZED) ) ; doc . add ( new F i e l d ( " TESIS " , " R e c u p e r a c i n de I n f o r m a c i n s o b r e Modelos de Dominio " , S t o r e . YES , I n d e x . ANALYZED) ) ; doc . add ( new F i e l d ( "OTHER_WORKS" , " 38 JAIIO R e c u p e r a c i n de I n f o r m a c i n s o b r e Modelos de Dominio " , S t o r e . YES , I n d e x . ANALYZED) ) ; w r i t e r . addDocument ( doc ) ; writer . optimize () ; writer . close () ;

p r i v a t e s t a t i c void s e a r c h ( ) throws IOException , ParseException { D i r e c t o r y d i r = N I O F S D i r e c t o r y . g e t D i r e c t o r y ( new F i l e ( "/ l u c e n e / l u c e n e t e s t / " ) ) ; I n d e x S e a r c h e r s e a r c h e r = new I n d e x S e a r c h e r ( d i r ) ;

Query q u e r y = new Q u e r y P a r s e r ( "OTHER_WORKS" , new S t a n d a r d A n a l y z e r ( ) ) . p a r s e ( " j a i i o ") ; TopDocs r s = s e a r c h e r . s e a r c h ( q u e r y , n u l l , 1 0 ) ; System . o u t . p r i n t l n ( " E n c o n t r a d o ( s ) "+r s . t o t a l H i t s+" r e s u l t a d o ( s ) " ) ;
f o r ( i n t i = 0 ; i < r s . t o t a l H i t s ; i ++) { Document h i t = s e a r c h e r . doc ( r s . s c o r e D o c s [ i ] . doc ) ; System . o u t . p r i n t l n ( " A u t o r : "+h i t . g e t F i e l d ( "AUTHOR" ) . s t r i n g V a l u e ( ) ) ; System . o u t . p r i n t l n ( " T e s i s : "+h i t . g e t F i e l d ( " TESIS " ) . s t r i n g V a l u e ( ) ) ; System . o u t . p r i n t l n ( " O t r o s : "+h i t . g e t F i e l d ( "OTHER_WORKS" ) . s t r i n g V a l u e ( ) ) ; }

68

CAPTULO 2.

ESTADO DEL ARTE

}
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) t h r o w s I O E x c e p t i o n , P a r s e E x c e p t i o n { index () ; search () ; }
Este ejemplo produce el resultado:

Encontrado ( s ) 1 r e s u l t a d o ( s ) : Autor : J u l i n Klas T e s i s : R e c u p e r a c i n de I n f o r m a c i n s o b r e Modelos de Dominio O t r o s : 38 JAIIO R e c u p e r a c i n de I n f o r m a c i n s o b r e Modelos de Dominio

Modelos de IR de Lucene
El modelo de IR (ver subseccin 2.1.4) utilizado por Lucene es una combinacin del modelo vectorial y el booleano (Apache, 2009b ). En Lucene esta combinacin consiste en utilizar el modelo booleano para denir qu documentos se recuperarn y luego priorizarlos con el modelo vectorial. Tal como comentamos al momento de introducir el modelo booleano, Lucene amplia los operadores AND, OR y NOT permitiendo bsquedas por wildcards, edit distance, frases y rangos (ver subseccin 2.1.5). Dentro del modelo vectorial, los pesos de relevancia aplicados por Lucene son variantes de la familia TF-IDF. Como veremos a continuacin, la aplicacin de TF-IDF tiene en cuenta la presencia de campos. La frmula de similitud de Apache Lucene

17 es (Apache, 2009b ):

Similitud (q, dj ) = coord (q, dj ) queryN orm (q)


tq

tfL (t, dj ) idfL (t) norm (dj ) boost (t)


(2.4.1)

Donde

es un termino de la query

dj

es el documento que se est evaluando. En el caso de Lucene

las funciones tf e idf que vimos en la subseccin (2.1.4) estn recalculadas de la siguiente manera:

tfL (t, dj ) =

tf (t, dj ) N df (t) + 1

idfL (t) = 1 + log


Los dems trminos tienen estos signicados:

coord (q, dj )

es una escala que depende de cuntos trminos de la query aparecen en el documento

(a mayor cantidad de trminos presentes, mayor peso).

queryN orm (q)


tipo de objeto

es un factor de normalizacin del tipo

2 wi,q

1 2

. Los valores

wi,q

dependen del

Query

que se utilice. Este factor de normalizacin no cambia el orden relativo de los

documentos (ver que no depende del documento) pero permite comparar los puntajes otorgados a un mismo documento en dos queries distintas.

boost (t) es un valor de impulso18

para el trmino de la query. Si queremos impulsar dinmicamente

un trmino de la query lo marcamos con un circunejo y un nmero que Lucene traducir a la frmula (2.4.1). Ej: information retrieval^4.

norm (dj )

es un clculo efectuado al indexar que incluye los siguientes factores:

el boost efectuado sobre el documento antes de indexarlo


hizo para la versin 3 de Lucene, sin embargo, la forma general de esta frmula suele mantenerse estable. ingls boost.

17 Este anlisis se 18 Traduccin del

2.4.

CASOS DE ESTUDIO

69

el boost efectuado sobre el campo antes de agregarlo al documento un valor de normalizacin respecto de la cantidad de trminos en el documento. La clase DefaultSimilirity lo implementa como

1
nmero de trminos

Si queremos que un documento o un campo de un documento del corpus sea ms relevante en forma esttica, podemos especicar un valor de impulso de forma similar a como especicamos

boost (t).

Ordenamiento y Filtrado
Comnmente tenemos que mezclar tareas de recuperacin ad hoc con operaciones tpicas de un RDBMS como el ordenamiento y el ltrado. Si suponemos una aplicacin que indexa y recupera informacin de un corpus de artculos cientcos, seguramente nos interese ordenar los resultados (artculos) segn el nmero de veces que fueron citados o ltrarlos para que la antigedad de un artculo no exceda cierta cantidad de aos. Lucene permite este tipo de recuperacin mediante la clase Sort y las subclases de Filter. Con este mecanismo podemos efectuar ordenamientos y ltros segn el campo del documento que especiquemos.

Anlisis de Lucene
En esta seccin vamos a analizar Lucene desde distintos ngulos considerando su uso para la indexacin de objetos de un modelo de dominio. Siguiendo los criterios propuestos en (Johnson y Foote, 1988), Lucene no es un framework sino que es una librera biblioteca. El ujo de control lo debe mantener la aplicacin husped invocando a Lucene al momento de indexar o buscar documentos, por lo que esta herramienta no cuenta con inversin del control (recordemos de la subseccin 2.2.1 que los enfoques ms puristas agregan IoC como un requisito para formar un framework). Dado que bajo estos criterios no es un framework, slo podemos discutir sus caractersticas de caja blanca y negra desde el punto de vista de la abstraccin como librera. En ese contexto presenta un comportamiento de caja negra ya que posee una API bien denida que no requiere grandes conocimientos de su estructura interna. Para usuarios expertos, Lucene se puede extender para alterar, por ejemplo, las frmulas de similitud y anlisis de texto. Si bien Lucene permite indexar y recuperar documentos en cualquier aplicacin Java, la herramienta est orientada a documentos. Para indexar objetos de dominio surgen desajustes similares a los estudiados al hablar de persistencia de objetos (ver subseccin 2.3.7), los cuales deben ser resueltos por el usuario de Lucene. Los autores de Hibernate Search (Bernard, 2007b ) sealan tres desajustes surgidos de utilizar Apache Lucene para indexar objetos de un dominio: Desajuste de Sincronizacin (Synchronization Mismatch ): consiste en el problema de mantener sincronizado el datastore y el ndice en base a los eventos CRUD. Desajuste Estructural (Structural Mismatch ): es el problema de efectuar un mapeo de objetos a documentos. Este desajuste es similar al que existe cuando se mapean objetos de dominio con JDBC segn analizamos en la subseccin (2.3.7). Desajuste de Recuperacin (Retrieval Mismatch ): al recuperar informacin Lucene devuelve instancias de la clase Document y no objetos del dominio. Una crtica comn hacia Lucene desde los autores de Hibernate Search y Compass es que es una solucin de bajo nivel. Si bien esto es especialmente subjetivo, es verdad que Lucene est lejos de ser tan simple de utilizar como, por ejemplo, libreras de logging. Las crticas que hacen los autores de Hibernate y Compass parece estar dirigida a que Lucene puede ser utilizado incorrectamente con facilidad y que tarde o temprano no nos permite abstraernos de qu ocurre dentro de la herramienta. A continuacin vamos a comentar cmo se implementan en Lucene las tcnicas principales de IR que hemos visto en la seccin (2.1). Es preciso notar que la mayora de las tcnicas de IR aplicadas por Lucene son soluciones estndar bien conocidas y descriptas en la literatura.

70

CAPTULO 2.

ESTADO DEL ARTE

Lucene implementa la indexacin dinmica mediante tcnicas similares a las de ndices auxiliares y generacionales (ver subseccin 2.1.5). Estos ndices auxiliares son llamados segmentos. Los segmentos son subndices independientes sobre los que es posible agregar y eliminar documentos. Vemos entonces que el ndice no es un archivo o estructura privilegiada sino que est formado por un conjunto de segmentos independientes. Un segmento esta formado por ms de una decena de archivos, los cuales almacenan el ndice invertido, las zonas y campos, documentos eliminados y estadsticas para el clculo de similitud (ver anlisis de ecuacin 2.4.1). Una caracterstica de Lucene es que sus ndices requieren un mantenimiento explcito mediante la opti-

mizacin. El proceso de optimizacin aplica la eliminacin de documentos dados de baja en el ndice as


como la fusin de segmentos segn la poltica de fusin. El algoritmo de fusin de segmentos tiende a buscar una solucin de compromiso entre necesitar acceder a muchos archivos para las bsquedas (lo que degrada la performance) y requerir fusiones excesivas (lo que afecta principalmente la performance de indexacin). El algoritmo de fusin es similar a la fusin logartmica (Manning et al., 2008) y se explica en detalle en (Cutting, 2004a ). Adicionalmente, la operacin de optimizacin tambin remueve fsicamente del segmento los documentos eliminados y recupera los huecos en la secuencia de numeracin introducidos por la eliminacin de documentos. Los eventos de altas, bajas y modicaciones de documentos se implementan con ciertas sutilezas que deben comprenderse para trabajar correctamente con Lucene el escritor (IndexWriter) actualiza el ndice, los nuevos documentos slo se hacen visibles a los lectores (IndexReader) al reabrir el ndice (en caso de que el ndice no estuviera abierto alcanza con abrirlo por primera vez). Las bajas de documentos se marcan en un vector de invalidaciones y se aplican fsicamente al optimizar el ndice. La modicacin de documentos en Lucene no se implementa estrictamente como tal sino que es necesario efectuar una baja del documento original y un alta del documento modicado. De hecho, estas operaciones se aplican sobre interfaces distintas (IndexReader para la baja e IndexWriter para el alta). Respecto de la performance de indexacin y recuperacin, existe un consenso acerca de las buenas marcas obtenidas por Lucene. En general se encuentra que Lucene emplea varias tcnicas para mejorar su performance (debemos tener en cuenta que la herramienta ha ido adoptando y mejorando tcnicas desde su aparicin en el ao 2000). Para acelerar la interseccin de posting lists, Lucene utiliza skip pointers. Debido a la necesidad de comprimir el ndice, se utiliza compresin por front coding para el diccionario de trminos junto con variable bit encoding para los identicadores de documentos. Esta informacin se puede obtener de la documentacin de Lucene as como de (Cutting, 2004b ). Las tcnicas de skip pointers, front coding y variable bit encoding se pueden encontrar en (Manning et al., 2008). La calidad de los resultados de Lucene (en trminos de similitud) est reconocida en la industria como muy buena. Como hemos analizado previamente, Lucene implementa el modelo vectorial mediante variantes de TF-IDF (ver subseccin 2.1.4). Las variaciones hechas a TF-IDF se explican bajo criterios heursticos pero la documentacin no referencia justicativos analticos de estas modicaciones. La solucin utilizada para valorizar zonas es intuitiva aunque la documentacin no referencia un sustento formal como el presentado en la subseccin (2.1.6). Esto ltimo se explica seguramente por la ausencia de un entrenador y la variabilidad en el nmero de zonas en un documento. En trminos de concurrencia, Apache Lucene resuelve la indexacin y bsqueda con un mecanismo similar (pero no idntico) al clsico problema de concurrencia de lectores y escritores. El proceso de bsqueda (lector) puede acceder al ndice en forma concurrente al mismo tiempo que un indexador (escritor). La diferencia con la semntica de lectores y escritores es que stos deban excluirse mutuamente mientras que en Lucene es posible buscar mientras se indexa. La exclusin mutua entre escritores s es necesaria y se da mediante archivos de bloqueo (lock les), quienes previenen la escritura concurrente del ndice lanzando una excepcin. La existencia de lock les provee exclusin mutua no solo entre hilos sino entre procesos.

19 . En el caso de las altas, luego de que

2.4.2. Hibernate Search


En esta seccin analizamos la primera herramienta que busca solucionar el problema de indexacin de objetos de un modelo de dominio, conocida como Hibernate Search (en adelante tambin la llamare-

19 Estas

consideraciones seguramente cambien con futuras versiones de Lucene. Recordemos que esta descripcin corre-

sponde a la versin 3 de la herramienta.

2.4.

CASOS DE ESTUDIO

71

mos simplemente HS ). A continuacin vamos a analizar esta herramienta desde distintas perspectivas relevantes al problema que queremos resolver.

Descripcin General
El objetivo de HS es indexar un modelo de dominio persistido con Hibernate Core o JPA, abstrayendo al programador de los desajustes que analizamos en las subsecciones (1.1.3) y (2.4.1). HS es una herramienta de cdigo abierto implementada en Java, la cual no es independiente sino que depende de Apache Lucene, Hibernate Core y complementos de ste como Hibernate Annotations. A diferencia del prximo caso de estudio (subseccin 2.4.3), los autores de HS recomiendan utilizarlo slo en conjunto con Hibernate o JPA (Bernard, 2007a )

20 .

Indexacin y Modelo de Dominio


Para poder indexar un dominio particular, HS requiere que introduzcamos annotations de Java que marcan las clases cuyas instancias son indexables (en adelante hablaremos simplemente de clases indexables entendiendo que lo que se indexan son instancias). Estas clases indexables se marcan con @Indexed y junto a ellas se debe indicar qu directorio de Lucene alojar el ndice (a priori los ndices de cada clase se separan en directorios con un ndice propio, aunque es posible almacenar distintas jerarquas en un mismo ndice). El hecho de indexar una clase no sirve para mucho sin indexar sus atributos. Para que un atributo ingrese al ndice es necesario anotarlo con @Field. Esta anotacin lleva parmetros que especican si el contenido del atributo se debe almacenar, analizar, etc. Estos parmetros son idnticos a los utilizados con Lucene para crear un Field (ver subseccin 2.4.1). Al recuperar un objeto, HS permite efectuar una operacin de proyeccin que slo retorna los atributos indicados (proyectados), ahorrando la carga de recuperar el grafo de referencias de un objeto. Dado que la proyeccin no utiliza el RDBMS, para hacer uso de ella es necesario almacenar en el ndice el valor del atributo proyectado. Para ser indexado y recuperado unvocamente desde el ORM, cada objeto necesita tener una identidad. Para marcar que un atributo identica la instancia, HS utiliza las anotaciones @Id y @DocumentId. Es posible hacer que la identicacin de un objeto provenga desde otra fuente mediante la anotacin @ProvidedId.

Procesos de Indexacin
Como discutiremos al abordar la propuesta de solucin en la subseccin (3.1.3), existen bsicamente tres modos de indexacin que tendran que cubrirse: indexacin online, semi-online y oine. HS implementa los tres modos de indexacin mediante backends, los cuales son llamados de la siguiente forma:

Lucene: utiliza directamente el ndice de Lucene. Equivale al modo Online o Semi-Online dependiendo de si es sincrnico (online) o asincrnico (semi-online). JMS: equivale al modo Oine. Se utilizan colas JMS para indicar la necesidad de indexar los objetos.

Los ndices se pueden dividir siguiendo un proceso conocido como index sharding, lo cual promueve ventajas de performance. En todos los casos, Lucene es quien nalmente accede al ndice, por lo que las polticas de bloqueos de archivos son las que maneja esa librera.

20 Si

bien han pasado algunos aos desde esta armacin, entendemos que el diseo de Hibernate Search no ha cambiado

sustancialmente y se sigue cumpliendo esta recomendacin

72

CAPTULO 2.

ESTADO DEL ARTE

Jerarquas de Subclasicacin y Asociaciones


HS permite la indexacin automtica de todos los atributos de la jerarqua de clases del objeto as como las asociaciones que ocurren en dicha jerarqua. Utilizando las anotaciones @IndexedEmbedded y @ContainedIn, es posible indexar grafos de objetos referenciados explcitamente o en colecciones. Esto es importante ya que un modelo rico de objetos posiblemente requiera colaboraciones, las cuales formarn un grafo de objetos compuestos. Cuando un objeto compuesto en otro es modicado, HS actualiza el ndice para que el objeto husped se actualice con la nueva informacin del objeto contenido (eso es porque HS asigna al objeto contenedor como dueo de los postings). Para generar el ndice invertido es necesario convertir las entidades del dominio a una representacin como texto. En HS esta conversin se aplica mediante puentes (bridges). Los puentes tienen la responsabilidad de convertir un tipo particular de objeto a String. Un hecho positivo de la implementacin de HS es que no obliga a la entidad en si misma a implementar una interfaz de conversin sino que inyecta una dependencia al conversor mediante el annotation @FieldBridge.

Modelos de IR y Puntajes
El modelo de IR y puntajes es heredado directamente de Lucene, por lo que HS implementa internamente un modelo vectorial. Los clculos de TF-IDF, impulsos y dems se mantienen tal como denimos en la subseccin (2.4.1). Para manejar los valores de impulso, HS implementa un annotation @Boost, el cual traslada este valor al ndice de Lucene. Para alterar la implementacin de similitud es necesario modicar directamente las clases de Lucene como DefaultSimilarity o Weight. En HS existe la posibilidad de ordenar y ltrar los resultados tal como hacamos con Lucene. Para el caso del ordenamiento se debe usar la API de Lucene mediante las clases Sort y SortField. El ltrado se resuelve tambin utilizando la API de Lucene, pero con cierta abstraccin provista por HS.

Recuperacin, Queries, Matching y Acceso a Datos


La recuperacin de objetos en HS funciona como un wrapper de una bsqueda de Lucene. Para el usuario de HS, la tarea de recuperacin se presenta como un hbrido entre el trabajo con el ORM y con Lucene. Como resultado de las bsquedas, HS retorna el objeto de dominio que considera relevante para la bsqueda. La rigurosidad con la que esto se implementa garantiza la identidad, es decir, si utilizamos el operador == entre los objeto devueltos por el ORM y HS el resultado sera true. Esto implica que existe una nica representacin de los objetos de dominio (en rigor, internamente tambin existe la representacin como Document de Lucene). Las operaciones extendidas (ver subseccin 2.1.5) de HS se resuelven utilizando el motor de IR de Lucene, por lo cual HS tiene la misma expresividad que ste. En la terminologa de Hibernate se suele utilizar el trmino hidratacin para referir al proceso de convertir objetos que slo tienen inicializados sus identicadores (deshidratados ) en los objetos completos con todos sus atributos (hidratados ). Esto es importante al trabajar con proyecciones (este concepto tambin est presente en Hibernate Core). Una proyeccin permite recuperar una forma deshidratada del objeto, en la cual slo podemos obtener (proyectar) datos que hemos almacenado en el ndice de Lucene. La proyeccin puede ser til para obtener valores del objeto sin cargarlo completamente (lo cual requiere utilizar el ORM y eventualmente cargar un grafo de objetos). Existe una discusin respecto de si el mtodo de proyeccin es mejor que una hidratacin desde el ORM ya que el segundo utiliza caches del ORM para evitar acceder al RDBMS, lo que podra resultar en una solucin an ms eciente. A la hora de procesar los textos de los atributos, HS utiliza los analizadores de Lucene, permitiendo variar la implementacin por clase o atributo. De todas formas, la utilizacin de analizadores distintos dentro de una misma clase es compleja ya que vuelve difcil efectuar las queries (porque no podemos usar un nico analizador para todos los campos).

2.4.

CASOS DE ESTUDIO

73

Una caracterstica interesante de HS es que permite variar el analizador de forma dinmica dependiendo del estado de la entidad que se indexa. Esto permite que si un objeto representa, por ejemplo, la entrada de un blog en espaol, podremos utilizar un analizador distinto que si la entrada esta escrita en hebreo. Existen algunas otras particularidades respecto de analizadores en HS para las cuales sugerimos consultar la documentacin. Otra caracterstica de HS es que permite restringir los resultados de las consultas a una entidad de negocio particular. Esto permite que una query como Batman retorne instancias de la clase Film (pelcula) pero no instancias de la clase Toy (juguete). Este comportamiento adems es polimrco, esto es, si B es subclase de A y aplicamos un ltro para los objetos de tipo A, tambin obtendremos objetos del tipo B.

Anlisis de Hibernate Search


El anlisis de esta herramienta lo diferimos hasta despus de describir la prxima herramienta (Compass Project). Al nalizar la prxima seccin haremos un anlisis conjunto y comparativo de HS y Compass.

2.4.3. Compass
Compass Project es otra herramienta que busca resolver el problema del Domain Model Search. En los
prximos apartados analizaremos esta herramienta desde perspectivas similares a las que utilizamos para analizar Hibernate Search.

Descripcin General
El objetivo de Compass es permitirnos indexar distintas fuentes estructuradas de informacin. Compass permite indexar no slo modelos de dominio sino archivos XML, representaciones JSON y otros. Al igual que Hibernate Search, esta herramienta est construida sobre Apache Lucene. Compass se compone de tres mdulos principales: Core: es responsable de implementar el sistema de mapeo de entidades, las transacciones, la API hacia el usuario y las extensiones a Lucene. Gps: se ocupa de la integracin con distintos ORM (Hibernate, JDO, JPA) y las utilidades para la indexacin de datos desde una base de datos mediante SQL. Spring: efecta la integracin entre Compass y los mdulos del framework Spring. La mayor parte de nuestra descripcin se basar en el mdulo Core y en menor medida en el Gps. Como comentamos al estudiar HS, mientras ste est dirigido a los usuarios con un modelo de dominio persistido con Hibernate o JPA, Compass presenta una visin ms generalista, admitiendo otras combinaciones de entidades y frameworks de persistencia. Veremos que Compass tiene un comportamiento intermedio entre framework y librera. En general la interaccin con Compass requiere que instanciemos la clase Compass y dirijamos el ujo de control, lo cual es propio de una librera. En situaciones como la inspeccin de los objetos y la conversin de atributos para indexacin, es la herramienta quien invoca nuestro cdigo trabajando como un framework de caja negra.

Indexacin y Modelo de Dominio


El trabajo con nuestras entidades depende de si vamos a indexar un modelo de dominio, archivos XML, JSON o el resultado de una consulta a una base de datos. Estos mapeos se implementan en cuatro modos de trabajo conocidos como OSEM (Object/Search Engine Mapping), XSEM (XML to Search Engine Mapping), JSEM (JSON Search Engine Mapping) y RSEM (Resource/Search Engine Mapping). Compass reimplementa conceptos y objetos de Lucene que permiten que nuestro trabajo tome cierta distancia de este. En particular las clases Document y Field de Lucene se respectivamente en Resource y Property.

74

CAPTULO 2.

ESTADO DEL ARTE

Indexacin OSEM (Object/Search Engine Mapping)


dominio.

Este tipo de indexacin se corresponde con

la provista por Hibernate Search y es la que ms nos interesa ya que apunta a indexar un modelo de

En el OSEM es necesario indicar qu clases y atributos son indexables mediante anotaciones de Java, conguracin XML o JSON. En esta descripcin vamos a cubrir el mtodo de anotaciones, siendo que basta con saber que el resto de los mtodos son equivalentes. Para indexar las instancias de cierta clase, se debe utilizar la anotacin @Searchable. Por defecto, cada entidad se indexa en un sub ndice separado. La anotacin @SearchableId le indica a Compass cul es el identicador de la entidad. Este identicador deber ser usado si queremos obtener la entidad real desde el ORM. Para los casos en los que es necesario que la clave de una entidad est representada por otra entidad compleja, se agrega un annotation @SearchableIdComponent, la cual traslada el mapeo de clave a la segunda entidad. Existe un tipo distinguido de clases llamadas races. Las clases races son las que efectivamente pueden ser recuperadas en una bsqueda. Esto implica que si tenemos un objeto Client que contiene un objeto Name, las bsquedas que coincidan por dicho atributo retornarn el Client. Dado que el objeto recuperado es el de la clase raz, stos estn obligados a denir un atributo @SearchableId. En trminos de independencia del modelo de dominio (ver subseccin 2.2.2), Compass introduce algunas restricciones como:

Default Constructor: es necesario para instanciar los objetos mediante Constructor.newInstance(). Este requerimiento suele estar presente en los frameworks de persistencia como Hibernate Core. Este constructor puede tener cualquier grado de visibilidad. Property Identier: toda clase raz debe poseer al menos un identicador de clave primaria.

Vemos entonces que las imposiciones sobre el modelo de dominio son bastante bsicas, siendo que la necesidad de un constructor sin argumentos es con seguridad la ms discutible. Las clases pueden denir meta datos que se indexarn de forma idntica para todas sus instancias mediante la anotacin @SearchableConstant.

Otros mtodos de indexacin (XSEM , JSEM y RSEM)

Compass permite indexar fcilmente

XML y JSON as como nos da facilidades para mapear una fuente arbitraria de datos a un Resource, el cual luego puede ser indexado. Este ltimo mapeo es til para indexar tablas de una base de datos cuando no se dispone de un modelo de dominio que acompae dicho esquema. Si bien estos modos de mapeo son tiles para algunos casos, no forman parte de la solucin al problema principal que queremos atacar (subseccin 1.1.3). Por esto en adelante hablaremos principalmente del mtodo de indexacin OSEM. Continuando con esta lnea, a continuacin vemos un ejemplo bsico:

Ejemplo 2.4.3.
Project, 2009):
1 2 3 4 5 6 7 8 9 10 11 12 13 14

La indexacin de objetos se efecta mediante una interfaz muy similar a la utilizada con

otros ORM como Hibernate Core. Veamos un ejemplo tomado de la documentacin de Compass (Compass

CompassConfiguration conf = new C o m p a s s C o n f i g u r a t i o n ( ) . c o n f i g u r e ( ) . a d d C l a s s ( Author . c l a s s ) ; Compass compass = c o n f . b u i l d C o m p a s s ( ) ; C o m p a s s S e s s i o n s e s s i o n = compass . o p e n S e s s i o n ( ) ; CompassTransaction tx = n u l l ; try { tx = s e s s i o n . beginTransaction () ; ... s e s s i o n . save ( author ) ; CompassHits h i t s = s e s s i o n . f i n d ( " j a c k l o n d o n " ) ; Author a = ( Author ) h i t s . d a t a ( 0 ) ; Resource r = h i t s . resource (0) ; ... t x . commit ( ) ;

2.4.

CASOS DE ESTUDIO

75

15 16 17 18 19

} } }

catch ( Compa ssExce ption ce ) { i f ( t x != n u l l ) t x . r o l l b a c k ( ) ; finally {


session . close () ;

Las lneas 1 a 3 generan una conguracin de Compass y una fbrica de sesiones (en este caso la conguracin es programtica). La conguracin y la generacin de la fbrica de sesiones es un proceso costoso, por lo que se suele efectuar una nica vez por instancia de la aplicacin. Despus de la lnea 4 aparece el cdigo que se ocupa de abrir una transaccin, efectuar una query y obtener los resultados como objeto de dominio o

Resource

(este es el cdigo que veremos con mayor frecuencia en la aplicacin).

Compass tiene un tratamiento transaccional del ndice, el cual requiere una demarcacin programtica de las transacciones. Los niveles de aislamiento provistos por Compass son: read_commited, lucene y async. En los prximos apartados detallaremos la semntica de estos modos. Como vimos en el ejemplo (2.4.3), el estilo de programacin para la actualizacin del ndice es muy similar al de los ORM como Hibernate. Asimismo, la tarea de recuperacin es similar al trabajo con Lucene. Segn los autores de Compass, estos dos hechos son una estrategia para facilitar la adopcin de Compass por parte de quienes ya trabajan con Apache Lucene y los ORM tipo Hibernate Core.

Procesos de Indexacin
Compass permite la indexacin programtica utilizando la interfaz CompassSession as como la indexacin automtica mediante el mdulo Gps. El mdulo Gps permite indexar de forma transparente un dispositivo de tipo CompassGpsDevice. Dos ejemplos de dispositivos pueden ser Hibernate o iBATIS. El Gps puede indexar todos los datos del dispositivo (eventualmente un RDBMS) as como estar a la escucha de eventos y replicar lo que sucede en el ORM hacia su ndice. El ndice en Compass est formado por un conjunto de subndices. Cada subndice contiene exactamente un ndice de Lucene (el cual internamente adems contiene segmentos generacionales). Para garantizar la transaccionalidad, las operaciones de escritura bloquean los subndices (por lo cual es til contar con una buena dispersin de entidades entre los subndices). Dentro de un mismo subndice, la exclusin mutua sobre los segmentos se resuelve utilizando los mecanismos de bloqueos nter e intra procesos de Apache Lucene. Compass permite utilizar distintos tipos de transacciones mediante transaction managers (TM). Un TM es encargado de proveer semnticas de consistencia en la lectura y escritura del ndice. Los TM ms discutidos en la documentacin son: read_commited, lucene y async. El TM read_commited garantiza que las transacciones slo ven cambios conrmados en el ndice (con excepcin de los cambios que la propia transaccin est llevando a cabo). Este TM bloquea el subndice slo al efectuar una operacin de escritura. El siguiente TM conocido como lucene, es similar al read_commited con la diferencia de que los cambios hechos por la transaccin no son visibles por ella hasta conrmarse. Estos TM son similares al modo de indexacin online que comentamos junto a HS. El TM async permite que un hilo en paralelo tome la tarea de indexacin (es decir, el mtodo commit() retorna sin conrmar realmente la escritura), lo que relaja la semntica de consistencia. La documentacin de Compass tambin habla de otros niveles transaccionales conocidos como mt, search y tc. En particular el TM tc (terracota ) funciona de manera similar al modo de indexacin oine que discutimos en HS, permitindonos efectuar una indexacin diferida respecto de la conrmacin de la sesin. Al efectuar bsquedas, podemos trabajar fuera de una transaccin pidiendo instancias de CompassDetachedHits (el cual no permite escribir en el ndice).

Jerarquas de Subclasicacin y Asociaciones


Dado que la subclasicacin es una herramienta muy importante en los diseos de objetos, Compass soporta la indexacin de jerarquas de entidades anotadas con @Searchable. Cuando se indexa una entidad

76

CAPTULO 2.

ESTADO DEL ARTE

de la parte inferior de la jerarqua, todos los campos anotados de la parte superior de la jerarqua se heredan automticamente. Una propiedad interesante soportada por Compass es la capacidad de indexar entidades que no fueron anotadas pero que su jerarqua contiene en sus capas superiores clases anotadas con @Searchable. En estos casos, la indexacin slo trabaja sobre los campos anotados en la parte superior de la jerarqua, mientras que la bsqueda recupera y entrega objetos a partir de los atributos de toda la jerarqua. Tal como suceda con HS, Compass tambin permite indexar clases compuestas. Si queremos indexar una

asociacin debemos anotarla con @SearchableProperty. Esta anotacin permite indexar automticamente
objetos de tipo String, primitivos de Java (int, oat, double, etc.), java.util.Date y java.util.Calendar. Si tenemos una asociacin entre objetos anotados como @Searchable y requerimos que la recuperacin de uno de ellos tambin recupere (hidrate) el otro, podemos anotar la asociacin con @SearchableReference. Este mecanismo permite utilizar lazy-loading para evitar recuperar grafos extensos desde el ndice. Para resolver las asociaciones circulares existe una anotacin @SearchableParent, la cual previene a Compass de tal situacin. Cuando estamos asociando objetos anotados con @Searchable, podemos lograr que una bsqueda que debera retornar el objeto contenedor tambin recupere el objeto contenido. Para lograr este efecto disponemos de la anotacin @SearchableComponent. En ocasiones una entidad contiene una lista o un mapa que permite implementar algo as como una clase con atributos variables. En ciertos casos sos elementos deben ser indexados como si fueran atributos concretos, por lo que Compass permite resolver dinmicamente el nombre y el valor de esos atributos dinmicos utilizando la anotacin @SearchableDynamicProperty.

Modelos de IR y Puntajes
Analizando la documentacin de Compass (Compass Project, 2009), el modelo de IR y puntajes ocupa un lugar relativamente pequeo en comparacin con las caractersticas de transaccionalidad. Este hecho tambin se reeja en la herramienta, la cual se limita a utilizar el modelo de similitud de Lucene. Al igual que con HS, es posible utilizar la API de Lucene para modicar las frmulas de similitud y efectuar ordenamientos basados en atributos especcos. Desde el punto de vista de la conguracin, Compass permite denir un valor de impulso para el algoritmo de similitud de Lucene mediante la anotacin @SearchableBoost, la cual es idntica al annotation @Boost de HS.

Recuperacin, Queries, Matching y Acceso a Datos


Compass implementa directamente el modelo de consultas de Lucene envolvindolo en un objeto de tipo CompassQuery. Las consultas que se pueden efectuar tienen exactamente la misma expresividad que las de Lucene, excepto por pequeos agregados como mejoras al sistema de consultas de rangos. Un aspecto central que distingue la forma de trabajar de Compass es el mtodo de hidratacin de los resultados. La hidratacin depende de si activamos o no el marshalling. Cuando el marshalling est activo, los datos necesarios para hidratar el objeto se obtienen desde los campos almacenados en el ndice invertido. Esto implica que para recuperar los objetos de dominio tenemos dos caminos: utilizar marshalling para hidratar el objeto en base a la representacin del ndice o recuperar desde el ndice los identicadores para luego consultar nuestro ORM. Es inmediato notar que el marshalling tiene impacto sobre el tamao del ndice de Lucene, el consumo de memoria y la velocidad del sistema. Por esto tambin es posible escoger la solucin de compromiso ms adecuada al problema efectuando un marshalling parcial del objeto. Cuando efectuamos un marshall parcial, los atributos que no pueden recuperarse se cargan con un valor null. Eventualmente, tambin es posible no hacer marshalling y trabajar directamente sobre los objetos de tipo Resource. Como es de esperar, la expresividad de las consultas es la misma que la de Apache Lucene. Si bien Compass posee objetos de tipo Resource, la hidratacin permite obtener como resultado de una bsqueda nuestro objeto de dominio.

2.4.

CASOS DE ESTUDIO

77

Internamente Compass utiliza analizadores compatibles con los Analyzer de Lucene. Es factible escoger el analizador en funcin del atributo que se est indexando mediante la anotacin @SearchableAnalyzer. As como vimos que podemos utilizar un objeto CompassDetachedHits, la implementacin ms comn utilizar el envoltorio del objeto Hits de Lucene llamado CompassHits. Esta reimplementacin del objeto de Lucene agrega el comportamiento necesario para trabajar en el entorno transaccional de Compass. Al estudiar las tcnicas de operaciones extendidas (subseccin 2.1.5), vimos que puede ser util contar con un motor de correcciones o sugerencias soportado por un tesauro. Compass provee este servicio de sugerencias simulando el Did you mean que ofrecen buscadores como Google. El proceso de generacin de sugerencias corre en segundo plano, reconstruyendo peridicamente el ndice de correcciones.

Ejemplos
En este apartado vamos a ver algunos casos concretos de trabajo con Compass (los ejemplos son mayormente adaptaciones de muestras y tests JUnit que acompaan a la herramienta).

Ejemplo 2.4.4 (Conguracin e Indexacin de un Objeto de Dominio).


1
CompassConfiguration config = new

En este ejemplo vemos (a) cmo

se construye la conguracin de Compass y (b) se opera con los objetos de dominio.


CompassConfiguration () . configure (

" / o r g / compass / s a m p l e / l i b r a r y / compass . c f g . xml " ) . a d d C l a s s ( A u t h o r . c l a s s ) . a d d C l a s s ( A r t i c l e . c l a s s ) . a d d C l a s s ( Book . c l a s s ) ;

2 3 4 5

compass =

c o n f i g . buildCompass () ;

compass . g e t S e a r c h E n g i n e I n d e x M a n a g e r ( ) . d e l e t e I n d e x ( ) ; compass . g e t S e a r c h E n g i n e I n d e x M a n a g e r ( ) . c r e a t e I n d e x ( ) ; c o m p a s s T e m p l a t e = new CompassTemplate ( compass ) ;

La lnea nmero 1 genera la conguracin desde un XML y agrega el mapeo de dos clases. La lnea nmero 2 genera el objeto compass a partir de esta conguracin, dejando el sistema listo para generar sesiones (CompassSession) o trabajar mediante un template (CompassTemplate). Las lneas 3 y 4 eliminan el ndice actual. La lnea nmero 5 genera un objeto de tipo CompassTemplate que explicaremos en breve. En el siguiente fragmento de cdigo vemos la forma transaccional de operar en Compass para almacenar dos objetos:

// generamos dos o b j e t o s de d o m i n i o
Author j a c k L o n d o n = new Author ( ) ; " Jack " , " London " ) ) ; j a c k L o n d o n . s e t I d ( new L o n g ( 1 ) ) ; j a c k L o n d o n . s e t N a m e ( new Name ( "Mr" , Calendar c . s e t (1876 , 0, 12) ; String [ ] { " american author " }) ; c = Calendar . getInstance () ;

jackLondon . s e t B i r t h d a t e ( c . getTime ( ) ) ; j a c k L o n d o n . s e t K e y w o r d s ( new w h i t e F a n g = new Book ( ) ; w h i t e F a n g . s e t I d ( new L o n g ( 1 ) ) ; w h i t e F a n g . s e t T i t l e ( " White c . s e t (1906 , 0, 1) ; remarkable String [ ] { story " jack of a fiercely "call independent of the wild " }) ; F a ng " ) ;

whiteFang . s e t P u b l i s h D a t e ( c . getTime ( ) ) ; w h i t e F a n g . s e t S u m m a r y ( " The creature of the wild ") ; london " , w h i t e F a n g . s e t K e y w o r d s ( new

j a c k L o n d o n . a ddB ook ( w h i t e F a n g ) ;

// comienza l a i n t e r a c c i n con Compass


CompassSession
try

session

= compass . o p e n S e s s i o n ( ) ;

CompassTransaction { tx =

tx = null ;

session . beginTransaction () ;

78

CAPTULO 2.

ESTADO DEL ARTE

s e s s i o n . save ( jackLondon ) ; s e s s i o n . save ( whiteFang ) ; t x . c o mm i t ( ) ; }


catch if

( Exception != e; {
null )

e) {

{ }

( tx

tx . r o l l b a c k () ;

th row

} }

finally

session . close () ;

Si no queremos encargarnos de abrir y cerrar la sesin, podemos utilizar una colaboracin que responde al patrn de diseo Template (Gamma et al., 1995): compassTemplate . s a v e ( jackLondon ) ; En este ltimo caso Compass fue el responsable de abrir la sesin, conrmarla y cerrarla, actuando como un framework de caja negra. Si quisiramos efectuar una operacin ms compleja utilizando este patrn, podemos hacer que colaboren CompassCallbackWithoutResult y CompassTemplate como en el siguiente fragmento de cdigo: c o m p a s s T e m p l a t e . e x e c u t e ( new
protected void

CompassCallbackWithoutResult ()

{
throws

doInCompassWithoutResult ( CompassSession {

session )

// cargamos un " j a c k l o n d o n "


Author ; author = ( Author ) s e s s i o n . l o a d ( Author . class , jackLondon . g e t I d () )

CompassException

// y su l i b r o " w h i t e f a n g "
Book w h i t e F a n g = ( Book ) s e s s i o n . l o a d ( Book . c l a s s , whiteFang . g e t I d ( ) ) ;

// borramos a l a u t o r y a su l i b r o ( n i c a m e n t e d e l n d i c e )
s e s s i o n . d e l e t e ( author ) ; s e s s i o n . d e l e t e ( book ) ; } }) ; A continuacin efectuamos el anlisis de Hibernate Search y Compass Project.

2.4.4. Anlisis de Hibernate Search y Compass


En esta subseccin analizamos HS y Compass buscando los siguientes objetivos:

entender las decisiones de diseo que se tomaron, identicar sus debilidades y fortalezas, establecer un anlisis comparativo entre ellas.

Este aprendizaje permitir que nuestro motor de bsqueda adopte sus mejores prcticas y evite sus caractersticas no deseables. A medida que avancemos sobre cada tema vamos a formalizar la discusin mediante proposiciones, las cuales expresan los criterios que surgen del anlisis de las herramientas. Estas proposiciones quedarn completas cuando tratemos la propuesta de solucin, donde agregaremos casos y aspectos que no han sido cubiertos por HS y Compass.

Caractersticas Generales
Tanto HS como Compass buscan resolver el problema de indexacin y recuperacin de informacin de un modelo de dominio envolviendo Apache Lucene para que pueda indexar y recuperar objetos de un dominio.

2.4.

CASOS DE ESTUDIO

79

La principal crtica que podemos formular hacia HS y Compass es que no aprovechan al mximo el hecho de trabajar con objetos de dominio por sobre los documentos de Lucene. El hecho de haber sido concebidos como un envoltorio de Lucene o un atajo para reutilizar su infraestructura ha importado vicios del mundo de los motores de bsqueda orientados a texto plano o documentos. En los prximos apartados veremos cmo la delegacin de trabajo sobre Lucene (orientado a documentos) tiende a limitar la riqueza de indexacin y recuperacin de objetos de estas dos herramientas. Veamos algunos problemas del esfuerzo por integrarse con Lucene:

Abstraccin Incompleta: a pesar de la sosticacin de estos envoltorios, an debemos conocer los conceptos principales y funcionamiento de Lucene. Esto ocurre principalmente en HS, donde nos encontramos con grados de abstraccin propios del trabajo con Lucene. Por ejemplo, si en HS queremos efectuar una bsqueda, debemos instanciar explcitamente un objeto Query de Lucene. Otro ejemplo que impacta tanto a Compass como a HS es la inspeccin fsica de los ndices, la cual requiere utilizar inspectores de ndices de Lucene como Luke. Infraestructura Correctiva: en HS y Compass se construyen infraestructuras cuyo nico propsito es evitar limitaciones de Lucene. Por ejemplo, las tcnicas de particin de ndices en HS y Compass tienen por objetivo mejorar aspectos negativos de la implementacin del ndice de Lucene (como los bloqueos). Otro caso es la optimizacin de los ndices, la cual propaga decisiones de conguracin hasta las capas de HS y Compass por ms que son problemas exclusivos de Lucene. Es decir, estas infraestructuras estn condicionadas por forzar la reutilizacin a bajo nivel de Lucene. Desaprovechamiento Estructural y Semntico: al momento de implementar las frmulas de similitud, ninguna de las dos herramientas toma sucientemente en cuenta las interrelaciones entre objetos y su riqueza estructural. Ms adelante veremos cmo esta riqueza estructural podra traducirse en consultas jerrquicas como las de XML retrieval (ver Manning et al., 2008). Tcnicas como PageRank y HITS (subseccin 2.1.6) tampoco estn aprovechadas. Esta no es una limitacin necesaria de las herramientas sino que existe por el uso directo de las frmulas de similitud de Lucene, el cual se limita a implementar zonas y campos (ver subseccin 2.1.6).

Es preciso comentar que en ninguna de las dos herramientas plantea como objetivo primordial el ocultamiento de Lucene. Sin embargo, veremos muchos ejemplos en los cuales en vez de trabajar con un framework de indexacin de objetos terminamos hacindolo con dos herramientas: una librera de indexacin y un envoltorio de sta. Un ejemplo de esta dualidad aparece en HS, el cual obliga a elegir una estrategia de lectura del ndice (shared, not-shared o custom). Para elegir esta estrategia es necesario comprender que los ndices de Lucene mejoran su performance luego de un tiempo de precalentamiento. Es decir, para tomar una decisin debemos conocer una herramienta adicional (Lucene) que trabaja sobre una abstraccin diferente a los objetos (documentos). En general encontraremos que, respecto de HS, Compass cubre en objetos propios una mayor porcin de la API de Lucene. Dado que Lucene evoluciona independientemente de Compass y HS, existe una tensin propia de la necesidad de stos de ser compatibles con Lucene. A medida que Lucene introduce mejoras progresivas, eventualmente se vuelve incompatible con versiones previas (de hecho la versin 3.0 muestra incompatibilidades con las anteriores). Para aprovechar dichas mejoras, los dos proyectos debern producir peridicamente versiones compatibles con Lucene (en el caso de HS, adems estamos acoplados a ciertas versiones de Hibernate Core, Annotations y otros).

Comportamiento como Framework


Tanto HS como Compass dan un gran paso adelante respecto de Lucene, el cual hemos visto que tiene comportamiento de librera. En el caso de HS, la indexacin se maneja automticamente invocando cdigo del usuario cuando el framework lo decide (un ejemplo son los bridges que convierten tipos de datos). En Compass, la indexacin mediante un Gps tambin tiene el mismo estilo que el de HS. Ambos comportamientos son tpicos de un framework de caja negra, lo cual hemos visto que es un aspecto deseable (ver subseccin 2.2.1) Sin embargo, tanto HS como Compass exhiben algunos comportamientos que no son propios de un framework de caja negra sino de una librera. Como veremos en el prximo apartado, Compass permite

80

CAPTULO 2.

ESTADO DEL ARTE

indexar objetos programaticamente mediante sesiones, lo cual produce una interaccin muy similar a la que exista con Lucene (cuyo comportamiento vimos que era del tipo librera). Las situaciones que requieren manejo explcito del ujo de control no siempre son indeseables. Existen ocasiones en la cual es conveniente operar de forma explcita ignorando los eventos CUD que suceden en cada transaccin, como el caso de la indexacin en lotes. De aqu surge la siguiente proposicin:

Proposicin 1.

Es deseable que el motor de bsqueda provea un comportamiento de caja negra mediante

inversin del control (subseccin 2.2.1). Sin embargo, es importante que el usuario del framework pueda hacerse dueo del ujo de control en los puntos donde la inversin de control no sea conveniente.

Indexacin y Modelo de Dominio


En esta seccin vamos a analizar el espritu de trabajo de cada una de las herramientas en cuanto a indexacin de objetos. Las perspectivas desde las cuales necesitamos analizar la indexacin son: soporte transaccional, modelo de programacin de actualizaciones al ndice y mapeo de entidades de dominio. A la hora de la indexacin, Compass y Hibernate Search muestran losofas muy distintas en cuanto a

transaccionalidad. Compass implementa transacciones con distintos niveles de aislamiento mientras que
HS no implementa transacciones sino que simplemente utiliza los mecanismos de exclusin mutua de Lucene. Este hecho forma parte de una gran controversia entre los dos proyectos, ya que desde Compass ven la transaccionalidad como algo indispensable y desde HS como algo secundario cuya solucin debe venir desde Lucene. Las transacciones de Compass incluyen la etapa de actualizacin del ndice pero dejan fuera de su alcance

la etapa persistencia en el ORM. Esto es, las transacciones de Compass slo garantizan niveles ACID
sobre el ndice de Lucene. En el caso de Compass, dado que la hidratacin se hace desde el ndice, esta semntica puede ser importante para evitar inconsistencias entre sesiones concurrentes. Fuera del caso de Compass, esta semntica no parece brindar mayores benecios que la garanta de consistencia sobre el ndice (la cual se puede obtener mediante exclusin mutua como en HS). Los autores de Hibernate sealan que no es deseable que una falla en la indexacin produzca un rollback en la transaccin de negocio (esto es discutible caso por caso), por lo que una semntica transaccionalmente fuerte que incluya al ORM puede no ser la ms adecuada. Esto induce a una nueva proposicin.

Proposicin 2.

Si el motor de bsqueda implementa un comportamiento transaccional, el mismo ser

ajustable, permitiendo variarlo entre los niveles: Nivel 1: no hay comportamiento transaccional, slo garantas de consistencia frente al acceso concurrente al recurso. Nivel 2: dem nivel anterior pero agrega propiedades ACID para el acceso al ndice. Nivel 3: dem nivel anterior pero las propiedades ACID tienen en su alcance tanto la operacin con el ORM como con el ndice. La implementacin del nivel 1 es condicin necesaria para cualquier motor de bsqueda que quiera mantener su ndice consistente. Los niveles 2 y 3 son opcionales pero la implementacin debe permitir al usuario la eleccin de los niveles previos ya que hay aplicaciones que no requieren esta semntica.

Compass permite trabajar sobre el ndice con exibilidad mediante transacciones programticas (en adelante TP), Templates y Gps. Las TP se asemejan al trabajo con una librera ya que el usuario de la herramienta debe mantener el ujo de control, demarcar las transacciones y atrapar excepciones. El caso de las transacciones programticas debe evitarse ya que obliga a tener cdigo duplicado para crear/iniciar/cerrar la sesin y atrapar excepciones. La utilizacin de Templates es ms razonable ya que slo requiere que especiquemos operaciones entre objetos de dominio y el ndice, sin requerir el cdigo relacionado con la transaccin. Sin embargo, si utilizamos el Template para eventos de escritura sobre el ndice (toda operacin excepto las bsquedas),

2.4.

CASOS DE ESTUDIO

81

estamos desaprovechando la inversin de control de los ORM que pueden ser programados para noticarnos de eventos de persistencia. Este ltimo comportamiento por eventos est dado por el Gps, quien se registra a los eventos de persistencia y se ocupa de todo el trabajo de indexacin. Como ya comentamos, HS no soporta las transacciones de la misma forma que Compass. Por esto, en HS no encontraremos problemas de demarcacin de transacciones sino que ste indexa los objetos en base a eventos del ORM (muy similar al Gps de Compass). Sin embargo, para casos en los que las capacidades de bsqueda se agregan despus de que el sistema entra en operacin, existen un mecanismo de indexacin manual. Dado que HS no soporta transacciones, este mecanismo de persistencia manual no es exactamente comparable a las TP o a los Templates, sino que es similar a la indexacin de documentos en Lucene. Con este anlisis podemos llegar a la siguiente observacin para tener en cuenta en nuestro buscador:

Proposicin 3.

Para evitar la repeticin de cdigo, aprovechar la inversin del control y ganar compor-

tamiento de framework de caja negra, las operaciones sobre el ndice deben ocultarse al usuario del motor de bsqueda y, cuando esto no sea posible, se deben proveer Templates que eviten la repeticin de cdigo.
Existe un caso para el cual la utilizacin de Templates y eventos no es posible. Si necesitamos lanzar una excepcin propia de la aplicacin, no tenemos forma de lanzarla desde dentro del Template ya que la clusula throws debe especicar una tipo de excepcin del motor de bsqueda (o un Exception, lo cual tampoco se aconseja ya que estaramos atrapando ms casos que los que sabemos manejar). Respecto del problema del desajuste de sincronizacin (synchronization mismatch, ver subsecciones 1.1.3 y 2.4.1), utilizar TP o Templates requiere que cualquier actualizacin de los objetos de dominio se replique explcitamente sobre el ndice, lo que tiende inevitablemente a un sistema difcil de mantener y a la aparicin de errores. Esto nos lleva a la siguiente observacin:

Proposicin 4.
herramienta.

Para evitar el problema del desajuste de sincronizacin, las operaciones CUD (cre-

ate, update y delete) deben ser atrapadas por el motor de bsqueda sin intervencin del usuario de la

Existen excepciones por las cuales todava es necesario contar con Templates o TP. Una de estas excepciones es el caso de que el ORM no d aviso de los eventos CUD. Por esto el motor de bsqueda tambin debe dar un acceso similar a las TP o Templates de Compass, siempre preriendo estos ltimos. Otra excepcin a la indexacin automtica por eventos tiene que ver con la necesidad de indexar las entidades manualmente fuera de los procesos de negocio transaccionales (este caso fue analizado previamente en el apartado de Comportamiento como Framework). Un campo en el cual las dos herramientas son muy potentes es en la resolucin del structural mismatch (ver subseccin 2.4.1). Las dos implementaciones proveen mecanismos a tener en cuenta como: soporte de subclasicacin, composicin de objetos, indexacin de colecciones, reconocimiento de claves complejas, ltrado de resultados por tipo de instancia y transformacin de tipos de datos complejos. Como vimos previamente, si bien las dos herramientas logran una expresividad similar en cuanto a qu pueden indexar de un objeto y sus relaciones, la forma en la que lo hacen produce controversias acerca de cmo recuperar esta informacin (ver discusin acerca de los modelos de hidratacin en HS y Compass). Esto lo podemos enunciar en la siguiente proposicin:

Proposicin 5.

Las capacidades de indexacin y recuperacin de objetos del motor de bsqueda deben

incluir soporte para:

Subclasicacin Polimorsmo Composicin Colecciones Claves complejas Transformacin de atributos

82

CAPTULO 2.

ESTADO DEL ARTE

Restriccin de resultados por tipo de instancia

El tipo de soporte que debemos dar a cada caracterstica vara dependiendo de si estamos en un contexto de indexacin o recuperacin. Como ejemplo, podemos adelantar que reconocer colecciones durante la indexacin nos permite indexar los objetos contenidos en una lista y no la lista en s misma, mientras que al recuperar objetos podemos reconocer las listas para generar proxys que utilicen lazy loading. Estos casos se abordarn en detalle el tratar la propuesta de solucin, donde tambin incluiremos otras dimensiones como la seguridad. Al comenzar este apartado dijimos que una de las perspectivas desde la cual analizaramos el problema es el mapeo de los objetos de dominio. El trmino mapeo debe ser utilizado con mucho cuidado ya que es propenso a confusiones. En el mbito de los ORM hablamos de mapeos entre objetos y tablas de un RDBMS. En un motor de bsqueda sobre objetos, este concepto debe tomarse con pinzas ya que hay una diferencia importante entre introducir un objeto y sus atributos en el ndice vs. mapearlos a tablas. Justamente, en un motor de bsqueda sobre objetos no necesitamos garantizar que el objeto es representado elmente por el ndice, sino que slo debemos garantizar que ste permitir eventualmente obtener su identidad. Durante el mapeo de objetos en Compass, ste utiliza tres representaciones de los objetos: la entidad misma, el Resource de Compass y el Document de Lucene. Esto tambin ocurre para los atributos de una entidad, los cuales existen como objetos del dominio, objetos Property de Compass y Field de Lucene. Si bien Compass agrega dos representaciones adicionales de la entidad, a los ojos del usuario slo se expone la entidad de dominio y los envoltorios de Compass (Resource y Property). Por el lado de Hibernate Search, slo existen las representaciones como entidad del dominio y sus contrapartes de Lucene (Document y Field). Sin embargo, HS facilita el acceso a las estructuras de Lucene, dando acceso a un trabajo puramente orientado a documentos. Estas representaciones intermedias entre el dominio y el ndice slo tienen sentido en el contexto de herramientas que necesitan interactuar con Lucene o indexar fuente como archivos XML o JSON (casos en los que no estamos interesados). En un motor de bsqueda sobre objetos no hay necesidad de que el usuario maneje una abstraccin adicional a la entidad misma. Establezcamos esto en una proposicin:

Proposicin 6.

El proceso de indexacin y recuperacin debe minimizar la presencia de representaciones

no polimrcas de los objetos de dominio.

Procesos de Indexacin
Tanto HS como Compass dan soporte a procesos de indexacin online, semi-online y oine (ver seccin 3.3.4). En el caso de HS la indexacin oine se implementa a travs de colas de mensajes JMS, lo cual es una buena alternativa pero requiere que el contexto de ejecucin de la transaccin de negocio utilice JMS.

Proposicin 7.

El proceso de indexacin de objetos debe permitir elegir entre una indexacin sincrnica

con la transaccin de negocio y una indexacin asincrnica. Esta eleccin es una solucin de compromiso que deber pesar las eventuales demoras en completar una transaccin a causa de la indexacin vs. el retardo de sincronizacin entre el ndice y el RDBMS.

Recuperacin, Queries, Matching y Acceso a Datos


Excepto por optimizaciones puntuales como la implementacin de subndices o la reutilizacin de lectores, HS y Compass delegan la lectura del ndice en Lucene. Las optimizaciones son agregados de cada herramienta y slo tienen sentido en un contexto de falta de abstraccin en cuanto a ndices de Lucene. Idealmente, cualquiera de estas optimizaciones deberan ser parte de cmo el motor de bsqueda resuelve el almacenamiento de sus ndices y no un agregado para resolver deciencias de una librera subyacente. A la hora de especicar bsquedas, vimos las dos herramientas agregan a Lucene la mnima expresividad necesaria para referenciar los atributos de los objetos. Las queries se especican en texto plano siguiendo una nomenclatura hbrida que permite tanto utilizar las operaciones extendidas de Lucene (wildcards, phrase queries, etc) como referenciar los atributos mapeados a campos de Lucene.

2.4.

CASOS DE ESTUDIO

83

Existen casos en los cuales tanto el documento como la query son ricos en su estructura. Uno de estos casos es la recuperacin de XML (ver Manning et al., 2008). Para el caso de objetos, la presencia de estructuras y relaciones es an mucho ms evidente. Teniendo esto en cuenta, una caracterstica que no est presente en ninguna de las dos herramientas es la capacidad de especicar informacin de relaciones entre objetos. Veamos un ejemplo de este caso:

Ejemplo 2.4.5 (Grafo de Objetos como Query).


grafo de personas relacionadas en una red social.

En este ejemplo especicamos una query en base a un

// u s u a r i o s de n u e s t r a r e d de c o n t a c t o s P e r s o n a U s e r = new P e r s o n ( " Pablo M. Lpez " ) ; P e r s o n a n o t h e r U s e r = new P e r s o n ( " Pablo S a l a d i l l o " ) ; P e r s o n a T h i r d U s e r = new P e r s o n ( " J o s " ) ; // Creamos e s t e g r a f o de r e l a c i o n e s : // ( Pablo M. Lpez ) <> ( Pablo S a l a d i l l o ) <> ( J o s e ) a U s e r . ad dC on t ac t ( a n o t h e r U s e r ) ; a n o t h e r U s e r . a d dC on ta ct ( a T h i r d U s e r ) ; // s a l v a m o s l o s o b j e t o s en e l ORM s e s s i o n . save ( . . . ) ; // en o t r a p a r t e creamos una q u e r y en forma de g r a f o p a r a b u s c a r p e r s o n a s a d i s t a n c i a 2 de un " J o s " P e r s o n q u e r y = new P e r s o n ( " j o s e " ) ; // cramos un f i l t r o que s l o p e r m i t e r e t o r n a r o b j e t o s a e x a c t a m e n t e 2 g r a d o s de d i s t a n c i a de l a q u e r y F i l t e r f i l t e r = new S e c o n d D e g r e e F i l t e r ( ) ; // hacemos una bsqueda que d e b e r a r e t o r n a r a " Pablo M. Lpez " y NO a " Pablo S a l a d i l l o " C o l l e c t i o n <Person> s e a r c h R e s u l t s = S e a r c h . f i n d ( q u e r y , f i l t e r ) ;
Como vimos al estudiar el modelo vectorial (subseccin 2.1.4), ste nos permite recuperar documentos similares entre s. Esta caracterstica es conocida como More like this (en adelante MLT). En Compass se provee un MLT a travs de la implementacin de Lucene, la cual naturalmente no conoce nada acerca de objetos por lo que se limita a utilizar el modelo vectorial sobre la unin de todos los campos indexados. A diferencia de Compass, HS no dispone actualmente

21 de un MLT.

As como quisiramos contar con la capacidad de efectuar bsquedas a partir de un objeto teniendo en cuenta sus relaciones, tambin deberamos tener una implementacin del MLT que reciba un objeto y entregue los objetos similares. Consolidamos este anlisis en la siguiente proposicin:

Proposicin 8.

Un motor de bsqueda orientado a objetos debera permitir bsquedas a partir de objetos.

En caso de implementar una funcionalidad del tipo MLT, la misma tambin debera aceptar objetos.

La implementacin de MLT en Compass no puede cumplir con esta proposicin porque est basada en una extensin a Lucene, la cual slo conoce acerca de documentos. Como hemos comentado previamente, un aspecto que genera gran controversia entre los dos proyectos es la hidratacin de los objetos recuperados. En Compass el proceso de hidratacin se hace desde el ndice, lo que requiere almacenar todos los datos necesarios en ste. Esta solucin evita acceder a la base de datos para obtener los resultados a cambio (a) un ndice ms grande, (b) asignar al motor de bsqueda la responsabilidad de resolver la persistencia de los objetos y (c) exponerse al sincronization mismatch si las tablas se modican mediante SQL. Por el lado de Hibernate Search, la hidratacin se hace desde el ORM, con la penalidad terica de requerir acceso al RDBMS para resolver las bsquedas.

21 Al

momento de escribir este trabajo, el MLT est en la lista de funcionalidades a implementar en la versin 3.2 de la

herramienta.

84

CAPTULO 2.

ESTADO DEL ARTE

Entre las dos posiciones, la hidratacin desde el RDBMS es ms sensata en cuanto que evita tanto el sincronization mismatch como la reimplementacin de la persistencia en el motor de bsqueda. Adems, tal como dependen los autores de HS, la presencia de caches en el ORM puede evitar la necesidad de utilizar el RDBMS. Otro aspecto que se gana manteniendo la hidratacin desde el ORM es la identidad (recordar que HS garantiza que el operador == retorna true cuando se compara un mismo objeto recuperado desde el motor de bsqueda y el ORM). En base a esto enunciamos la siguiente proposicin:

Proposicin 9.

Mientras sea posible, la hidratacin de los objetos se debe delegar en el ORM para evitar

el sincronization mismach, aprovechar sus caches y mantener la identidad de los objetos.


Cabe comentar que existen casos donde podemos almacenar datos en el ndice para resolver problemas puntuales como la previsualizacin del contexto donde hubo coincidencia con la query. Este tipo de tcnicas no deben ser consideradas una hidratacin ya que tienen un propsito muy especco que no incluye sustituir polimorcamente al objeto indexado.

Modelos de IR y Puntajes
En lo que respecta al modelo de IR y la valoracin de los resultados, vimos que tanto HS como Compass utilizan las frmulas estndar de Lucene. Al igual que cuando estamos utilizando Lucene, podemos variar la implementacin de similitud. En HS es posible indicar la implementacin mediante una anotacin a nivel de clase. Para el caso de Compass, la documentacin establece la posibilidad de ajustar las clases de similitud por separado para la indexacin y la recuperacin en forma global y no por tipo de instancia como en HS. En ninguna de las dos herramientas se resuelve el problema de decidir qu tipo entidad es la que mejor responde a una necesidad de informacin sino que se utilizan las frmulas de similitud y eventualmente se ltra por tipo de instancia. Por otro lado, como vimos en la subseccin (2.1.6), en ocasiones es necesario poder valorizar los resultados no solo en base a la relevancia sino a reglas de negocio. Para implementar estas reglas en HS o Compass, debemos modicar la frmula de similitud o reordenar los resultados de bsqueda. En cualquier de los dos casos, necesitamos conocer ciertos detalles avanzados de Lucene, lo que nos induce a la siguiente proposicin:

Proposicin 10.
por conguracin.

El motor de bsqueda debe permitir incorporar reglas de puntajes y ordenamientos que

excedan la nocin de similitud del modelo de IR, dando la exibilidad de ajustar parmetros de negocio

Respecto de tcnicas de valoracin estructural global como HITS y PageRank, ninguna de las dos herramientas analiza cmo incorporarlas. Dado que estas herramientas son principalmente envoltorios de Lucene y ste no implementa tcnicas como HITS y PageRank, stas exceden el alcance de HS y Compass. Una posible implementacin bajo HS o Compass seguramente requerira de un clculo externo a la herramienta y la consecuente aplicacin de impulsos a entidades particulares. Es probable ver la solucin a este tipo de problemas desde Lucene ms que desde HS y Compass, los cuales no dedican sus principales esfuerzos a adaptar la similitud provista por Lucene a la recuperacin de objetos. Analizando la documentacin de las herramientas podemos observar que la relevancia no toma un papel central en ninguna de ellas, quizs asumiendo que Lucene es el encargado de resolver estos problemas. En caso de que tal suposicin exista, entendemos que es errnea ya que Lucene no cuenta con nociones de recuperacin de objetos, por lo que difcilmente ayude a resolver los problemas que excedan la abstraccin de documentos.

Captulo 3

Desarrollo de la Propuesta de Solucin


El objetivo de este captulo es exponer el diseo de nuestra solucin al problema de IR sobre modelos de dominio, basndonos en el anlisis del estado del arte y en las diferentes soluciones posibles al problema. La seccin 3.1 analiza el problema que queremos resolver planteando las distintas variantes de solucin, teniendo en cuenta lo que hemos estudiado en el captulo anterior acerca del estado del arte. Como es esperable de una etapa de anlisis, el objetivo de esta seccin es comprender qu queremos construir. En la seccin 3.2 explicamos la estrategia por la cual el framework de IR puede conocer el modelo de dominio, de forma de poder indexarlo y recuperar informacin sobre ste. Esta seccin funciona tambin como transicin del anlisis al diseo. En la seccin 3.3 describimos el diseo interno del framework, explicando su arquitectura y la integracin con los distintos ORM y motores de acceso a ndices invertidos. Al nalizar esta seccin, quedar explicito

cmo construimos este framework.

3.1.

Anlisis General del Problema

Luego de haber analizado el estado del arte, estamos en mejor posicin de rearmar que la recuperacin de informacin no es una tarea trivial y que no puede ser resuelta ntegramente a base de consultas a una base de datos, por lo que necesitamos un software especco que se ocupe de esto. Esto es, un framework

reusable.
Tambin vimos que las libreras de IR como Lucene efectan un muy buen trabajo pero que no son adecuadas para trabajar transparentemente sobre modelos de objetos. Por ltimo, sabemos que existen muy buenas herramientas como Compass y Hibernate Search, las cuales llevan aos de maduracin pero, al estar montados sobre Lucene, exponen el hecho de que no son un framework nico e independiente sino que son capa adaptadora de Lucene. Esta adaptacin tampoco es transparente, ya que vemos expuestos conceptos propios de Lucene y no de un framework de indexacin de objetos. An aceptando su modelo mixto, al contrastar las herramientas (subseccin 2.4.4) encontramos que proponen diferentes soluciones a cada problema, lo que nos llev a enunciar una serie de proposiciones acerca de cmo debera resolverse el problema de IR sobre objetos. En las siguientes subsecciones vamos a analizar distintos aspectos del problema y escoger la mejor solucin para nuestro framework.

3.1.1. Modelos de IR
En la subseccin (2.1.4) estudiamos tres modelos clsicos de IR: booleano, vectorial y probabilstico. Como vimos, los distintos modelos de IR son determinantes en cuanto a qu resultados entrega el motor de bsqueda y cmo los prioriza de cara al usuario. Vimos que el modelo booleano es muy simple pero todava sigue siendo aceptado en sistemas donde el usuario es un experto creador de consultas. Por otro lado, sabemos que el modelo vectorial y el probabilstico parten de orgenes distintos pero llegan a frmulas de relevancia similares. 85

86

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

Lucene implementa un hbrido entre el modelo booleano y el vectorial (ver subseccin 2.4.1), teniendo en cuenta una nocin de zonas y campos (ver subseccin 2.1.6). Para nuestro framework de IR tomamos las siguientes decisiones:

Proposicin 11

(Modelo de IR)

En esta versin del framework implementaremos tanto el modelo

booleano como el modelo vectorial.

La decisin de implementar el modelo booleano se basa en que (a) su simplicidad nos permite disear el framework comenzando por un problema ms simple que si tuviramos que comenzar por otro modelo y (b) a pesar de su simpleza es muy utilizado, an en escenarios reales. A su vez, la decisin de implementar el modelo vectorial se basa en que (a) la literatura lo respalda como un avance sobre el modelo booleano y (b) tanto los frameworks que estudiamos en la seccin (2.4) como el resto de la industria lo han adoptado logrando muy buenos resultados. Dentro de la eleccin del modelo vectorial, decidimos comenzar con la versin ms simple de las frmulas TF-IDF e ir complejizndolas a medida que sea necesario. Es preciso tener en cuenta que respecto del modelo booleano, la implementacin del modelo vectorial supone un esfuerzo extra ya que nos obliga a almacenar y mantener los valores TF-IDF para cada trmino y posting. Si bien decidimos comenzar con una implementacin de los modelos booleanos y vectorial, bien podramos querer incorporar el modelo probabilstico. En consecuencia, una de las ventajas que queremos incorporar en nuestro framework es la facilidad de variar entre modelos de IR con un mnimo impacto en la aplicacin husped (en lo posible, quisiramos variar el modelo por conguracin). Esto es especialmente importante porque nos permite escoger el modelo ms apto para nuestra aplicacin en base a los resultados que produce cada uno. Esto ltimo nos induce a la siguiente proposicin:

Proposicin 12.

Permitiremos variar el modelo sin afectar al usuario del framework.

En la prxima subseccin continuamos el anlisis abordando las tcnicas de acceso a datos y la inteligencia para lograr coincidencia entre trminos.

3.1.2. Tcnicas de Matching y Acceso a Datos


Registro Maestro e ndices Invertidos
Como sabemos de la subseccin (2.1.5) y de los casos de estudio de la seccin (2.4), tanto la literatura como los frameworks actuales sealan que los ndices invertidos son la mejor solucin disponible para la tarea de recuperacin de informacin en base a trminos. Una caracterstica innovadora que queremos incorporar en el framework es un registro maestro de objetos

indexados.
El objetivo de este registro es:

evitar reprocesar el texto del objeto para conocer sus postings al momento de actualizar/eliminar objetos, no requerir acceso al objeto persistido para que el proceso de reindexacin pueda saber qu objetos estn indexados, conocer en todo momento qu objetos deberan estar en el ndice y bajo qu trminos a los nes de resolver eventuales inconsistencias. Esto es, evitar postings fantasma que existen en el ndice pero no en la base de datos (este problema ocurre si se actualiza el objeto persistido mediante una consulta SQL).

3.1.

ANLISIS GENERAL DEL PROBLEMA

87

Respecto de implementar slo un ndice invertido, incorporar un registro maestro trae aparejado un incremento del espacio necesario en disco o memoria para alojar este registro as como un incremento en la complejidad de la solucin. Haciendo un balance de lo anterior, decidimos que es benecioso hacer el esfuerzo de incorporar este ndice ya que brinda un grado de robustez necesario para aplicaciones del mundo real. Adems de este registro maestro vamos a construir un ndice invertido tradicional, el cual debe estar sincronizado con el anterior. La pareja registro maestro-ndice invertido debe presentar una interfaz que soporte las siguientes operaciones: Operaciones sincronizadas entre ndice Invertido y Registro Maestro:

creacin de nuevos Postings eliminacin de Postings

Operaciones del ndice Invertido:

leer una Posting List obtener el valor de DF por trmino (para soportar el clculo TF-IDF) obtener el tamao del diccionario de trminos (para soportar el clculo TF-IDF)

Operaciones del Registro Maestro

obtener iterador sobre la lista de objetos indexados obtener el nmero total de objetos indexados (para soportar el clculo TF-IDF)

Especicando este conjunto de operaciones en una interfaz, podemos componentizar el par registro-ndice en una capa de acceso a datos intercambiable, permitiendo variar la implementacin por conguracin. La mayora de las operaciones anteriores son necesarias para intersectar posting lists (ver subseccin 2.1.5) y luego indicarle al usuario o al ORM qu objeto es necesario hidratar. Respecto de esto surgen dos preguntas: La hidratacin debe ser responsabilidad del framework? Cul es la forma correcta referenciar el objeto indexado de forma de poder hidratarlo? La primera pregunta la vamos a responder parcialmente en la siguiente proposicin para luego completarla al presentar los plugins de Hibernate e iBATIS (ver subseccines 3.3.4 y 3.3.4).

Proposicin 13.

La hidratacin no es responsabilidad del framework de bsqueda sino que es respons-

abilidad del framework de persistencia. Por lo tanto, nuestro framework slo mantendr la informacin necesaria para que el framework de persistencia pueda hidratar los objetos luego de ser recuperados.
Esta proposicin nos da el pi para responder a la segunda de las preguntas que nos hicimos:

Proposicin 14.

Tanto el ndice invertido como el registro maestro de objetos mantendrn referencia

de los objetos indexados mediante la combinacin de: una versin serializada del identicador del objeto a indexar y el nombre completo de la clase a la que pertenece dicho objeto. A esta combinacin la llamaremos clave del objeto.
Esta proposicin se justica por las siguientes razones: la hidratacin en los ORM siempre requiere el identicador del objeto y, de una u otra forma, la clase del objeto a recuperar.

88

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

dado que tanto el identicador original del objeto como el nombre de su clase son serializables, la

clave del objeto es serializable, lo que permite almacenar el ndice en un medio persistente.
es independiente del espacio de memoria donde se ejecuta el motor de bsqueda, esto es, los objetos indexados en una mquina virtual pueden recuperarse en otra. si el identicador del objeto implementa el mtodo equals, permite aplicar lgebra de Boole sobre las postings lists (necesario para los modelos de IR que queremos soportar). En la prxima subseccin veremos cmo construir fsicamente el ndice y el registro para soportar estas operaciones.

Construccin del ndice


Dado que vamos a soportar el modelo booleano y el vectorial, necesitamos que los ndices invertidos soporten las operaciones bsicas de cada modelo: Modelo Booleano

obtencin de postings lists a partir de un trmino operaciones AND, OR y NOT sobre los postings

Modelo Vectorial con TF-IDF (ver subseccin 2.1.4)

obtencin de postings lists a partir de un trmino operacin OR sobre postings obtencin del tamao del diccionario de trminos obtencin de la cantidad de objetos asociados a un trmino

Para soportar el modelo booleano nos alcanza con un generar un ndice invertido simple, capaz de asociar trminos y claves de objetos. Este ndice se visualiza en la gura (3.1).

(A;1) (B;1) (A;1) (B;1) (A;2)

Figura 3.1: ndice Invertido para recuperacin booleana. En este ejemplo A y B son nombres de clases y los nmeros son el identicador serializado del objeto.

El modelo vectorial requiere llevar cuenta de la cantidad de objetos indexados, la cantidad de trminos en el diccionario y la cantidad de veces que aparece un trmino en un objeto. El primer valor se puede conseguir en el registro maestro de objetos indexados, mientras que el segundo y el tercero se suelen ubicar en el ndice invertido segn se muestra en la gura (3.2).

1 2 2
tamao = 3

(A;1) tf=1 (B;1) tf=2 (A;1) tf=1 (B;1) tf=1 (A;2) tf=3
con TF por posting

Figura 3.2: ndice Invertido para recuperacin vectorial. Respecto del caso booleano, agregamos el tamao del diccionario, el nmero de postings por trmino y la cantidad de apariciones del trmino en el objeto.

3.1.

ANLISIS GENERAL DEL PROBLEMA

89

Si bien este ltimo modelo de ndice es suciente a los efectos de la recuperacin pura, al explicar ordenamiento y ltrado veremos que normalmente necesitamos conocer qu atributo del objeto es el que produjo determinado posting as como ser necesario almacenar valores en el ndice. Como vimos en la subseccin (2.1.6), en ocasiones tenemos la necesidad de ltrar los resultados y/o priorizarlos por un criterio de negocio. Para poder hacer esto dentro de los pocos milisegundos que se espera que tome una consulta, es necesario almacenar el valor de dichos atributos fuera del ORM. Este ltimo requerimiento nos obliga a retroceder en cuanto a slo mantener una referencia al objeto indexado y no superponer nuestras responsabilidades con el ORM. Sin embargo, a falta de una mejor alternativa debemos aceptar el requerimiento como tal e implementarlo de la mejor forma posible (es preciso notar que los frameworks que estudiamos en la seccin 2.4 resuelven este problema de la misma forma). Entonces tenemos que agregar al ndice de la gura (3.2) la capacidad de: indicar TF para cada atributo que contenga el trmino de la posting list almacenar los campos que intervengan en ltrado y ordenamiento Estos cambios se ven aplicados en la gura (3.3):

1 2 2
tamao = 3

A;1 B;1 B;1

fieldX.tf=1 fieldY.value=5 fieldX.tf=1 fieldY.value=5 fieldX.tf=3 fieldY.value=3

fieldA.tf=2

A;1 A;2

fieldA.tf=2

con TF y Stored Fields por posting

Figura 3.3: ndice Invertido con almacenamiento y TF diferenciado por atributo. Este ndice soporta tanto el modelo booleano como el vectorial, as como los conceptos de zonas y campos y ordenamiento/ltrado por reglas de negocio.

Si bien es verdad que el almacenamiento de campos superpone roles del ORM con los del framework de IR, si somos conservadores acerca de almacenar nicamente atributos inmutables, evitamos la desincronizacin con la base de datos, lo cual reduce el desajuste de sincronizacin (ver subseccin 2.4.1). Por el lado de las optimizaciones, este ltimo ndice invertido puede utilizar todas las tcnicas disponibles en la literatura como front coding, skip pointers y merge generacional ( ver Manning et al., 2008). Adems de las optimizaciones clsicas que podemos encontrar en la literatura, podramos enviar los atributos almacenados al registro maestro y as tener una nica versin de dichos valores, lo cual ahorra espacio en el ndice invertido y reduce la probabilidad de anomalas de actualizacin. Esta ltima optimizacin puede ser contraproducente en las bsquedas, ya que no podemos resolver la bsqueda con un nico acceso al ndice invertido. Para esta versin del framework decidimos utilizar la opcin ms simple de alojar los atributos almacenados en los postings. Si en el futuro esto probara ser una oportunidad de mejora, gracias a la componentizacin de los ndices, podramos pasar estos valores al registro maestro sin mayor impacto.

Procesamiento de Textos
El procesamiento de textos comprende toda la inteligencia para lograr coincidencia entre la consulta del usuario (query) y los textos presentes en los objetos. Los procesadores de textos deben ser simtricos en cuanto a la indexacin y la recuperacin. Es decir, necesitamos que al indexar un objeto se produzcan los mismos trminos que se producirn al analizar la query del usuario. Tanto la indexacin como la interpretacin de la query requieren dos pasos: normalizacin del texto y

delimitacin en trminos.

90

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

Las normalizacin del texto consiste en conversin a maysculas/minsculas, quitar smbolos, aplicar stemming lematizacin, corregir ortografa, quitar espacios redundantes, etc. La estrategia que elegimos para delimitar trminos es separar mediante espacios en blanco, comas, puntos y dems smbolos ortogrcos. Esta estrategia es muy efectiva en lenguajes como el espaol, pero puede ser inefectiva en otros como el alemn o el chino. Tambin pueden existir problemas en dominios donde algunas palabras pierdan signicado al ser tratadas por separado. Por ejemplo, la query X-MEN tendra menor efectividad separando los trminos por el guin ya que el primer termino (X) se tomara como un stopword y el trmino restante (MEN) tendra alto recall y baja precisin. Por este tipo de problemas locales a cada lenguaje y dominio, incluimos la posibilidad de variar el comportamiento de los procesadores de texto en forma dinmica segn el lenguaje y modicar la implementacin para soportar excepciones especcas del dominio. En la gura (3.4) presentamos un ejemplo simple de normalizacin y delimitacin:

Figura 3.4: El primer paso de normalizacin convierte las maysculas a minsculas y los caracteres acentuados a su versin sin tildes. Luego se convierten signos ortogrcos a espacios en blanco, eliminando los espacios redundantes. Por ltimo, se delimita el texto en base a los espacios blancos, en este caso se obtiene el conjunto

{brutus, conspiro, contra, caesar, su, padre}.

Nuestro framework proveer un procesador de textos por defecto que aplica eliminacin de stop words, normalizacin de textos y stemming. El procesador es un componente especialmente sensible al lenguaje, por lo que nuestra implementacin debe ser variable segn el lenguaje del texto. Adicionalmente a la normalizacin y la delimitacin, la interpretacin de la query del usuario requiere la construccin de un rbol de consulta, el cual explicaremos en el prximo apartado.

Consultas Booleanas y Vectoriales


En el apartado previo vimos que la resolucin de consultas y la indexacin requieren de normalizacin y delimitacin de trminos. Estas dos operaciones son agnsticas respecto del modelo de IR utilizado. Por otro lado, el procesamiento de consultas s depende del modelo de IR, ya que en un modelo como el booleano debemos poder utilizar conectores lgicos AND, OR y NOT . Esta caracterstica constituye diferencia la indexacin de texto de la interpretacin de consultas, la cual requiere la construccin de un

rbol de consulta.
El rbol de consulta determina el orden jerrquico de recuperacin de los trminos en el ndice as como las operaciones booleanas a aplicar entre posting lists. A continuacin vemos un ejemplo:

Ejemplo 3.1.1 (rbol de Consulta).


1 Si

Veamos el rbol de consulta para una query en el modelo booleano:

bien adoptamos la convencin de uso del trmino NOT, el trmino debera ser MINUS ya que estamos substrayendo

elementos entre conjuntos (operacin binaria) y no complementndolos (operacin unaria).

3.1.

ANLISIS GENERAL DEL PROBLEMA

91

coca cola light +OR pepsi diet +NOT zero

NOT

zero

OR

AND

AND

coca cola light

pepsi diet

En este ejemplo los rectngulos simbolizan las posting lists resultantes de cada operacin y los operadores lgicos se simbolizan con un

por delante del conector.

En primer lugar tenemos una interseccin entre los postings de las palabras lugar entre las de

pepsi diet.

coca cola light

y en segundo

Luego de estas dos intersecciones, se efecta una unin entre los resultados

de cada sub rama del rbol y por ltimo se eliminan todos los elementos presentes en la posting lists de

zero.

En el ejemplo anterior se evidenci que existen algunos estndares de facto respecto de cmo interpretar lgicamente una consulta:

la consulta se interpreta segn el sentido de lectura del idioma del usuario. Esto es, de izquierda a derecha para ingls o espaol y de derecha a izquierda para hebreo o rabe, en el modelo booleano, ante la ausencia de un conector lgico entre trminos se asume un AND booleano, en el modelo vectorial los trminos estn conectados implcitamente por un OR booleano.

Adems de los estndares de cada modelo, el rbol de consulta vara al momento de su ejecucin en dos aspectos:

el tipo de resultados que entrega cada modelo puede diferir ya que el modelo booleano slo retorna claves de objeto, mientras que el vectorial adems retorna un valor de similitud para cada resultado,

en el caso vectorial necesitamos calcular valores de TF-IDF sobre los objetos recuperados.

Resumiendo lo que vimos en este apartado:

el motor de bsqueda interpreta las consultas segn convenciones adecuadas de cada modelo de IR, la interpretacin produce como resultado un rbol de consulta.

En el prximo apartado utilizaremos estos conceptos para generar un mtodo de consulta a partir de objetos.

92

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

Consultas de Objetos
Una caracterstica original incluida en nuestro framework es la posibilidad de especicar consultas a partir

de objetos.
Al contar con un objeto como elemento de consulta, podemos aprovechar la inteligencia de mapeos (ver seccin 3.2) para generar una consulta simtrica al objeto indexado. Esta caracterstica propone salir de un esquema clsico en el cual la consulta es una frase para pasar a un esquema donde la query y el corpus son de un mismo tipo (objetos). Veamos esto aplicado a un ejemplo:

Ejemplo 3.1.2.
autos. tomvil:

Supongamos un sitio web en el cual queremos crear un buscador de opiniones acerca de

El siguiente fragmento de cdigo muestra una clase que representa una opinin particular sobre un au-

public c l a s s

CarOpinion { // e s t o s a t r i b u t o s s e n o r m a l i z a n p e r o no s e l e s a p l i c a n stemming n i e l i m i n a c i n de s t o p words S t r i n g brand , model ; // s o b r e e s t o s a t r i b u t o s a p l i c a m o s n o r m a l i z a c i n , e l i m i n a c i n de s t o p words y stemming segn e l l e n g u a j e de l a a p l i c a c i n String subject , opinion ; // s e almacena p a r a p e r m i t i r f i l t r a r l o s r e s u l t a d o s int s t a r s ; // i d e n t i f i c a d o r d e l o b j e t o long o p i n i o n I d ;

Entonces el usuario ingresa algunos valores a partir de los cuales quiere buscar opiniones:

Car Reviews
pticas Delanteras
Quiero refinar mi bsqueda: Marca Modelo Tema at brava

Buscar
Slo opiniones con calificacin mnima:

En base a estos valores, podemos generar un objeto de tipo para que retorne opiniones como las que buscamos.

CarOpinion

y proveerlo al motor de bsqueda

Veamos que si utilizamos el mismo tipo de objetos en la bsqueda e indexacin, el motor de bsqueda puede aplicar selectivamente el procesamiento de textos y normalizar para un atributo, evitando el stemming del atributo los modelos

brava

bravo

(modelos existentes de la

pticas Delanteras en ptica delantera slo model, el cual resultara en un overstemming entre marca Fiat), empeorando la precisin de la respuesta.

La capacidad de proveer objetos como consulta nos abre las puertas a una implementacin sencilla de la funcin More Like This que discutimos en la subseccin (2.4.4). Para implementar el MLT, slo

3.1.

ANLISIS GENERAL DEL PROBLEMA

93

necesitamos proveer el objeto resultante de una bsqueda, y el motor de bsqueda buscar los objetos de mayor similitud en trminos de IR. La recuperacin a partir de objetos no es un modelo completo en s mismo sino que se monta sobre el modelo vectorial. Esto es, la similitud entre objetos se realiza en base a frmulas TF-IDF.

3.1.3. Procesos de Indexacin


Las tareas de recuperacin que estamos describiendo requieren la capacidad de indexar objetos en el ndice invertido. En los apartados previos discutimos la estategia para llevar adelante esta indexacin, siendo que nos resta analizar la dinmica con la cual esto se llevar a cabo. En esta subseccin veremos tres dimensiones en las que una aplicacin puede variar sus procesos de indexacin, explicando cmo vamos a dar soporte desde el framework a cada caso de uso.

Tipos de Indexacin
En cuanto al ujo de objetos hacia el indexador, podemos trabajar en dos formas distintas:

Indexacin Automtica o por Eventos: consiste en utilizar un plugin del framework de IR (ver ltimo apartado) que interconecta los eventos CUD del ORM con el proceso indexador. Este tipo de indexacin es la recomendada ya que transparenta el uso del framework y nos garantiza consistencia entre el almacn de datos y los ndices. Indexacin Proactiva: esta es una opcin de ms bajo nivel en la cual el usuario se ocupa de inyectar los objetos al indexador para que este aplique los cambios sobre los ndices. Esta variante es ms verstil que la anterior ya que ya que puede utilizarse en ausencia de un ORM y puede combinarse con la indexacin automtica a efectos de reindexar manualmente un conjunto de objetos.

Nuestro framework permite tanto la indexacin por eventos como la proactiva. Para el caso de la indexacin automtica, proveemos plugins que reejan los eventos de los ORM Hibernate e iBATIS. En el ltimo apartado retomaremos la explicacin acerca de la funcionalidad de plugins. La segunda dimensin en la que podemos variar nuestro proceso indexador tiene que ver con el grado de

sincronismo de la indexacin:

Indexacin Online: se ejecuta sincronicamente con la transaccin de negocio, no deja que sta concluya hasta haber terminado la indexacin del grupo de objetos implicados en la transaccin. Indexacin Semi-Online: ocurre en la misma mquina virtual que desarrolla las transacciones de negocio, pero en forma asincrnica a sta. A su vez puede ser mono o multi hilo. Indexacin Oine: el proceso indexador se ejecuta en forma asincronica en una mquina virtual distinta a la transaccin de negocio.

En los prximos apartados damos algunos detalles ms de estos tres modos de indexacin. La tercera y ltima dimensin involucra la distribucin del indexador:

Indexacin Centralizada: la indexacin se efecta en un nico nodo. Indexacin Distribuida: la indexacin se efecta en distintos nodos al mismo tiempo.

En los siguientes apartados tratamos cada tipo de indexacin desde el punto de vista del sincronismo y explicamos cmo se ven afectadas por el resto de las dimensiones.

94

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

Indexacin Online

En esta modalidad el framework de IR aplica el procesamiento de objetos y los cambios sobre ndices desde el mismo hilo que invoca la indexacin, ya sea por eventos o proactivo (ver gura 3.5).

: objetos a indexar

Figura 3.5: Indexacin Online. La aplicacin efecta operaciones transaccionales que se ejecutan sincrnicamente con la indexacin de objetos.

Es preciso notar que la indexacin online no excluye la posibilidad de que varios hilos indexen un mismo objeto concurrentemente, por lo que debemos resguardar el ndice de operaciones inconsistentes. En un apartado posterior profundizaremos acerca de la concurrencia y distribucin.

La indexacin online es la modalidad ms simple, sobre todo cuando la indexacin es centralizada. Esta modalidad est dirigida a aplicaciones que pueden esperar a que se indexe un objeto antes de completar la transaccin de negocio.

Indexacin Semi-Online

En este caso el framework encola las operaciones de indexacin y las asigna a hilos trabajadores o workers. Estos workers se comportan como indexadores online paralelos que se ejecutan fuera del entorno de la transaccin de negocio (ver gura 3.6).

3.1.

ANLISIS GENERAL DEL PROBLEMA

95

: objetos a indexar

: cola de mensajes

Figura 3.6: Indexacin Semi-Online. Los hilos de ejecucin de la aplicacin y el ORM estn desacoplados de

En un escenario de tolerancia a fallas, este mtodo de indexacin se complejiza porque el sistema puede fallar luego de que la transaccin de negocio ha sido conrmada pero antes que el indexador complete su trabajo. Para resolver este problema, el indexador debera mantener un log de transacciones similar al de un RDBMS, de forma tal de poder recuperarse ante un fallo inesperado.

Indexacin Oine

La indexacin oine consiste en encolar mensajes de indexacin persistentes en una mquina virtual y aplicarlos a los ndices en forma asincrnica en otra mquina virtual. El o los procesos indexadores debern desencolar los mensajes, procesar los objetos y aplicar los cambios en los ndices. Este esquema se presenta en la gura (3.7):

96

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

: objetos a indexar

: cola de mensajes

Figura 3.7: Indexacin Oine. La mquina virtual en la que ejecuta la aplicacin persiste los datos en su almacn de datos y encola mensajes de indexacin. En forma asincrnica, la mquina virtual indexadora desencola los mensajes, procesa los objetos y aplica los cambios sobre el ndice.

Esta indexacin oine requiere la utilizacin de un sistema de mensajera, el cual debe ser asincrnico y puede o no ser persistente. Es importante que el sistema de mensajera preserve el orden en el que se producen los eventos de indexacin, de otro modo nos arriesgamos a que una ejecucin fuera de orden produzca inconsistencias en los ndices. Por otro lado, los mensajes de indexacin se pueden generar tanto por eventos como en forma proactiva. Los problemas como el ruteo, concurrencia y orden de mensajes son especialmente complejos en un entorno distribuido, por lo delegaremos la implementacin a un framework o librera que implemente el estndar de mensajera JMS de Java. La indexacin oine distribuida se trata en el siguiente apartado.

Indexadores Concurrentes y Distribuidos


Tanto las indexaciones concurrente como distribuida presentan algunas sutilezas que debemos mencionar. La indexacin concurrente y la distribuida pueden generar la ejecucin de los eventos de indexacin en un orden distinto al que se da en el ORM. Por ejemplo, si las operaciones de indexacin y desindexacin de un objeto invierten su orden, al nalizar la ejecucin los datos no habrn sido eliminados del ndice. En este escenario, podemos decir que el framework de IR es responsable de aplicar los cambios en el mismo orden que le son indicados, asumiendo que el ORM o la aplicacin proveen este orden en forma

3.1.

ANLISIS GENERAL DEL PROBLEMA

97

correcta. La combinacin de un indexador concurrente y uno distribuido nos dan cuatro escenarios donde indexar objetos: Indexador Concurrente no no si si Indexador Distribuido no si no si Problemas de Aislamiento no no si si Problemas de Orden no si si si

Los problemas de aislamiento ocurren cuando un objeto se indexa en simultaneo desde ms de un hilo, de forma tal que los cambios producidos por uno de ellos se hace visible al otro antes que el primero complete su ejecucin. Esto da lugar a problemas clsicos de los RDBMS como las lecturas fantasma (este es el caso en el que un hilo ve como vlido un dato temporal que slo existi durante el transcurso de otra transaccin). La resolucin de los problemas de aislamiento los delegamos en la capa de acceso a datos. Es decir, es responsabilidad de quien provee el sistema de almacenamiento de ndices que una escritura no se haga visible hasta tanto se conrme la operacin. Los problemas de orden se dan cuando la aplicacin ejecuta las transacciones pero nuestro framework aplica los cambios en el orden cuando el hilo

T1

T2

en orden

T1 T2 H2

T2 T1 . H1

En el caso centralizado, esto ocurre

H1

se demora procesando los objetos de la transaccin

T1 ,

de forma tal que el hilo

procesa e indexa los objetos de la transaccin

T2

antes que

termine. En el caso distribuido, adems

puede ocurrir que nuestro framework demore el encolado en un nodo, de forma que el indexador recibe las operaciones en un orden distinto al especicado por el ORM. Este ltimo problema es especialmente complejo, pero tiene algunas soluciones posibles:

la solucin ms simple es asegurar aplicativamente que un mismo objeto no es operado desde nodos distintos, o en trminos ms generales, que las operaciones de indexacin son conmutativas entre nodos (no as dentro de un mismo nodo, donde debemos dar garantas FIFO). Si podemos generar este escenario, se eliminan los problemas de ordenamiento. para el caso centralizado-concurrente, podemos establecer una cola FIFO que nos asegure un desencolado en el orden especicado por el ORM, mas un sistema de bloqueos que prevenga a un hilo de indexar objetos en conicto con otro. Por ejemplo, si el hilo comenzar, cuando

H1

bloquea los objetos antes de

H2

intenta operar sobre un objeto compartido con

H1

deber esperar a que ste

nalice su trabajo, evitando la ejecucin fuera de orden. para los casos distribuidos, debemos implementar algoritmos distribuidos que nos permitan simular (a) la cola FIFO del caso anterior y (b) el bloqueo de objetos. Los detalles de implementacin de este escenario son problemas complejos tpicos de sistemas distribuidos, por lo que exceden el anlisis que queremos dar al caso. Sin embargo, es preciso notar que podemos evitar algunos problemas si contamos con una herramienta centralizada como un RDBMS, el cual nos puede facilitar la generacin de nmeros secuenciales y el bloqueo de objetos mediante tablas de bloqueos.

En aplicaciones en las cuales los objetos son relativamente simples, podemos paralelizar la indexacin simplemente partiendo el espacio de claves del objeto en particiones disjuntas e indexando cada lote por separado. En estos casos, los dos problemas anteriores desaparecen. En general los escenarios donde tenemos que indexar objetos suelen ser ms benignos y no es necesario considerar la indexacin de objetos cruzados entre nodos o al menos no al mismo tiempo.

Reindexacin
Si los objetos de la aplicacin se actualizan por un circuito externo al aplicativo (por ejemplo, mediante consultas SQL), el ndice tender a divergir respecto del contenido real de los objetos. Este problema se puede resolver utilizando un proceso reindexador.

98

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

Para reindexar un objeto es necesario (a) eliminar los postings del objeto previo y (b) indexar los nuevos postings. Para eliminar los postings del objeto anterior entra en juego el registro maestro de objetos, el cual conoce qu trminos gener el objeto originalmente indexado. Utilizando el registro maestro podemos ubicar los trminos viejos y eliminarlos. Por otro lado, el reindexador necesita saber qu objetos hay que reindexar, lo cual debe quedar a cargo de la aplicacin o quien parametrice dicho proceso. En el captulo 4 veremos que no es necesario proveer un reindexador genrico ya que el cdigo ligado al motor de bsqueda es trivial.

Plugins
Como explicamos al principio de esta subseccin, tenemos la intencin de componentizar algunas partes del framework, de forma de poder cambiar su implementacin por conguracin sin impacto en el cdigo de la aplicacin husped. Estos componentes sern llamados plugins. En cuanto al acceso a datos y la indexacin, tenemos tres tipos de plugins:

Plugins de Indexacin por Eventos desde ORM: se conecta con el mecanismo de eventos del ORM y adapta su interfaz para reejar los eventos CUD en los ndices. Plugins de Backend de Acceso a ndices: implementan el acceso fsico a los ndices invertidos y al registro maestro. Plugins de Indexacin Oine: conecta el framework de IR con el proveedor del servicio de colas de mensajes.

Los plugins se pueden congurar y asocian a las clases que los requieren por medio de inyeccin de dependencias. En el captulo 4 retomaremos este tema mostrando cmo inyectamos los plugins en una aplicacin editando archivos de conguracin.

3.1.4. Tcnicas de Puntaje y Relevancia


Hasta aqu hemos analizado qu modelos de IR se adecan al problema que estamos resolviendo, qu ndices debemos construir y qu procesamiento debemos efectuar sobre los textos. Dado que hemos sentado las bases para indexar y recuperar objetos, en esta subseccin vamos a explicar cmo priorizar y ltrar estos objetos recuperados por una query. Las tcnicas de puntajes las abordaremos desde el punto de vista de la similitud de cada modelo de IR y desde el ordenamiento por reglas de negocio, dependientes de cada aplicacin. Adems de priorizar los resultados, tambin necesitaremos aplicarles clasicacin y ltrado. La clasicacin consiste en un proceso opcional de separacin de los resultados en clases, lo cual abre las puertas a la bsqueda facetada (ver subseccin 2.1.5). El ltrado se utiliza para eliminar de la respuesta los resultados que no cumplen con una condicin dada al momento de la bsqueda. Esta funcionalidad se puede utilizar para tareas de seguridad (ltrar objetos a los que una persona no tiene acceso), para implementar reglas de negocio (por ejemplo eliminando de la respuesta objetos de cierta antigedad) o para implementar la bsqueda facetada. Notemos que tanto la clasicacin como el ltrado responden a necesidades particulares de negocio. Es decir, en general no son herramientas portables entre dominios como s lo pueden ser los modelos de IR. En los prximos apartados analizamos cmo vamos a incorporar las nociones de similitud, clasicacin y ltrado.

3.1.

ANLISIS GENERAL DEL PROBLEMA

99

Similitud

Para soportar el modelo vectorial vamos a implementar una frmula de similitud del tipo

TF-IDF. Las frmulas TF-IDF que aplicaremos tendrn la forma general:

Similitud (q, o) =
tq
donde:

idft
ao

tft,a

(3.1.1)

q o

es una query compuesta de trminos

t a
son sus atributos

es el objeto que est siendo evaluado y

Si bien esta frmula es relativamente simple, es buen punto para comenzar y luego ajustarla o reemplazarla segn el problema que estemos resolviendo. Es preciso notar que esta sencilla frmula requiere bastante informacin:

idft :

necesita el nmero de postings para

y la cantidad total de objetos indexados

tft,a :

requiere saber cuntas ocurrencias se dieron para cada trmino en cada atributo

Notemos que la ecuacin de similitud diere de la frmula de Lucene (ecuacin 2.4.1) principalmente en factores de normalizacin y en el valor de impulso que Lucene aplica a cada campo. Nuestra propuesta de implementar esta frmula simple se debe a que queremos evitar una sobre ingeniera en la frmula de similitud desde el comienzo para todos los dominios. Dado que la similitud tiene menor prelacin que los ordenamientos por reglas duras y blandas, una sobre ingeniera puede perjudicar el rendimiento y quedara oculta detrs de reglas de negocio de mayor prioridad. Sin embargo, vamos a aseguremos que el diseo del framework permita extender esta frmula para el caso en el que muestre ser inefectiva. En el captulo 4 ejemplicaremos el uso de esta frmula sobre tres dominios distintos, donde analizaremos en detalle su desempeo.

Ordenamiento y Reglas de Negocio

Como vimos en la subseccin (2.1.6), el xito de un sistema

de IR excede a la relevancia provista por el modelo de IR. Mientras el modelo de IR se ocupa de dar una solucin global al problema de la relevancia, nosotros debemos permitir implementar una solucin local a cada aplicacin mediante reglas duras y blandas (ver subseccin 2.1.6). Nuestro framework soporta la inclusin de ordenamiento por reglas de negocio previo al retorno de los objetos recuperados. El hecho de permitir un ordenamiento previo a la entrega de los resultados paginados es distintivo del framework y es importante ya que nos permite aplicar ordenamiento antes de hidratar los objetos (lo cual puede ser prohibitivo si una bsqueda retorna cientos de miles de objetos).

Filtrado

El ltrado se utiliza cuando queremos implementar algn tipo de bsqueda facetada o sim-

plemente eliminar objetos que no cumplan con ciertas condiciones (de seguridad, de antigedad, etc.) El framework provee una implementacin de algunos ltros bsicos como el ltrado por tipo de objeto (clase) y antigedad de un atributo. Mas all de estos casos puntuales, la actividad de ltrado responde siempre a un requerimiento de negocio, por lo que es responsabilidad del usuario del framework proveer los ltros. La etapa de ltrado recorre todos los objetos retornados desde los ndices, permitiendo la clasicacin

de los resultados. Esta clasicacin bien puede contar los objetos que cumplen con ciertos criterios y as
implementar bsquedas facetadas (ver subseccin 2.1.5). La actividad de ltrado necesita recorrer completamente la lista de resultados, por lo que se ejecuta en tiempo O (n). Dado que O (n log n), para reducir el ordenamiento de los resultados se ejecuta en el mejor de los casos en tiempo el tiempo total de ejecucin, el ltrado debe preceder al ordenamiento.

100

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

3.2.

Mapeo de Clases

3.2.1. Introduccin
En la seccin (3.1) recorrimos los problemas que componen un framework como el que queremos desarrollar, investigamos las variantes de implementacin y efectuamos propuestas concretas acerca de cmo resolver el problema. En esta seccin haremos una transicin del anlisis al diseo abordando los siguientes problemas: cmo indicar al framework de IR las decisiones que tomamos en cuanto a cmo queremos indexar y recuperar los objetos, cmo procesar los objetos de forma que stos se conviertan desde y hacia las posting lists. Comencemos a resolver estos problemas con una analoga: La mayora de los frameworks de persistencia automtica requieren que el programador indique cmo debe ser mapeo entre el modelo de objetos y al RDBMS. Mas all de cuan inteligente sea el framework de persistencia, el framework desconoce la semntica de cada atributo (por ejemplo, para saber qu campos deben ser persistentes o claves) y existen muchas formas de mapear un conjunto de clases. Anlogamente, un framework de IR sobre objetos tampoco puede deducir qu clases deben indexarse o qu atributos deben utilizarse para la recuperacin.

3 de indexacin tal que el framework pueda obtener informacin semntica del dominio.
indexados y recuperados. Estos tipos son llamados clases indexables.

Para resolver este problema, es necesario idear un sistema de mapeos de clases

2 que produzca directivas

Este mapeo de clases debe especicar qu tipos de objetos deben ingresar al framework de IR para ser

Adems, para poder recuperar los objetos desde los ndices invertidos e hidratar los resultados, necesitamos conocer qu atributo identica unvocamente al objeto. Estos son los identicadores de objeto. Por ltimo, es necesario especicar qu parte del objeto contiene la informacin a indexar. Estos son los

atributos indexables.
Si bien veremos que hay otras directivas ms complejas, las directivas bsicas deben determinar (a) cules son las clases indexables, (b) los identicadores de objeto y (c) los atributos indexables. A continuacin explicamos cmo se conguran los mapeos en el framework de IR para luego explicar mapeos ms avanzados.

3.2.2. Conguracin y Mapeo


El conjunto de directivas de indexacin de todas las clases indexables constituyen lo que llamamos la

conguracin del framework.


Enumeremos algunas propiedades de la conguracin: 1. Para efectuar cualquier accin de indexacin o recuperacin debe existir una conguracin activa. 2. En todo momento existe a lo sumo una conguracin activa (puede no haber ninguna). 3. Las conguraciones son modicables durante el ciclo de vida de la aplicacin sin requerir reinicios de la misma. 4. Se pueden generar programaticamente o a partir de anotaciones Java. La conguracin es un punto centralizado del framework, por lo cual lo implementamos en la clase SearchConguration siguiendo el patrn Singleton (Gamma et al., 1995).

2 En 3 Si

rigor, el trmino mapeo no debera ser usado ya que suele referir a un isomorsmo entre un modelo de objetos y un

modelo distinto como el relacional, lo cual veremos que no suceder en este caso. bien estas directivas se suelen utilizar simtricamente en la indexacin y la recuperacin, por simplicidad hablamos slo de directivas de indexacin implicando tambin la recuperabilidad de los objetos.

3.2.

MAPEO DE CLASES

101

Mapeo Programtico
Como explicamos anteriormente, el motor de bsqueda se puede congurar programaticamente o mediante anotaciones. Para el caso programtico, el programador dene los mapeos invocando los mtodos de la clase SearchConguration.

Ejemplo 3.2.1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

(Conguracin y Mapeo Programtico)

El siguiente fragmento de cdigo muestra el

mapeo programtico de una clase y un atributo mediante un test JUnit.

private c l a s s D u m m y E n t i t y W i t h A t t r i b u t e private O b j e c t a t t r i b u t e ;

@Test

public void

testMappedAttributeIsMapped () { // creamos una nueva c o n f i g u r a c i o n y obtenemos una r e f e r e n c i a a e l l a SearchConfiguration c o n f i g u r a t i o n = SearchEngine . getInstance () . newConfiguration () ; // l a e n t i d a d a mapear D u m m y E n t i t y W i t h A t t r i b u t e dummyWithAttributes = DummyEntityWithAttribute ( ) ;

new

// g e t A t t r i b u t e F i e l d e x t r a e e l campo ' a t t r i b u t e ' de una c l a s e c u a l q u i e r a F i e l d a t t r i b u t e F i e l d = g e t A t t r i b u t e F i e l d ( dummyWithAttributes ) ; // agregamos un mapeo p a r a l a c l a s e y e l a t r i b u t o c o n f i g u r a t i o n . addEmptyMapping ( dummyWithAttributes . g e t C l a s s ( ) ) . put ( a t t r i b u t e F i e l d , new M a p p e d F i e l d D e s c r i p t o r ( a t t r i b u t e F i e l d ) ) ; // v e r i f i c a m o s que e l a t r i b u t o ha s i d o mapeado A s s e r t . a s s e r t T r u e ( c o n f i g u r a t i o n . isMapped ( dummyWithAttributes . g e t C l a s s ( ) , attributeField )) ;

Analicemos las lneas ms importantes de este fragmento de cdigo: El primer paso para iniciar el trabajo se da en la lnea 8 con la generacin de una nueva conguracin. En las lneas 11 y 14 extraemos el atributo mapea programaticamente en la lnea 17. Por ltimo, la lnea 20 verica que el mapeo se haya efectuado.
En el ejemplo anterior podemos intuir que la conguracin programtica es una solucin relativamente bajo nivel. En la prxima subseccin veremos una conguracin de ms alto nivel a partir de anotaciones.

attribute

de la clase

DummyEntityWithAttributes,

el cual se

Mapeo desde Anotaciones Java


Para congurar el framework mediante anotaciones contamos con la clase AnnotationCongurationMapper. Esta clase inspecciona la estructura de la clase en busca de anotaciones propias del motor de bsqueda e internamente utiliza la interfaz programtica para generar el mapeo. Veamos un ejemplo de la conguracin por anotaciones:

Ejemplo 3.2.2.
un test JUnit.
1 2 3 4

Veriquemos que una clase anotada como indexable fue mapeada como tal utilizando

@Indexable @Test

private c l a s s

DummyIndexable {}

102

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

public void

t e s t I n d e x a b l e O b j e c t I s M a p p e d ( ) throws SearchEngineMappingException { // e l i m i n a m o s c u a l q u i e r c o n f i g u r a c i n p r e v i a y generamos una nueva SearchEngine . getInstance () . r e s e t () ; // e l o b j e t o a i n d e x a r , cuya c l a s e queremos mapear DummyIndexable dummyIndexable = new DummyIndexable ( ) ;

// creamos una nueva c o n f i g u r a c i n y obtenemos una r e f e r e n c i a a e l l a SearchConfiguration c u r r e n t C o n f i g u r a t i o n = SearchEngine . getInstance () . newConfiguration () ; // creamos e l mapeador de a n o t a c i o n e s y l e pedimos que A n n o t a t i o n C o n f i g u r a t i o n M a p p e r mapper = new A n n o t a t i o n C o n f i g u r a t i o n M a p p e r () ; // e s t e mtodo e f e c t a t o d o s l o s mapeos n e c e s a r i o s mapper . map( o b j e c t ) ; // v e r i f i c a m o s que l a c l a s e f u e mapeada y que e s i n d e x a b l e ( r e c o r d a r que una c o s a no i m p l i c a l a o t r a ! ) A s s e r t . a s s e r t T r u e ( c u r r e n t C o n f i g u r a t i o n . isMapped ( dummyIndexable . g e t C l a s s ( ) )); A s s e r t . a s s e r t T r u e ( c u r r e n t C o n f i g u r a t i o n . getMapping ( dummyIndexable . g e t C l a s s () ) . isIndexable () ) ; }
Nuevamente hagamos un anlisis de las lneas ms importantes: La lnea 1 comienza con la anotacin

@Indexable,

la cual le indica al framework que los objetos de este

tipo deben ser considerados en la indexacin. La lnea 7 renueva la conguracin, de forma de eliminar mapeos previos, siendo que la lnea 13 obtiene una instancia de la conguracin. En la lnea 16 creamos un

AnnotationCongurationMapper, quien ser el encargado de leer las anotaciones map.

de los objetos e internamente generar la conguracin programtica. Esto se materializa en la lnea 19 con la ejecucin del mtodo

Por ltimo, las lneas 22 y 23 verican que efectivamente hayamos mapeado la clase como indexable.
Como explicamos antes, dado que el mapeo desde anotaciones utiliza internamente la conguracin programtica, el poder de expresividad de las anotaciones es equivalente al anterior (aunque mucho ms sencillo). Si bien ya hemos visto cmo indicar que una clase es indexable, para constituir la clave del objeto necesitamos indicar qu atributo lo identica dentro de la jerarqua de clases. Este atributo se especica anotndolo con @SearchId. Utilizando en conjunto las anotaciones @Indexable y @SearchId podemos construir la clave del objeto, la cual ser necesaria para identicar unvocamente el objeto recuperado. La ltima anotacin bsica que nos resta presentar es la que nos indica qu atributos deben utilizarse para indexar el objeto. Esta anotacin es @SearchField. Veamos un ejemplo en el que combinamos estas tres anotaciones para efectuar un mapeo bsico:

Ejemplo 3.2.3.
@SearchField
1 2 3 4

En el siguiente fragmento de cdigo aplicamos las anotaciones

@Indexable, @SearchId

para indexar una clase de dominio:

@Indexable

private c l a s s
@SearchId

Article { i d = 1L ;

private long

3.2.

MAPEO DE CLASES

103

5 6 7 8

private

@SearchField String

abstract

= " In recent years , advances in the f i e l d of . . . " ;

En las prximas secciones veremos capacidades avanzadas de nuestro framework que nos permitirn trabajar con objetos y jerarquas complejas.

3.2.3. Mapeos Avanzados


Los usos ms simples del framework requieren mapear una clase como indexable, su identicador y los campos desde los que extraer informacin. Sin embargo, en los prximos apartados consideraremos mapeos

avanzados que nos permitirn trabajar con jerarquas de herencia, asociaciones de objetos, indexar objetos
en colecciones y muchos otros casos de uso.

Jerarquas de Herencia
En dominios que utilizan subclasicacin debemos considerar los siguientes casos:

un objeto debe poder ser indexable por pertenencia a una jerarqua de objetos indexables, los atributos de un objeto indexable deben poder repartirse a lo largo de toda la jerarqua de herencia sin requerir que todas las clases en dicha jerarqua sean indexables, en una jerarqua indexable, ciertos miembros de la jerarqua pueden querer ser excluidos de la rbol jerarqua de clases indexable.

ChildWithCascadeParent
indexacin.

Ejemplo 3.2.4

(Mapeo en Cascada y Herencia de Atributos)

En este fragmento de cdigo, la clase

hereda de su superclase la capacidad de ser indexado, as como sus atributos de

@ I n d e x a b l e ( m a k e S u b c l a s s e s I n d e x a b l e = true ) private c l a s s SuperWithCascade { @ S e a r c h I d public int i d ; @ S e a r c h F i e l d public S t r i n g someValue ; }

private c l a s s
Ejemplo 3.2.5.

ChildWithCascadeParent

extends

SuperWithCascade { }

En el siguiente fragmento de cdigo, un objeto hereda atributos de su superclase, por

ms que esta ltima no es indexable:

private c l a s s N o t I n d e x a b l e W i t h I d { @ S e a r c h I d public int i d = 1 0 0 0 ;

@Indexable ( climbingTarget = NotIndexableWithId . class ) private c l a s s I n d e x a b l e W i t h I n h e r i t e d I d extends N o t I n d e x a b l e W i t h I d { public S t r i n g a t t r i b u t e = " s o m e t h i n g " ; }

Ejemplo 3.2.6.

Este fragmento de cdigo muestra el caso en el cual una clase propaga su condicin de

indexable slo en una rama de la jerarqua de herencia:

@Indexable ( makeSubclassesIndexable = private c l a s s SuperWithCascade { @ S e a r c h I d public int i d ; }

true )

104

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

@NotIndexable } }

private c l a s s

NotIndexableLeaf IndexableLeaf

extends

SuperWithCascade {

private c l a s s

extends

SuperWithCascade {

Si bien el mapeo de jerarquas es inherentemente complejo, esta herramienta nos da el poder de expresividad necesario para controlar la indexacin de dominios con uso extensivo de subclasicacin. En el prximo apartado tratamos el caso de objetos referenciados entre s.

Asociacin de Objetos
Existen una serie de casos en los cuales el motor de bsqueda debe conocer las relaciones entre objetos, de forma de indexar indirectamente un objeto a partir de sus asociaciones. Las asociaciones entre objetos pueden requerir indexacin en los siguientes casos:

los objetos de una coleccin deben poder ser indexados a partir del objeto que tiene la referencia a la coleccin. Ejemplo: relacin entre un objeto autor y una lista de objetos libro correspondiente a sus obras. si un objeto (indexable o no) mantiene una referencia a un objeto indexable, debemos poder indexar este segundo objeto. Ejemplo: un objeto producto referenciado por un objeto orden de compra. en los casos previos debemos permitir que el objeto indexado referencie a su contenedor, a l mismo o ambos.

Ejemplo 3.2.7

(Mapeo de Asociaciones)

Veamos cmo se indican algunas relaciones de asociacin

mediante anotaciones:

@IndexableContainer DummyContainter { @ S e a r c h C o l l e c t i o n ( r e f e r e n c e=I n d e x R e f e r e n c e . SELF ) L i s t <DummyContained> o b j e c t L i s t = new A r r a y L i s t <DummyContained >() ; }

public c l a s s

En el fragmento de cdigo anterior, la anotacin

@IndexableContainer

indica al motor de bsqueda que si

bien la entidad no es indexable, debe ser inspeccionada porque contiene elementos indexables. La anotacin objeto de

y el parmetro

@SearchCollection indica que los objetos de la coleccin deben ser analizados para indexarlos reference indica que cualquier posting resultante de este anlisis debe hacer referencia al tipo DummyContained y no a DummyContainer. El parmetro reference se puede variar para que

las referencias de los postings producidos referencien al objeto contenedor o a ambos.

Seleccin de ndices
En ocasiones necesitamos segregar objetos de distinta naturaleza en diferentes ndices, tal de permitir la indexacin y recuperacin de unos y otros en forma independiente. Por ejemplo, en la subseccin (4.2.3) utilizaremos la seleccin de ndices para separar la bsqueda e indexacin de productos comerciales de la de anuncios publicitarios. La seleccin del ndice se puede hacer:

a nivel de clase, utilizando un mismo ndice para toda instancia de la clase, en forma dinmica por objeto segn el valor de un atributo o el valor retornado desde un mtodo.

Ejemplo 3.2.8.

Veamos algunos ejemplos de seleccin de ndices con annotations.

3.2.

MAPEO DE CLASES

105

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

@ I n d e a x a b l e ( indexName=" a d v e r t i s i n g " ) public c l a s s A d v e r t i s i n g { @ S e a r c h I d private Long i d ; @ S e a r c h F i e l d private S t r i n g t i t l e ; public S t r i n g h y p e r l i n k ; ... } @ I n d e x a b l e ( indexName=" p r o d u c t s " ) public c l a s s P r o d u c t { @SearchId private Long i d ; @SearchField private S t r i n g i t e m T i t l e ; }
En este ejemplo, las lneas 1 y 9 seleccionan de forma esttica los ndices de cada entidad. Veamos otro caso:

1 2 3 4 5 6 7 8 9 10 11 12

@Indexable

private c l a s s

Something {

@SearchId private I n t e g e r i d ;

private
}

@IndexSelector String indexSelector ;

private

@SearchField String value ; indexSelector


de la

En este nuevo caso, la seleccin se da en forma dinmica segn el valor del atributo lnea 8.

La separacin de objetos en distintos ndices tambin permite a la capa de acceso a datos separar los objetos indexados en diferentes tablas, archivos o estructuras de datos, lo cual puede mejorar la eciencia de dicha capa.

Identicador y Selector de Lenguaje


El identicador de lenguaje le indica al framework que los objetos de una clase poseen textos en un lenguaje determinado. Esto permite que las clases que procesan el texto de los objetos adecen su lista de stopwords, stemmer y dems elementos al lenguaje particular del objeto que tratan. Esta es una caracterstica original de nuestro framework que no suele estar presente en otros similares. Esto es muy util en casos como el desarrollo web, donde una misma clase produce objetos para sitios de pases distintos. Con esta directiva, escribimos un nico cdigo y en tiempo de ejecucin elegimos la implementacin correcta del procesador de textos. La seleccin del lenguaje se puede dar en forma general para todos los objetos de una clase o bien ser elegida objeto por objeto en base al valor de un atributo. Cuando la seleccin del lenguaje se da por un atributo, tenemos un selector de lenguaje. A continuacin vemos un ejemplo:

Ejemplo 3.2.9

(Indicador y Selector de Lenguaje )

Veamos cmo indicar el lenguaje de un objeto

mediante anotaciones:

@ I n d e x a b l e @LangId ( v a l u e="es_AR" ) private c l a s s DummyIndexableWithLangId {

106

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

@ S e a r c h I d private long i d = 0 ; @ S e a r c h F i e l d private S t r i n g t e x t = " yo u t i l i z o p a l a b r a s l o c a l e s como ' che '" ;

@Indexable

private c l a s s D u m m y I n d e x a b l e W i t h L a n g S e l e c t o r { @ S e a r c h I d private long i d = 0 ; @ L a n g S e l e c t o r private S t r i n g l a n g = "en_US" ; @ S e a r c h F i e l d private S t r i n g t e x t = " t h i s t e x t


English . " ; DummyIndexableWithLangId

s h o u l d be i n d e x e d i n

En el cdigo anterior, la clase en Argentina. Para el segundo caso,

est anotada de forma que todos los objetos

de se tipo sern procesados segn la lista de stopwords, stemmers y correcciones del espaol localizado

DummyIndexableWithLangSelector

especica un atributo que por defecto indica la

indexacin de texto en ingls localizado en los Estados Unidos, pero que puede variar objeto a objeto.

Filtrado y Ordenamiento
Cuando analizamos las tcnicas de puntaje y relevancia (ver subseccin 3.1.4), vimos que debemos dar soporte al modelo de similitud del modelo de IR, los ordenamientos por reglas duras y blandas y al ltrado y clasicacin de objetos. Para brindar este soporte, debemos indicarle al framework qu campos van a participar en estos procesos. Dado que la recuperacin booleana no incorpora una nocin de similitud intrnseca al modelo, no necesitamos almacenar ninguna informacin adicional a la clave del objeto. Sin embargo, para el modelo vectorial s debemos almacenar valores adicionales para el clculo de TF-IDF. Para esto, nuestro framework no requiere una directiva de mapeo explcito sino que automticamente ubica los valores necesarios junto a los postings y posting lists. Tratemos ahora el caso de ltrado y ordenamiento: Como explicamos en la subseccin (3.1.4), tanto el ltrado como el ordenamiento ocurren antes de la hidratacin de los resultados. Por lo tanto, el motor de bsqueda es responsable de proveer los atributos requeridos en esa etapa. Para identicar estos valores, incluimos una directiva de mapeo para atributos de ltrado y ordenamiento. Veamos un ejemplo:

Ejemplo 3.2.10 (Mapeo de Atributos para Filtrado).


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

En este extracto de cdigo mostramos cmo indicar

que cierto atributo debe utilizarse para ltrado utilizando anotaciones:

@Indexable

private c l a s s E n t i t y F o r F i l t e r i n g @ S e a r c h I d public int i d ;


@SearchField

public

String attribute ;

@ S e a r c h F i l t e r ( a c c e s s B y G e t=true )

public

Date d a t e O f B i r t h ;

public

Date g e t D a t e O f B i r t h ( ) { Calendar birthCalendar = Calendar . getInstance () ; b i r t h C a l e n d a r . s e t ( C a l e n d a r . YEAR, 1 9 8 3 ) ; b i r t h C a l e n d a r . s e t ( C a l e n d a r .MONTH, 0 3 ) ; b i r t h C a l e n d a r . s e t ( C a l e n d a r .DAY_OF_MONTH, 3 0 ) ; b i r t h C a l e n d a r . s e t ( C a l e n d a r . MINUTE, 0 ) ; b i r t h C a l e n d a r . s e t ( C a l e n d a r . SECOND, 0 ) ; b i r t h C a l e n d a r . s e t ( C a l e n d a r . MILLISECOND , 0 ) ; return b i r t h C a l e n d a r . getTime ( ) ;

3.2.

MAPEO DE CLASES

107

La clave de este ejemplo est en la lnea 7. En esta lnea especicamos que el campo al atributo puede hacerse mediante la convencin JavaBeans, llamando al mtodo

dateOfBirth (fecha de

nacimiento) debe utilizarse en tareas de ltrado y por lo tanto debe almacenarse. Notemos que el acceso

getDateOfBirth.

En este ejemplo tambin podemos ver que los objetos que utilizamos para el ltrado pueden ser objetos complejos Java, con el simple requisito de ser serializables.
Para soportar el ordenamiento por reglas el panorama es muy similar. Ya sea ltrado u ordenamiento, el framework siempre debe proveer los atributos intervinientes. A la hora de especicar dichos atributos, debemos utilizar nuevamente las directivas de mapeo. Veamos un ejemplo:

Ejemplo 3.2.11
1 2 3 4 5 6 7 8 9 10 11 12 13 14

(Mapeo de Atributos para Ordenamiento por Reglas)

En este extracto fragmento de

cdigo especicamos que un atributo participa del ordenamiento por reglas utilizando anotaciones:

@Indexable

private c l a s s S o r t E n t i t y { @ S e a r c h I d private int i d ;


@SearchSort @SearchField

private f l o a t private

price ;

String t i t l e ; id , S t r i n g t i t l e ,

public S o r t E n t i t y ( int this . id = id ; this . t i t l e = t i t l e ; this . price = price ;

float

price ) {

En este caso la clave est en la lnea 5, donde indicamos que el atributo utilizarse al aplicar el ordenamiento por reglas.

price

debe ser almacenado para

Con estos ejemplos estamos en condiciones de resumir los puntos claves del mapeo de atributos para ltrado y ordenamiento: los atributos deben almacenarse en el motor de bsqueda por utilizarse en forma previa a la hidratacin, existen dos directivas de indexacin que indican si un atributo participa del ltrado y/o del ordenamiento, las cuales son accesibles programaticamente o mediante las anotaciones @SearchSort y @SearchField. Ms adelante retomaremos este tema rerindonos a cmo disear el framework para que ltrar, clasicar y ordenar resultados sea una tarea sencilla y rpida (subseccin 3.3.5).

Procesamiento de Textos
Cuando estudiamos las tcnicas de matching y acceso a datos (subseccin 3.1.2), propusimos implementar cierta inteligencia que normalice y delimite los textos presentes en los objetos indexables. En nuestro framework esta inteligencia se puede variar a partir de directivas de indexacin, las cuales indican qu clase es la encargada de extraer el texto de los atributos, normalizarlos y generar trminos. Veamos un ejemplo:

Ejemplo 3.2.12
1 2 3 4 5 6

(Eleccin del Procesador de Textos)

En el siguiente fragmento de cdigo, elegimos el

procesador de textos para la clase utilizando anotaciones:

@Indexable @TextProcessor ( MyTextProcessor . c l a s s ) private c l a s s E n t i t y W i t h T e x t P r o c e s s o r { @ S e a r c h I d int i d = 0 ; @ S e a r c h F i e l d public S t r i n g a t t r i b u t e = "some t e x t t o be t r e a t e d " ; }

108

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

La lnea clave de este ejemplo es la nmero 2, donde indicamos al framework que debe utilizar la clase

MyTextProcessor

para la extraccin y procesamiento del texto  some

text to be treated.

Si no indicamos explcitamente un procesador de textos, el framework utiliza uno por defecto que aplica eliminacin de smbolos y stop words, normalizacin a maysculas, stemming y delimitacin de trminos por espacios.

Notas Adicionales
Cuando utilizamos un mapeo por anotaciones, todos los mapeos avanzados/directivas de indexacin se

heredan en la jerarqua de objetos. Es decir, si aplicamos un procesador de objetos o un selector de


lenguajes a una clase y sta utiliza el parmetro makeSubclassesIndexable = true, las clases descendientes aplicarn el mismo procesador de objetos o selector de lenguajes. Para evitar la herencia de directivas de indexacin podemos redenir la directiva en el nivel de la jerarqua donde queremos evitar que se aplique la directiva conictiva.

Hasta aqu explicamos qu problemas debemos resolver para generar una herramienta completa de IR sobre objetos, as como expusimos la expresividad del framework en trminos de mapeos o directivas de indexacin.

En la siguiente seccin completamos la propuesta exponiendo el diseo interno del framework y los algoritmos que dan solucin a cada uno de los elementos que analizamos.

3.3.

Diseo del Framework de IR sobre ob jetos

3.3.1. Introduccin
Como explicamos al comenzar este captulo, en esta seccin completamos la transicin del anlisis al diseo, explicando cmo hemos construido el motor de bsqueda sobre objetos.

El objetivo de esta seccin es ajustar el grado de detalle y denir el diseo del framework que presentaremos en funcionamiento en el captulo 4.

3.3.2. Arquitectura del Framework


Diseo de Capas: Indexacin
El framework se estructura en una arquitectura de capas intercambiables por conguracin.

En la gura (3.8) vemos las capas que vamos a utilizar para la indexacin.

3.3.

DISEO DEL FRAMEWORK DE IR SOBRE OBJETOS

109

Application

Indexer Service Indexing Pipeline Index Writer

Memory, etc...

Figura 3.8: Arquitectura de Capas de Indexacin. La primera capa siempre es la aplicativa, luego aparecen las capas del framework y por ltimo una seccin fsica de almacenamiento de ndices.

Analicemos cada una de estas capas:

Application: produce los eventos de indexacin, delegando la indexacin en el Indexer Service. Indexer Service: es el encargado de secuenciar el procesamiento de los objetos y asegurarse que se escriban en los ndices. El framework provee las siguientes variantes:

OnlineIndexer y SemiOnlineIndexer: cumplen las funciones que explicamos en la subseccin (3.1.3). Luego de resolver la secuenciacin y sincronizacin de procesos, delegan la indexacin en DefaultIndexerService. Ms adelante veremos que existe un servicio de indexacin oine a travs de JMS, el cual es provisto por un plugin.

DefaultIndexerService: es la terminal de todos los indexadores. Se ocupa de orquestar la conversin de objetos a postings a travs del IndexingPipeline y la escritura en los ndices a travs de los IndexWriter. Mantiene un pool de escritores abiertos para minimizar las aperturas y cierres de ndices.

Indexing Pipeline: su responsabilidad es procesar una entidad y generar un semi ndice con los postings que deben escribirse en el ndice invertido y el registro maestro. El pipeline se utiliza slo en la creacin y actualizacin de objetos, no en la eliminacin. Este proceso lo tratamos en detalle ms adelante. Index Writer: es el encargado del acceso de escritura al ndice invertido y al registro maestro.

Para visualizar mejor la solucin podemos explicitar estas interfaces en el siguiente listado de cdigo:
public interface void void

IndexerService

{
throws

public public

c r e a t e ( Object

entity )

IndexObjectException ; IndexObjectException ;

b u l k C r e a t e ( L i s t <?> d e l e t e ( Object

entity )

throws

public public

void void

entity )

throws

IndexObjectException ;
throws

b u l k D e l e t e ( L i s t <?> update ( Object

entities )

IndexObjectException ;

public public

void void

entities )

throws

IndexObjectException ; IndexObjectException ; IndexObjectException ;

b u l k U p d a t e ( L i s t <?>

entities ) entity )

throws

public public

void void

createOrUpdate ( Object

throws

b u l k C r e a t e O r U p d a t e ( L i s t <?>

entity )

throws

IndexObjectException ; }

110

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

public

interface

IndexingPipeline

{ entity )
throws

public

SemiIndex

processObject ( Object

IndexObjectException

; }
public interface void void void

IndexWriter

public public public

open ( ) ; open ( I n d e x I d close () ; w r i t e ( Term term , ObjectKey key , PostingMetadata metadata ) ; indexId ) ;

public public

void void

d e l e t e ( IndexObjectDto

indexObjectDto ) ; indexObjectDto ) ; key , PostingMetadata ObjectKey key

public public

void void

openDeleteAndClose ( IndexObjectDto o p e n W r i t e A n d C l o s e ( Term term ,

ObjectKey

metadata ) ;
public void

openWriteAndClose ( I n d e x I d metadata ) ;

indexName ,

Term

term ,

, }

PostingMetadata

Como comentamos al principio de este apartado, estas capas estn bien denidas por interfaces, por lo que podemos variar su implementacin con facilidad.

Diseo de Capas: Recuperacin


As como la etapa de indexacin cuenta con una arquitectura de capas, la etapa de bsqueda tambin cuenta con una arquitectura de este tipo. Veamos un diagrama de las capas del motor de recuperacin:

Application

Query Parser

Core Engine
Result Windowing Sorting Rules Filtering Rules IR Model Similarity (Vector Model only)

Index Reader

Memory, etc...

Figura 3.9: Arquitectura de Capas de Bsqueda. La capa aplicativa colabora con el intrprete de consultas y el motor de bsquedas. ste se compone de sub capas segn el modelo de IR correspondiente, accediendo a los ndices mediante la capa de acceso a datos (IndexReader).

3.3.

DISEO DEL FRAMEWORK DE IR SOBRE OBJETOS

111

Analicemos en detalle las capas de la gura (3.9):

Application: provee al QueryParser el texto u objeto de bsqueda para que ste lo interprete y enva la consulta al motor de bsqueda (Core Engine). Luego de la ejecucin de la bsqueda, la aplicacin recibe una lista de objetos deshidratados. Query Parser: interpreta la consulta que enva la aplicacin y colabora con los procesadores de texto para normalizar y delimitar la consulta. El Query Parser es responsable de construir un rbol de consultas adecuado al modelo de IR. Existe una implementacin del Query Parser para el modelo booleano y otra para el modelo vectorial, estas son BooleanQueryParser y VectorQueryParser. Core Engine: esta capa implementa el ncleo de la recuperacin de informacin. Existen dos implementaciones, una para el modelo booleano y otra para el vectorial, estas son: BooleanSearch y VectorSearch. Segn el modelo de IR, se recibe un objeto BooleanQuery o VectorQuery y se procede a ejecutar una serie de operaciones internas (en orden inverso):

IR Model Similarity (slo modelo vectorial): VectorSearch delega en un objeto VectorRanker la evaluacin de los puntajes correspondientes al modelo. La implementacin por defecto efecta el clculo de la frmula (3.1.1).

Filtering Rules: aplica los ltros que se especiquen. Los ltros se deben agregar a un objeto de tipo FilterChain, el cual los recorre uno a uno, eliminando los resultados que no cumplan la condicin de algn ltro. En esta etapa podemos tambin clasicar los resultados para construir una bsqueda facetada.

Sorting Rules: aqu se aplican los ordenamientos por reglas duras y blandas. Existen dos formas combinables de aplicar reglas: proveyendo una implementacin de la interfaz PreSort o una implementacin de la interfaz Comparator. En el primero caso, la implementacin de PreSort es responsable de ordenar los resultados, mientras que en el segundo caso se utiliza el algoritmo de ordenamiento de la clase Collections de Java.

Result Windowing: nalmente los resultados son segmentados en pginas segn lo especique la query.

Index Reader: recibe los pedidos de lectura de trminos, accede a los ndices y retorna las postings lists.

Ejemplo 3.3.1.
1 2 3 4 5 6

Veamos un ejemplo de cdigo que muestra la recuperacin en el caso booleano y aso-

ciemoslo con las capas de la gura (3.9).

B o o l e a n Q u e r y P a r s e r p a r s e r = new B o o l e a n Q u e r y P a r s e r ( " b o o l e a n r e t r i e v a l " ) ; BooleanQuery q u e r y = p a r s e r . g e t Q u e r y ( ) ; query . setPage (1) ; query . setPageSize (30) ; B o o l e a n S e a r c h b o o l e a n S e a r c h = new B o o l e a n S e a r c h ( query , MemoryIndexFactory . getInstance () ) ; Set<O b j e c t K e y R e s u l t > r e s u l t = b o o l e a n S e a r c h . s e a r c h ( ) ;
Este cdigo que escribimos pertenece a la capa

Application.

La lnea 1 accede a la capa de

la cual nos entrega una query sobre la cual especicamos el paginado (ver subcapa

Core Engine).

La lnea 5 accede a la capa

debe utilizar para la capa

Index Reader.

Core Engine

Query Parsing, Result Windowing de

indicndole al motor booleano qu implementacin

Por ltimo, la lnea 6 ejecuta la bsqueda y obtiene un conjunto

de resultados deshidratados (claves de objeto u

ObjectKeyResult).

Al igual que la etapa de indexacin, podemos intercambiar las capas y cambiar de modelo fcilmente. Veamos una variante en las que modicamos el motor de bsqueda y el backend de acceso a ndices.

Ejemplo 3.3.2.

Modiquemos el ejemplo (3.3.1) para permitir la recuperacin vectorial y utilizar un

lector de ndices en disco.

112

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

1 2 3 4 5 6

V e c t o r Q u e r y P a r s e r p a r s e r = new V e c t o r Q u e r y P a r s e r ( " v e c t o r r e t r i e v a l " ) ; VectorQuery query = p a r s e r . getQuery () ; query . setPage (1) ; query . setPageSize (30) ; V e c t o r S e a r c h v e c t o r S e a r c h = new V e c t o r S e a r c h ( query , BerkeleyIndexReaderFactory . getInstance () ) ; L i s t <V e c t o r R a n k e d R e s u l t > r e s u l t = v e c t o r S e a r c h . s e a r c h ( ) ;

A primera vista, las diferencias principales de este cdigo con el del ejemplo (3.3.1) es el reemplazo de la palabra Boolean por Vector. Sin embargo, hay algunos detalles que tenemos que notar:

El tipo de datos de retorno en la lnea 6 cambia tanto en el tipo de coleccin como en su contenido. Esto sucede porque la bsqueda booleana simple no aplica un modelo de similitud entre objetos, por lo tanto devuelve un conjunto de objetos (recordemos que un conjunto no tiene nocin de orden). El cambio de tipo de datos en la coleccin obedece a que en el caso vectorial los resultados contienen informacin de valoracin, cosa que no ocurre en el caso booleano.

Por otro lado, notamos que la lnea 5 cambia el uso de ndices en memoria por un ndice en disco Berkeley. Tanto el lector de ndices en memoria del ejemplo anterior como este lector de ndices Berkeley cumplen con la interfaz

IndexReader,

de forma tal que

VectorSearch

har su trabajo independientemente de cmo

se almacenen los postings. Seguramente este es uno de los ejemplos ms fuertes acerca de la simplicidad con la que podemos intercambiar capas en este diseo.

Plugins

La arquitectura de capas que mostramos en las subsecciones anteriores nos permiten generar componentes intercambiables o plugins.

Cuando hablamos de plugins nos estamos reriendo a componentes heterogneos que pueden afectar distintas partes del framework: desde intrpretes de queries hasta acceso a ndices, el comportamiento del framework es fcilmente variable por estos plugins.

Actualmente el framework dispone de cuatro plugins: ndice BerkeleyDB (subseccin 3.3.3), indexador oine JMS (subseccin 3.3.4) y los indexadores por eventos para Hibernate (subseccin 3.3.4) e iBATIS (subseccin 3.3.4).

3.3.3. Tcnicas de Matching y Acceso a Datos


Arquitectura de ndices, Posting Lists y Postings

La arquitectura de ndices se organiza en base al conjunto de interfaces de la gura (3.10):

3.3.

DISEO DEL FRAMEWORK DE IR SOBRE OBJETOS

113

Figura 3.10: Arquitectura de ndices. El diseo se desacopla en ndices y lectores. Los ndices deben implementar MasterAndInvertedIndex, mientras que los lectores hacen lo propio con las interfaces de escritura y lectura.

Veamos el rol de cada interfaz: MasterAndInvertedIndexReader y MasterAndInvertedIndexWriter: especican el conjunto de operaciones que se esperan de quien es responsable de abrir, leer/escribir y cerrar ndices. InvertedIndex y MasterIndex: representan el ndice invertido y el registro maestro. En nuestro framework no implementamos directamente estas interfaces sino que lo hacemos a travs de MasterAndInvertedIndex. MasterAndInvertedIndex: representa la combinacin de un registro maestro y un ndice invertido, tal como los hemos presentado al hacer el anlisis del problema. En nuestro framework proveemos una implementacin a travs del MemoryIndex y otra en el BerkeleyIndex (ver ms adelante el apartado acerca de BerkeleyDB). IndexReaderFactory e IndexWriterFactory: las implementaciones de estas dos interfaces son el punto de interaccin entre la aplicacin y la capa de acceso a datos. Esta es una implementacin similar al patrn de diseo AbstractFactory (Gamma et al., 1995). El hecho de contar con este juego de interfaces nos permite extender el backend de acceso a datos a partir de plugins, tal que implementndolos podemos crear ndices sobre otras tecnologas como bases de datos relacionales o archivos.

114

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

Adems de este conjunto de interfaces, el diseo de los ndices cuenta con otras entidades concretas. A continuacin explicamos las entidades que aparecen como parmetros en los mtodos de la gura (3.10):

Object Key: representa la clave del objeto tal como la denimos en la subseccin (3.1.2).

Posting List: contiene los postings asociados a un trmino, representndolos por pares (ObjectKey ; PostingMetadata), los cuales se almacenan en un mapa. El concepto representado por esta clase es el mismo que presentamos en la subseccin (2.1.5).

Posting Metadata: este objeto almacena para cada posting los datos necesarios para el ltrado, ordenamiento y valoracin por el modelo de IR. En el caso del modelo vectorial, tambin lleva cuenta del valor de TF para cada atributo del objeto.

Term: es la representacin de un trmino normalizado y delimitado. Luego del procesamiento de objetos, es la nica representacin del texto original del objeto operable por el motor de bsqueda.

Cualquier ndice que implemente las interfaces de la gura (3.10) debe representar la informacin en trminos de estos objetos desde y hacia el motor de bsqueda (por ms que internamente utilice otra representacin de datos). En las prximas subsecciones presentamos dos ndices concretos sobre las interfaces y objetos estudiados.

ndice en Memoria
El ndice en memoria es una implementacin de la interfaz MasterAndInvertedIndex que mantiene el registro maestro y el ndice invertido en memoria RAM. Esta implementacin es til para pruebas de concepto y el desarrollo de tests unitarios (como comentaremos en el captulo 4, esto es especialmente importante para nosotros ya que hicimos un desarrollo basado en pruebas). De los casos de estudio de la seccin (2.4), podemos recordar que Apache Lucene tambin implementa un ndice en memoria, el cual tambin es heredado por sus frameworks descendientes (Hibernate Search y Compass). Este ndice tambin puede ser utilizado como una representacin intermedia o buer, por ejemplo, para un almacenamiento asincrnico en un medio persistente.

ndice Berkeley DB
BerkeleyDB (Oracle, 2009a ) es una implementacin gratuita de una base de datos embebida, la cual tiene una implementacin Java que incluye soporte transaccional. Este plugin experimental se construy para dar soporte a los ndices persistentes de las aplicaciones del captulo 4, proveyendo versiones en disco del registro maestro y el ndice invertido. Como programador del plugin, BerkeleyDB nos provee una implementacin persistente de la clase HashMap de Java, la cual es una muy buena opcin para representar el mapeo entre trminos y posting lists. El diagrama de clases de este plugin es el siguiente:

3.3.

DISEO DEL FRAMEWORK DE IR SOBRE OBJETOS

115

Figura 3.11: Diagrama de clases del plugin BerkeleyDB.

Para utilizar el plugin basta con agregarlo como dependencia en el proyecto que se est desarrollando, y proveerlo al motor de bsqueda tanto al indexar como al recuperar objetos.

Procesador de Textos
Los procesadores de textos forman un componente esencial en cualquier motor de bsqueda ya que determinan en gran medida el recall y precisin del sistema. En nuestro caso, stos intervienen en la indexacin de objetos y en la interpretacin de consultas de usuarios. La interfaz que debe cumplir un procesador de textos para la indexacin es la siguiente:
public interface abstract

ObjectTextProcessor L i s t <Term>

{ extractedText ,

public

processField ( String

MappedFieldDescriptor }

fieldDescriptor ) ;

y para el caso de la interpretacin de consultas:


public interface

QueryTextProcessor

{ text , Language language ) ;

public

L i s t <Term> p r o c e s s T e x t ( S t r i n g

Analicemos cada interfaz para entender sus similitudes y diferencias:

116

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

Al momento de indexar un objeto necesitamos conocer informacin acerca de cmo fue mapeado (por ejemplo, para saber qu tipo de stemming aplicar). Dentro de la informacin de mapeo se encuentran los detalles acerca del lenguaje del objeto o del atributo, el tipo de stemming a aplicar, cmo extraer los textos de los atributos, etc. Por otro lado, al momento de interpretar una query, la interfaz slo requiere el texto de la consulta y su lenguaje. Otras caractersticas como el stemming o la eliminacin de stop words no deben pertenecer a la interfaz de estos objetos porque no son una parte esencial de un procesador de textos sino implementaciones particulares que deben congurarse por separado de la interfaz denida. Comentemos brevemente respecto de la inclusin explcita de lenguajes: Una caracterstica original de este framework es que incorpora explcitamente la nocin de lenguaje a lo largo de todas las clases de mapeos y procesamiento de textos. El hecho de conocer el lenguaje de los objetos en tiempo de ejecucin podra haber sido opcional, sin embargo, decidimos incluirlo en todo el sistema porque permite extender naturalmente el framework para efectuar operaciones como la correccin de ortografa (lo cual de otra forma requerira reconocer el lenguaje del texto original, lo cual no es trivial). Si no tuviramos una fuerte presencia de objetos que representan lenguajes, seguramente tendramos que resolver este problema por nuestra cuenta y dicultaramos las extensiones del framework, lo cual no es deseable. En esta versin del framework incluimos un procesador de textos por defecto para la indexacin ( DefaultObjectTextProcessor ) y otro para la interpretacin de consultas ( DefaultQueryTextProcessor ). Estos procesadores aplican normalizacin a maysculas, eliminacin de caracteres no alfabticos, delimitacin de trminos por espacios, eliminacin de stop words y, en caso de que corresponda, stemming snowball.

Intrprete de Consultas
En la subseccin (3.1.2) explicamos que la interpretacin de consultas comprende tanto la normalizacin y delimitacin de textos, a cargo del procesador de textos, as como la construccin del rbol de consultas. Este apartado expone el diseo de las clases encargadas de la construccin del rbol de consultas. Cada modelo de IR cuenta con su propio intrprete de consultas: en el caso booleano tenemos el BooleanQueryParser mientras que en el vectorial tenemos el VectorQueryParser. Estos intrpretes se diferencian en los algoritmos que aplican para generar el rbol de consulta, de forma de soportar sus operadores y estndares de facto (ver subseccin 3.1.2). Para soportar estas dos variantes, cada modelo complementa su rbol de consulta con un extractor de posting lists. El trabajo del extractor es:

1. leer las postings lists y generar resultados segn el tipo de objeto esperado por cada modelo,

2. recolectar desde el ndice los datos necesarios para el modelo correspondiente de IR. En el caso del modelo vectorial, buscamos el valor de DF sobre los postings recuperados.

Mas all de qu algoritmo se utilice, cada interprete lee la consulta del usuario y la traduce en una composicin de operadores lgicos AND, OR, NOT mas un operador adicional no booleano llamado RETRIEVE simplemente R. Este ltimo operador tiene la responsabilidad de leer la posting list desde el ndice y colaborar con el extractor de resultados para generar un resultado parcial de la bsqueda (ver subseccin 3.1.2). La jerarqua de clases que representa estos operadores se presenta en la gura (3.12).

3.3.

DISEO DEL FRAMEWORK DE IR SOBRE OBJETOS

117

Figura 3.12: Jerarqua de Operadores. Los operadores constituyen el rbol de consulta de una query. El nodo raz produce la ejecucin en cascada del resto de los operadores, terminando siempre en nodos hoja de tipo RETRIEVE.

La jerarqua de la gura (3.12) se organiza de la siguiente forma:

Operator: clase abstracta que dene las responsabilidades de cualquier operador. Estas responsabilidades son: entregar el trmino que los representa en una query (getOperatorTerm), efectuar su operacin (work) y redenir los mtodos hashCode e equals de la clase Object. BinaryOperator: esta clase abstracta representa un operador que a su vez contiene un operador izquierdo y derecho. Esta clase es la base de la composicin de operadores, lo cual permite la construccin del rbol de consulta. La mayora de los operadores extienden esta clase. BinarySimetricOperator: esta clase abstracta agrega a BinaryOperator la propiedad de conmutatividad. Redene los mtodos equals y hashCode para adecuarlos a su semntica. MinusOperator, OrOperator, AndOperator: estos son operadores concretos cuyos mtodos work efectan operaciones de substraccin, conjuncin y disyuncin de conjuntos. Cada uno de ellos implementa el mtodo getOperatorTerm para indicar cmo se los debe reconocer en una query. El MinusOperator es un operador simtrico no conmutativo, por lo que extiende a BinaryOperator. En cambio, OrOperator y AndOperator s son conmutativos, de forma que extienden a BinarySimetricOperator. RetrieveOperator: esta clase concreta implementa el nico operador unario de la jerarqua. El objetivo de esta clase es obtener y extraer los postings a partir del lector del ndice. El RetrieveOperator es

el nico operador hoja de esta jerarqua.


Desde el punto de vista procedural, cuando el intrprete de queries le entrega el rbol de consulta al motor de bsqueda, ste ejecuta el mtodo work del operador raz, produciendo la ejecucin en cascada de los operadores del rbol. Por ejemplo, si la raz es un operador binario, ste pedir a su trmino izquierdo los resultados de su trabajo, luego har lo mismo con el derecho y por ltimo operar sobre los conjuntos obtenidos por sus operadores izquierdo y derecho.

118

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

3.3.4. Procesos de Indexacin


En esta subseccin vamos a tratar el diseo de la parte del framework que desglosa objetos de dominio en postings del ndice invertido.

El diseo del framework separa los procesos de indexacin en tres subcapas con responsabilidades bien diferenciadas:

Dinmica de Indexacin: maneja el nivel de asincronismo entre las transacciones de negocio y la actualizacin de los ndices. Aqu tenemos los indexadores online, semi-online u oine.

Secuenciamiento de la Indexacin y Acceso a ndices: orquesta el procesamiento de objetos y la interaccin con la capa de escritura de ndices. Aqu tenemos al DefaultIndexerService.

Procesamiento de Objetos / Pipeline de Indexacin: es responsable de generar postings a partir de un objeto y su descripcin de mapeo.

Pipeline de Indexacin

El pipeline de indexacin es el encargado de implementar la lgica de generacin de postings a partir de un objeto de dominio.

Este proceso debe tener en cuenta los mapeos que expusimos en la seccin (3.2), de forma tal de producir los resultados esperados por el usuario del framework.

El pipeline de indexacin es denido de la siguiente forma:

public

interface

IndexingPipeline

{ entity )

public

SemiIndex

processObject ( Object

throws

IndexObjectException ;

La implementacin por defecto de este interfaz est dada por la clase DefaultIndexingPipeline. Al igual que otras capas del framework, el pipeline de indexacin se puede reemplazar fcilmente proveyendo otra implementacin de IndexingPipeline.

En la gura (3.13) presentamos un diagrama de actividades simplicado para la implementacin del mtodo processObject de DefaultIndexingPipeline.

3.3.

DISEO DEL FRAMEWORK DE IR SOBRE OBJETOS

119

Figura 3.13: Diagrama de actividades para el mtodo DefaultIndexingPipeline.processObject(Object entity). En este diagrama simplicado vemos las variantes de generacin del semi ndice en funcin de cmo fue mapeada la entidad.

Analizando el diagrama de actividades de la gura (3.13) vemos que la indexacin de un objeto depende en gran parte de si es indexable por s mismo y/o si es un contenedor de objetos indexables. El primer rombo de decisin del diagrama (3.13) insina la capacidad de este algoritmo de indexar jerarquas de objetos anidados. Esta capacidad se implementa mediante recursin. Para controlar que esta recursividad sea nita, cada llamado verica que el objeto actual no haya sido procesado en el rbol de llamadas del hilo actual, retornando en caso de que ello suceda. El sistema de mapeos permite adems que los objetos anidados generen postings con referencias a sus contenedores, y a su vez estos postings pueden almacenarse en un ndice distinto al del objeto contenedor. Para soportar estas caractersticas, el resultado del mtodo processObject no puede ser simplemente un conjunto de postings a aplicar en el ndice sino que debe ser una estructura ms compleja llamada semi

ndice (SemiIndex).
El semi ndice representa un mapeo a postings de los objetos que estn cursando su proceso de indexacin. Adems de sus caractersticas como estructura de datos, el semi ndice permite la operacin de fusin (merge) con otro semi ndice, tal de permitir acumular postings a medida que procesamos recursivamente una jerarqua de objetos anidados.

Indexador Online, Semi-Online & Oine


En este apartado retomamos la discusin de la subseccin (3.1.3), diseando las tres dinmicas de indexacin de objetos: indexacin online, semi-online y oine. Para crear un indexador que reeje los eventos CUD en el motor de bsqueda, debemos implementar la interfaz IndexerService. Los indexadores que vamos a presentar se ocupan de la relacin entre la transaccin

120

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

y la indexacin. La generacin de postings no es implementada por estas clases sino que se delega en otra implementacin de IndexerService. El primer indexador que vamos a comentar es el OnlineIndexer, el cual naturalmente se corresponde con el indexador online que presentamos en la seccin de anlisis. Este indexador hace algunas vericaciones simples y delega el procesamiento de los objetos en una implementacin de IndexerService (normalmente en DefaultIndexerService). El segundo tipo de indexador es el semi-online y est implementado por la clase SemiOnlineIndexer. En este modo de indexacin debemos trabajar en forma asincrnica a la transaccin de negocio, encolando los pedidos de indexacin y retornando inmediatamente el control a la aplicacin. El desencolado de estos pedidos de indexacin se realiza en forma concurrente por un grupo de hilos, los cuales se comportan como indexadores online en paralelo. Por ltimo tenemos al indexador oine. ste es similar al indexador semi-online, excepto por la diferencia de que la cola de pedidos se implementa en forma persistente y el proceso que desencola los pedidos debe ejecutarse en una mquina virtual distinta al que los encola. El indexador oine requiere de un plugin que provea la cola de indexacin persistente, siendo que nuestra implementacin est basada en JMS (ver subseccin 3.3.4). Al discutir los casos de experimentacin del captulo 4 veremos cmo variar la dinmica de indexacin con una simple conguracin de inyeccin de dependencias.

Plugin de Indexacin Oine JMS


Este plugin implementa la indexacin oine utilizando una implementacin del estndar de mensajera de Java, la tecnologa JMS ( ). La implementacin particular de JMS que utilizamos para este plugin es Apache ActiveMQ (Apache, 2009a ). Nuestra implementacin consiste en un plugin inyectable como dependencia en la capa de interaccin con el ORM. Al igual que cualquier indexador, es necesario implementar la interfaz IndexerService, lo cual hicimos en la clase JmsOineIndexer. La migracin hacia/desde el indexador oine JMS es transparente a la aplicacin ya que la implementacin de IndexerService es semnticamente equivalente al indexador online o el semi-online.

Plugin Hibernate
El objetivo de este plugin es reejar los eventos CUD del ORM en el motor de bsqueda. Para usar este plugin, debemos registrarlo como un escucha de los eventos que se producen en el ORM mediante conguracin de Hibernate. El plugin consiste en una implementacin de las interfaces de escucha de eventos de Hibernate, tal de reejar los cambios de estado de los objetos en nuestro motor de bsqueda. El principio de funcionamiento del plugin es simple: cuando un objeto se crea, actualiza o elimina un objeto, Hibernate enva a los escuchas registrados la informacin relativa a dicho evento. Esta informacin es recibida por nuestro framework, quien la reeja en los ndices.

Ejemplo 3.3.3
1 2 3 4 5 6 7 8 9

(Conguracin Programtica del Plugin para Hibernate)

Veamos cmo congurar Hi-

bernate para que utilice el plugin de indexacin por eventos.

H i b e r n a t e E v e n t I n t e r c e p t o r l i s t e n e r= new H i b e r n a t e E v e n t I n t e r c e p t o r ( new S e a r c h I n t e r c e p t o r ( new D e f a u l t I n d e x e r S e r v i c e ( new D e f a u l t I n d e x i n g P i p e l i n e ( ) , MemoryIndexWriterFactory . g e t I n s t a n c e () ) ) ) ; C o n f i g u r a t i o n c o n f i g u r a t i o n = new C o n f i g u r a t i o n ( ) . c o n f i g u r e ( ) ; c o n f i g u r a t i o n . g e t E v e n t L i s t e n e r s ( ) . s e t P r e I n s e r t E v e n t L i s t e n e r s ( new P r e I n s e r t E v e n t L i s t e n e r [ ] { l i s t e n e r }) ;

3.3.

DISEO DEL FRAMEWORK DE IR SOBRE OBJETOS

121

10 11 12 13

c o n f i g u r a t i o n . g e t E v e n t L i s t e n e r s ( ) . s e t P r e U p d a t e E v e n t L i s t e n e r s ( new P r e U p d a t e E v e n t L i s t e n e r [ ] { l i s t e n e r }) ; c o n f i g u r a t i o n . g e t E v e n t L i s t e n e r s ( ) . s e t P r e D e l e t e E v e n t L i s t e n e r s ( new P r e D e l e t e E v e n t L i s t e n e r [ ] { l i s t e n e r }) ; sessionFactory = configuration . buildSessionFactory () ; teEventInterceptor


Las lneas 1 a 6 conguran las capas de indexacin del framework (ver gura 3.8). La clase

Hiberna-

que referenciamos en la lnea 1 ser la encargada de escuchar los eventos producidos

por Hibernate y enviarlos a

SearchInterceptor.

La lnea 8 le indica a Hibernate que ya puede congurarse,

mientras que las lneas 9 a 11 son especialmente importantes porque le indican a Hibernate que debe comunicar los eventos CUD al framework de indexacin.

Plugin iBATIS
Al igual que el plugin Hibernate, el plugin para iBATIS conecta el ORM con el motor de bsqueda para que los eventos CUD generados en la aplicacin se reejen en nuestro framework. Veamos un ejemplo.

Ejemplo 3.3.4
nuestro plugin:

(Conguracin de Plugin Interceptor de iBATIS)

Veamos cmo se congura un inter-

ceptor iBATIS a partir de XML y un fragmento de cdigo. El primer paso consiste en editar el archivo XML de conguracin iBATIS para indicarle que utilice

<p l u g i n s> <p l u g i n i n t e r c e p t o r="com . j k l a s . s e a r c h . i n t e r c e p t o r s . i b a t i s . I b a t i s 3 I n t e r c e p t o r "/> </ p l u g i n s>


La clase

Ibatis3Interceptor

que denimos en esta conguracin implementa la interfaz

Interceptor

de

iBATIS, lo que le permite recibir los eventos CUD. Por ltimo, las capas de indexacin se interconectan como hicimos con el plugin de Hibernate:

new I b a t i s 3 I n t e r c e p t o r ( ) . s e t S e a r c h I n t e r c e p t o r ( new S e a r c h I n t e r c e p t o r ( new D e f a u l t I n d e x e r S e r v i c e ( new D e f a u l t I n d e x i n g P i p e l i n e ( ) ,

MemoryIndexWriterFactory . g e t I n s t a n c e () ) ) ) ;

Luego de seguir estos pasos, el framework de IR reejar en sus ndices operaciones como las siguientes:

@Test

public void

P e r s o n I s I n d e x e d ( ) throws I O E x c e p t i o n { Company c = new Company ( ) ; c . s etI d (1) ; P e r s o n p = new P e r s o n ( " J u l i n " , " K l a s " , " j k l a s @ f i . uba . a r " ) ; p . setCompany ( c ) ; PersonDao ( s e s s i o n ) . i n s e r t P e r s o n ( p , " 123456 " ) ;

new
}

A s s e r t . a s s e r t E q u a l s ( 1 , MemoryIndex . g e t D e f a u l t I n d e x ( ) . g e t O b j e c t C o u n t ( ) ) ;

Hasta aqu hemos descripto el diseo de las funcionalidades de indexacin. En la prxima subseccin expondremos el diseo del framework en trminos priorizar los objetos recuperados segn el modelo de IR y las reglas de negocio.

122

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

3.3.5. Tcnicas de Puntaje y Relevancia


En esta subseccin vamos a presentar nuestra implementacin de los modelos de similitud vectorial, el ordenamiento por reglas y el ltrado de objetos.

Puntaje en el Modelo Vectorial: VectorRanker


Para implementar una frmula de similitud en el modelo vectorial (recordemos que el modelo booleano no tiene nocin de similitud), debemos implementar la interfaz VectorRanker. Presentemos dicha interfaz:
public abstract

L i s t <V e c t o r R a n k e d R e s u l t > r a n k ( V e c t o r Q u e r y reader ) ;

vectorQuery ,

S e t <S i n g l e T e r m O b j e c t R e s u l t > u n s o r t e d R e s u l t s , MasterAndInvertedIndexReader

Las implementaciones de esta interfaz tienen la responsabilidad de retornar una lista priorizada de resultados segn la relevancia del modelo. Analicemos bevemente los parmetros del mtodo rank:

VectorQuery: representa la consulta del usuario en trminos del modelo vectorial. sta es necesaria para implementar frmulas que tengan en cuenta los trminos de la query. Set<SingleTermObjectResult>: es el conjunto de postings obtenidos desde los ndices. La implementacin de hashCode e equals permite que convivan en el conjunto postings que referencian a un mismo objeto desde diferentes postings lists (es decir, para distintos trminos). Este conjunto es vital para efectuar el clculo de similitud. MasterAndInvertedIndexReader: el lector de ndices es necesario para conocer datos que intervienen en la frmula de similitud y que no corresponden a la query ni al conjunto puntual de resultados (por ejemplo, el nmero global de objetos indexados).

Tal como describimos en la subseccin (3.1.4), nuestro framework provee una implementacin por defecto de la frmula de similitud vectorial a travs de la clase DefaultVectorRanker. En el captulo 4 presentaremos resultados experimentales en los que analizaremos los resultados de DefaultVectorRanker en aplicaciones reales.

Ordenamiento por Reglas


Tanto al estudiar el estado del arte como al analizar esta propuesta de solucin vimos que es necesario tener un mecanismo de ordenamiento previo a la hidratacin de objetos, interno a motor de bsqueda y que respete las variables de negocio de la aplicacin husped. Para cumplir con estas premisas, nuestro framework incorpora una capa de ordenamiento inmediatamente posterior a la similitud vectorial (en el caso booleano se implementa inmediatamente despus de la etapa de ltrado). Para enfatizar que esta capa ejecuta previamente a la hidratacin, tambin la llamaremos capa de pre -ordenamiento. Si bien podramos aplicar las reglas de negocio fuera del motor de bsqueda, esto requerira conocer los atributos del objeto para cada resultado de la recuperacin, lo que se puede traducir en miles de consultas al ORM (y potencialmente al RDBMS). Para solucionar el problema de requerir el valor de los atributos desde el ORM, las capacidades de mapeo de nuestro framework permiten almacenar atributos en el ndice invertido tal que disponer de ellos al momento de recuperar los objetos. A diferencia de la similitud vectorial, las reglas de pre-ordenamiento dependen de cada aplicacin, por lo que no podemos proveer una regla por defecto. Sin embargo, cualquier implementacin debe cumplir con la siguiente interfaz:

3.3.

DISEO DEL FRAMEWORK DE IR SOBRE OBJETOS

123

public

interface

PreSort
extends

{ O b j e c t R e s u l t > w o r k ( C o l l e c t i o n <?
extends

public

L i s t <?

ObjectResult > currentObjects ) ; }

A continuacin ejemplicamos la implementacin de esta interfaz con un extracto de los tests del framework: @Indexable
public class

HardAndSoftRuleEntity
public final int

@SearchId

id ; proxy1 ; proxy2 ; proxy3 ; attribute ; id , String attribute , proxy2 , String proxy3 )

@SearchSort @SearchSort @SearchSort @SearchField


public

public public public public

final final final final

int

float

String String

HardAndSoftRuleEntity ( int
int

proxy1 ,

float

{
this . id

= id ; = attribute ; = proxy1 ; = proxy2 ; = proxy3 ;

this . attribute this . proxy1 this . proxy2 this . proxy3

} }
private class

HardAndSoftRule ValueHolder score ;

implements

PreSort

private

class

implements

C o m p a r a b l e <V a l u e H o l d e r > {

public public

ObjectResult
float

okr ;

public

ValueHolder ( ObjectResult = okr ;


this . score

okr ,

float

score )

this . okr

=s c o r e ;

} @Override
public int

compareTo ( V a l u e H o l d e r F l o a t . compare ( s c o r e ,

o)

return

o . score ) ;

} }
private final

Field

proxy1Field ,
throws

proxy2Field

; NoSuchFieldException

public

HardAndSoftRule ( )

SecurityException ,

{
this . proxy1Field

= HardAndSoftRuleEntity . class . getDeclaredField (" = HardAndSoftRuleEntity . class . getDeclaredField ("

proxy1 " ) ;
this . proxy2Field

proxy2 " ) ; }
protected return final boolean

objectAccepted ( ObjectResult

object )

HardAndSoftRuleEntity . c l a s s . e q u a l s ( o b j e c t . getKey ( ) . g e t C l a z z

() ) ; } @Override

124

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

public

L i s t <?

extends

ObjectResult >
extends

w o r k ( C o l l e c t i o n <? {

ObjectResult > currentObjects )

i f ( c u r r e n t O b j e c t s== n u l l ) th row new

I l l e g a l A r g u m e n t E x c e p t i o n ( " Can ' t

work

on

null

result

set ") ; L i s t <V a l u e H o l d e r >


int

treated

= new

A r r a y L i s t <V a l u e H o l d e r >() ;

proxy1Max = 0 ; ( I t e r a t o r <? i t e r a t o r () ;
extends

for

ObjectResult >

iterator

= currentObjects .

i t e r a t o r . hasNext ( ) ; ) okr = ( ObjectResult )


continue ;

{ ObjectResult i t e r a t o r . next () ;
i f ( ! objectAccepted ( okr ) )

i t e r a t o r . remove ( ) ; t r e a t e d . a d d ( new
int

V a l u e H o l d e r ( okr ,

0f)) ;

proxy1Value = ( I n t e g e r ) okr . g e t S t o r e d F i e l d s () . get ( proxy1Field ) ; proxy1Max = p r o x y 1 V a l u e ;

i f ( p r o x y 1 V a l u e >p r o x y 1 M a x )

}
for

( ValueHolder
float

valueHolder

treated )

{ /

proxy2Value = ( float ) proxy1Max ;

( f l o a t ) valueHolder . okr . g e t S t o r e d F i e l d s () . get ( proxy2Field ) valueHolder . score = proxy2Value ; } Collections . sort ( treated ) ; L i s t <O b j e c t R e s u l t >
new

result

A r r a y L i s t <O b j e c t R e s u l t >( t r e a t e d . s i z e ( ) + c u r r e n t O b j e c t s . size () ) ;

for

( ValueHolder

valueHolder

treated )

r e s u l t . add ( v a l u e H o l d e r . o k r ) ; } r e s u l t . addAll ( currentObjects ) ;


return

result ;

} } @Test
public void

BooleanRetrievalMaxRule ()

throws

SecurityException ,

NoSuchFieldException { HardAndSoftRuleEntity
new

entity1

= to be retrieved" , 1 , 50.0 f

HardAndSoftRuleEntity (0 , " Something , "A" ) ; entity2 =

HardAndSoftRuleEntity
new

HardAndSoftRuleEntity (1 , " Another 20.0 f , "A" ) ; entity3 =

thing

to

be

retrieved" ,

HardAndSoftRuleEntity

3.3.

DISEO DEL FRAMEWORK DE IR SOBRE OBJETOS

125

new

HardAndSoftRuleEntity (2 , " I f , "A" ) ;

should

be

retrieved

too ! " ,

10

10.0

U t i l s . setupSampleMemoryIndex ( e n t i t y 1 , BooleanSearch s e a r c h = new

entity2 ,
new

entity3 ) ; BooleanQueryParser (" ) ;

BooleanSearch (

r e t r i e v e d " ) . getQuery () , L i s t <?


extends

MemoryIndexReaderFactory . g e t I n s t a n c e () results = s e a r c h . s e a r c h ( new

ObjectResult >

HardAndSoftRule ( ) ) ; Assert . assertEquals (2 , Assert . assertEquals (1 , Assert . assertEquals (0 , } @Test


public void

r e s u l t s . get ( 0 ) . getKey ( ) . g e t I d ( ) ) ; r e s u l t s . get ( 1 ) . getKey ( ) . g e t I d ( ) ) ; r e s u l t s . get ( 2 ) . getKey ( ) . g e t I d ( ) ) ;

VectorRetrievalMaxRule ()

throws

SecurityException ,

NoSuchFieldException { HardAndSoftRuleEntity
new

entity1

= to be retrieved" , 1 , 50.0 f

HardAndSoftRuleEntity (0 , " Something , "A" ) ; entity2 = HardAndSoftRuleEntity (1 , " Another 20.0 f , "A" ) ; entity3 = should

HardAndSoftRuleEntity
new

thing

to

be

retrieved" ,

HardAndSoftRuleEntity
new

HardAndSoftRuleEntity (2 , " I f , "A" ) ;

be

retrieved

too ! " ,

10

10.0

U t i l s . setupSampleMemoryIndex ( e n t i t y 1 , VectorSearch s e a r c h = new


new new

entity2 ,

entity3 ) ;

VectorSearch (

VectorQueryParser ( " r e t r i e v e d " ) . getQuery () , MemoryIndexReader ( )

) ; L i s t <?
extends

ObjectResult >

results

= s e a r c h . s e a r c h ( new

HardAndSoftRule ( ) ) ; Assert . assertEquals (2 , Assert . assertEquals (1 , Assert . assertEquals (0 , } Analicemos este extracto de cdigo: Los mtodos BooleanRetrievalMaxRule y VectorRetrievalMaxRule muestran cmo una aplicacin utilizara las capacidades de pre-ordenamiento de nuestro framework. Estos mtodos generan entidades, las indexan y luego las recuperan indicando su implementacin de PreSort. La clase HardAndSoft rule implementa dos criterios de negocio. El primero es una regla dura que indica que las entidades de tipo HardAndSoftEntity deben ubicarse primero que el resto. El segundo criterio es una regla blanda que busca el mximo global de un atributo de HardAndSoftEntity y establece el puntaje como la divisin del otro atributo de la entidad sobre el mximo global. Veamos que el usuario de las reglas de pre-ordenamiento slo conoce el nombre de la clase que implementa las reglas, siendo que no es necesario conocer nada mas acerca de cada regla. Esto es importante porque separa al usuario experto que implementa una regla del usuario que tiene un conocimiento mas bsico del framework. r e s u l t s . get ( 0 ) . getKey ( ) . g e t I d ( ) ) ; r e s u l t s . get ( 1 ) . getKey ( ) . g e t I d ( ) ) ; r e s u l t s . get ( 2 ) . getKey ( ) . g e t I d ( ) ) ;

126

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

Por ltimo, es importante notar que el mismo conjunto de reglas fue aplicado en una bsqueda vectorial y en una booleana, sin alterar en ninguna forma dichas reglas. Este es un claro ejemplo de la independencia entre capas.

En el prximo apartado analizamos la operacin de ltrado, la cual completa el circulo de requerimientos bsicos para un uso real.

Filtrado
Al igual que permitimos un pre-ordenamiento de objetos recuperados, tambin debemos permitir la eliminacin de objetos que no cumplan con requisitos de negocio. Esta eliminacin o ltrado es llamada

pre-ltrado y quienes realizan esta accin son los pre-ltros.


Como ya hemos comentado en captulos y secciones previas, el hecho de eliminar los objetos previamente a su valoracin es especialmente importante en corpus cuyas consultas recuperan muchos objetos. Esto se debe a que la operacin de ltrado es de orden

O (n)

mientras que la de ordenamiento es

O (n log n).

Es decir, si ltramos antes de ordenar estamos mejorando el tiempo total de recuperacin. El ltrado de objetos involucra las siguientes clases e interfaces:

FilterChain: interfaz cuyas implementaciones mantienen la lista de ltros a aplicar y los ejecutan en el orden especicado. ResultFilter: interfaz que implementan los pre-ltros.

Presentemos la interfaz FilterChain:


public interface abstract

FilterChain
void

{
extends

public

a p p l y F i l t e r s ( C o l l e c t i o n <?

ObjectResult >

unfilteredResults ) ; } y ResultFilter:
public interface boolean

ResultFilter

{ filtrable ) ;

public

i s F i l t e r e d ( ObjectResult

} A continuacin vemos un ejemplo en el que implementamos esta interfaz para generar un pre-ltro.

Ejemplo 3.3.5.

El siguiente es ejemplo de un ltro que elimina del conjunto de resultados las clases que

no pertenecen a cierta jerarqua:

public c l a s s

ClassFilter

implements

ResultFilter {

private f i n a l C l a s s <?> f i l t e r C l a z z ; private f i n a l boolean a l l o w S u b c l a s s e s ; public C l a s s F i l t e r ( C l a s s <?> f i l t e r C l a z z , boolean a l l o w S u b c l a s s e s ) i f ( f i l t e r C l a z z==n u l l ) throw new I l l e g a l A r g u m e n t E x c e p t i o n ( "The c l a z z t o be u s ed f o r
f i l t e r i n g can ' t be n u l l " ) ; {

this . f i l t e r C l a z z = f i l t e r C l a z z ; this . allowSubclasses = allowSubclasses ;


filterClazz ) {

public C l a s s F i l t e r ( C l a s s <?> i f ( f i l t e r C l a z z==n u l l )

3.3.

DISEO DEL FRAMEWORK DE IR SOBRE OBJETOS

127

throw new

I l l e g a l A r g u m e n t E x c e p t i o n ( "The c l a z z t o be u s ed f o r f i l t e r i n g can ' t be n u l l " ) ;

this . f i l t e r C l a z z = f i l t e r C l a z z ; t h i s . a l l o w S u b c l a s s e s = true ;

public boolean i s F i l t e r e d ( O b j e c t R e s u l t f i l t r a b l e ) { i f ( allowSubclasses ) { return ! f i l t e r C l a z z . i s A s s i g n a b l e F r o m ( f i l t r a b l e . getKey ( ) . g e t C l a z z ( ) ) ; } else { return ! f i l t e r C l a z z . e q u a l s ( f i l t r a b l e . getKey ( ) . g e t C l a z z ( ) ) ;


} } }

En este extracto de cdigo el ltro recibe el nombre de la clase que admite y un ag para determinar si admite la jerarqua completa o slo la clase especicada.
Como ejercicio para entender mejor el diseo, supongamos que necesitamos implementar un ltro de seguridad que elimina del conjunto de resultados los objetos a los que el operador actual no tiene acceso. Para esto podramos implementar un ltro similar al del ejemplo anterior, controlando que la clave del objeto est en la lista de objetos que se operador puede leer. Otro n que se le puede dar a los ltros es la implementacin de la bsqueda facetada. Normalmente, para implementar la bsqueda facetada necesitamos contar cuntos objetos cumplen con el criterio de cada faceta. Tanto esta operacin como la de ltrado se pueden realizar en simultaneo , siendo que el ltrado tendr efecto sobre el framework de IR y el recuento deber ser consultado por el usuario del ltro. Para soportar tanto la bsqueda facetada como la normal, tenemos dos implementaciones de FilterChain:

ImmediateRemoveFilterChain: esta implementacin elimina de la lista de resultados los objetos que no pasan por un ltro, evitando que pasen por el resto de ellos. LateRemoveFilterChain: si queremos que el framework de IR pase todos los objetos por todos los ltros y luego los ltre debemos agregar los ltros a esta implementacin. Debemos tener en cuenta que este tipo de FilterChain genera mayor trabajo sobre los ltimos ltros de la cadena.

Por ltimo, queremos resaltar que al igual que ocurri con los pre-ordenamientos, los pre-ltros no dependen del modelo de IR en el que trabajemos.

En este captulo cumplimos el objetivo de analizar y disear una solucin al problema de IR sobre objetos de un modelo de dominio, basndonos en los conceptos de recuperacin de informacin, diseo de software y persistencia de objetos que estudiamos en el captulo 2. En el prximo captulo ponemos a prueba nuestra solucin implementando tres aplicaciones con necesidades de information retrieval, las cuales se debern satisfacer a travs de nuestra herramienta.

4 Teniendo

el cuidado de indicarle al framework de IR que no elimine los objetos hasta pasarlos por todos los ltros, ya

que de otra forma los ltimos ltros contaran menos objetos de los que realmente hay.

128

CAPTULO 3.

DESARROLLO DE LA PROPUESTA DE SOLUCIN

Captulo 4

Experimentacin
El objetivo de este captulo es mostrar cmo probamos la adecuacin de la solucin propuesta en el captulo 3 al problema de IR sobre objetos. La organizacin de este captulo es la siguiente: La seccin 4.1 explica qu tipos de pruebas se disearon para vericar la validez de la propuesta. La seccin 4.2 muestra las tres aplicaciones que utilizamos para validar nuestro framework y analiza distintos aspectos de la integracin con estas aplicaciones. Por ltimo, la seccin 4.3 desarrolla las pruebas comparativas cuantitativas y cualitativas.

4.1.

Tipo de Pruebas Efectuadas

En esta seccin explicaremos los distintos tipos de pruebas que se hicieron para vericar la validez de la solucin propuesta en el captulo 3. Recordemos que el framework construido no es un sistema completo por s mismo sino que da servicio a aplicaciones que necesitan capacidades de indexacin y bsqueda. Esto requiere que veriquemos la capacidad del framework de adaptarse a distintos dominios y aplicaciones, caracterstica que llamaremos

portabilidad .
Para vericar la portabilidad decidimos aplicar el primero de los patrones que propone Johnsonn para el desarrollo de un framework: comenzar implementando tres aplicaciones de referencia sobre las cuales luego probar la adecuacin del framework (Roberts y Johnson, 1996). Estas aplicaciones pueden ser prototipos, pero es importante que hagan algo real. Las tres aplicaciones construidas Klink y KStore. PetClinic es una aplicacin articial creada por los desarrolladores del framework Spring para mostrar el funcionamiento de Spring Framework y es un estndar de facto con el que distintos frameworks como Compass, iBATIS, Hibernate y otros han mostrado su funcionamiento. KStore y KLink son aplicaciones articiales creadas especcamente para este trabajo. La primera simula una tienda online de productos generales y la segunda una red de contactos entre personas. Dentro de estas pruebas con aplicaciones reales vericamos el funcionamiento del framework con ORMs como Hibernate e iBATIS. Adems de estas pruebas con aplicaciones de referencia, hicimos pruebas de calidad. Las pruebas de calidad buscan reejar que el sistema que se construy es correcto. Para probar este punto, ejecutamos una serie de tests unitarios que nos aseguran el correcto comportamiento de la herramienta ante los casos probados y calculamos mtricas de cobertura de cdigo.

1 son PetClinic,

1A

diferencia de Klink y KStore, PetClinic no fue construida para este trabajo sino que fue mayormente tomada de la

implementacin que acompaa a Compass. En adelante, para facilitar la redaccin, evitaremos marcar esta excepcin en forma explcita.

129

130

CAPTULO 4.

EXPERIMENTACIN

Las pruebas comparativas de rendimiento buscan comprobar si existe un comportamiento anmalo en el rendimiento del framework y comprender qu grado de competitividad tiene respecto de las herramientas del estado del arte.

Por ltimo, las pruebas comparativas cualitativas buscan encontrar las diferencias en la integracin de los distintos frameworks con las aplicaciones.

A continuacin presentamos las pruebas con aplicaciones de referencia.

4.2.

Pruebas con Aplicaciones de Referencia

4.2.1. PetClinic
Descripcin General
PetClinic es una aplicacin web que implementa el negocio de una veterinaria y es una aplicacin de referencia con la que frameworks como Spring muestran su funcionamiento.

Las entidades ms importantes en este dominio son las mascotas (Pet), dueos (Owner), visitas (Visit), veterinarios (Vet) y la clnica misma (Clinic).

Para nuestro objetivo de probar la integracin y adecuacin del framework de IR sobre PetClinic, mantuvimos las tecnologas y casos de uso originales, agregando el mnimo conjunto de funcionalidades necesarias para dar a la aplicacin capacidades de IR.

PetClinic es una aplicacin de tres capas (presentacin, negocio y acceso a datos) construida con el patrn model-view-controller (MVC) a travs de Spring MVC.

La capa de presentacin de PetClinic produce vistas HTML utilizando tecnologas como Java Server Pages (JSP) , Java Standard Tag Libraries (JSTL) y Spring Web.

La capa de negocio se basa en objetos simples Java que colaboran entre si y aprovechan facilidades del framework Spring como inyeccin de dependencias.

La capa de acceso a datos est implementada sobre el ORM Hibernate, por lo que la integracin con PetClinic sirvi para hacer una prueba real de integracin con este ORM.

Casos de Uso y Modelo de Dominio


Los casos de uso de PetClinic son:

4.2.

PRUEBAS CON APLICACIONES DE REFERENCIA

131

Figura 4.1: Casos de Uso en PetClinic.

Vamos a describir brevemente el propsito de cada caso de uso:

See Search Stats: permite conocer el nmero de objetos indexados por ndice.

Search: representa la bsqueda de entidades utilizando el motor de IR a partir de una expresin de lenguaje natural.

Find Owner: este caso de uso sirve para encontrar un dueo utilizando Hibernate, es decir, generando una consulta a la base de datos sin la inteligencia del motor de bsqueda.

Manage Pet: permite agregar y modicar la informacin de una mascota. La informacin ingresada se indexa en el motor de IR.

Add Visit: agrega una visita de una mascota a la clnica. La informacin ingresada se indexa en el motor de IR.

Show Vets & Specialties: visualiza los veterinarios y sus especialidades.

Manage Pet Owners: permite agregar dueos as como modicar sus datos. La informacin ingresada se indexa en el motor de IR.

Veamos un diagrama de clases de las entidades de dominio:

132

CAPTULO 4.

EXPERIMENTACIN

Figura 4.2: Entidades de dominio en PetClinic.

Para esta prueba seleccionamos un subconjunto de las clases de dominio y las anotamos para volverlas indexables. Respecto del diagrama de clases de la gura (4.2), en la gura (4.3) agregamos estereotipos para indicar cmo anotamos las clases para su indexacin.

Figura 4.3: Entidades de dominio en PetClinic con informacin de indexacin.

El diseo de clases de la gura (4.2) es el original de PetClinic. Esto es, no se adapt de ninguna forma para utilizar nuestro framework. El hecho de no requerir ningn tipo de modicacin en el dominio marca

4.2.

PRUEBAS CON APLICACIONES DE REFERENCIA

133

el xito de uno de los criterios de diseo de un buen framework: independencia del modelo de dominio (ver subseccin 2.2.2). Dada la extensiva utilizacin de la subclasicacin en el diseo de PetClinic, fue necesario utilizar y extender el framework de IR para cubrir casos complejos. Veamos algunos de ellos:

Person: junto a los objetos de tipo Pet, los objetos de esta clase son los principales objetivos de indexacin en la aplicacin. El identicador de esta clase se encuentra en la superclase (concretamente en la clase Entity) pero los objetos concretos a indexar sern principalmente de las subclases Owner y Vet. Por otro lado, los atributos indexables se encuentran principalmente en la clase Person. Para soportar este mapeo, la anotacin @Indexable de la clase Person indica la propiedad climbingTarget=Entity.class, lo cual obliga a recorrer la jerarqua de clases en busca de atributos e identicadores. A su vez, la anotacin @Indexable fue necesario indicar la propiedad makeSubclassesIndexable=true tal que las clases Owner y Vet sean indexadas automticamente. Owner: el principal desafo en mapear esta clase consiste en que casi todos sus atributos se ubican en superclases, con excepcin de una coleccin de mascotas, la cual tambin se indexa. Pet: los objetos de esta clase no slo son indexables por si mismos sino que contienen dos atributos indexables por separado: un Owner y un PetType. Particularmente, estos dos objetos referencian a la mascota, de forma tal que cuando se indexa una mascota, una posterior bsqueda de su dueo retornar entre los resultados a la mascota.

El mapeo de todas las entidades se hizo sobre un mismo ndice, es decir, no hubo necesidad de particionar las entidades en ndices distintos. Tampoco fue necesario utilizar caractersticas avanzadas del framework como ltrado de objetos y ordenamientos ad hoc.

Funciones de IR en PetClinic
Sumado a los casos de uso originales de la aplicacin (administracin de dueos, mascotas y visitas), se agreg un caso de uso de bsqueda de entidades. En trminos visuales, se implement un cuadro de texto donde ingresar la expresin de bsqueda (query) y una vista donde se presentan las entidades que coincidieron con la query (gura 4.4).

Figura 4.4: Cuadro de bsqueda (arriba a la izquierda) y resultados de bsqueda (centro).

La bsqueda de entidades se hace mediante un modelo vectorial simple utilizando la familia de frmulas TF-IDF. Dado que nuestra estrategia de indexacin permite recuperar objetos de tipos heterogneos, agregamos una pequea capa con la inteligencia de dirigir los clics de cada tipo de entidad a su pantalla correspondiente (las mascotas tienen una pantalla de edicin distinta a los dueos).

Pruebas de Relevancia
A continuacin describimos una prueba de relevancia para un pequeo conjunto de datos generados, analizando los resultados de ejecutar distintas queries sobre el sistema. El conjunto de datos que se gener utilizando la interfaz web de PetClinic es el siguiente:

134

CAPTULO 4.

EXPERIMENTACIN

3 (tres) dueos: Julin Klas, Pedro Klas y Pedro de Mendoza. 2 (dos) mascotas: Fido (mascota de Pedro Klas) y Cuky (mascota de Julin Klas) 3 (tres) tipos de mascotas: Cat, Dog y Other 3 (dos) visitas de mascotas, una de Fido y dos de Cuky Para analizar mejor los resultados del sistema de IR, hicimos una modicacin a la interfaz de la gura (4.4) que incluye el puntaje que obtuvo cada elemento recuperado (gura 4.5).

Ejemplo 4.2.1.

Ante la query

Julin,

los resultados son:

Figura 4.5: Resultados para la query Julin sobre el conjunto de datos de prueba.

Para analizar los puntajes debemos tener en cuenta: se utiliza TF-IDF sobre los trminos coincidentes entre la query y el tem, hay un total de

N = 11

objetos indexados,

al indicarle al framework de IR que debe indexar las mascotas junto a su dueo, cualquier match en el dueo tambin aplica a la mascota. Entonces dueo como la mascota. el nico atributo coincidente entre la query y el corpus es el atributo para el dueo

df (Julian) = 2

porque se index tanto para el

Julin Klas.

rstName

de la clase

Owner

Analicemos entonces el puntaje entre la query

Julin

y el objeto coincidente:

SimilitudT F IDF (query, owner) = tf (Julian) idf (Julian) = tf (Julian) log10 N 11 = 1 log10 = 0,7404 df (Julin) a 2

Para el caso del objeto la mascota el clculo es idntico slo que la referencia a la identidad recuperada apunta a la mascota.

Ejemplo 4.2.2.

Veamos la respuesta del buscador y su anlisis ante la query

Pedro Klas:

Figura 4.6: Resultados para la query Pedro Klas sobre el mismo corpus del ejemplo previo.

4.2.

PRUEBAS CON APLICACIONES DE REFERENCIA

135

A continuacin analizamos el resultado posicin por posicin, teniendo en cuenta:

dfP EDRO = 3

Fido.

porque se referencia desde los dueos

Pedro de Mendoza, Pedro Klas

y su mascota

dfKLAS = 4 porque se referencia desde los dueos mascotas Fido y Cuky.


Si analizamos el resultado posicin por posicin:

Pedro Klas y Julin Klas, mas sus correspondientes

Resultado 1: es el elemento del corpus de mayor coincidencia y su ubicacin se explica conceptualmente porque es el nico que contiene todos los trminos de la query. Haciendo el clculo formal de similitud:

SimilitudT F IDF (query, owner) = tf (Pedro) idf (Pedro) + tf (Klas) idf (Klas) 11 11 + 1 log10 = 1, 003604 3 4

= 1 log10

Resultado 2: es idntico al anterior porque el mapeo que hicimos de la clase dueo el

Pedro Klas Owner.

referenciando a la mascota

Fido.

Pet

hizo indexar a su

Es decir, la similitud es igual a la anterior sobre

Resultado 3: naturalmente este resultado aparece por la coincidencia parcial en el trmino en un nico trmino. Calculando la similitud:

Pedro pero

vemos que tiene un puntaje sensiblemente inferior a los primeros dos resultados por la coincidencia

SimilitudT F IDF (query, owner) = tf (Pedro) idf (Pedro) = 1 log10

11 = 0, 564271 3

Resultado 4: nuevamente tenemos coincidencia parcial, pero ahora en el trmino umentos. A diferencia del trmino similitud:

Klas.

Aqu vemos referencia

cmo la familia de formulas TF-IDF da menor prioridad a los trminos de poca selectividad de doca 4 objetos. Esto hace que el trmino

Pedro, el Klas

cual se asociaba a 3 objetos, el trmino tenga menor relevancia que

Pedro,

Klas

reejndose en la

SimilitudT F IDF (query, owner) = tf (Klas) idf (Klas) = 1 log10


Resultado 5: al igual que con el segundo resultado, la mascota su dueo

11 = 0, 439333 4

Julian Klas

Cuky

obtiene la misma similitud que

de la posicin anterior.

Otras caractersticas de la solucin


La interconexin entre componentes como el ORM, el motor de IR y PetClinic se hizo utilizando la object factory del framework Spring. Para reejar los eventos CUD sobre el ndice invertido utilizamos nuestro plugin de Hibernate, el cual se conect al sistema de eventos de Hibernate Core mediante Spring. El interceptor de eventos fue congurado para recibir los eventos luego de que stos se ejecutan en Hibernate. Como adelantamos al inicio de este apartado, tanto el pipeline de indexacin como el tipo de ndice (memoria, Berkeley u otro) son congurables mediante Spring. Veamos un fragmento del XML que usamos para congurar el uso del ndice en memoria y el pipeline de indexacin por defecto:

136

CAPTULO 4.

EXPERIMENTACIN

<b e a n

i d=" O b j e c t S e a r c h H i b e r n a t e L i s t e n e r "

c l a s s ="com . j k l a s . s e a r c h .

i n t e r c e p t o r s . h i b e r n a t e . H i b e r n a t e E v e n t I n t e r c e p t o r "> <c o n s t r u c t o r </ b e a n> <b e a n i d=" S e a r c h I n t e r c e p t o r " c l a s s ="com . j k l a s . s e a r c h . i n t e r c e p t o r s .

a r g

r e f =" S e a r c h I n t e r c e p t o r " />

S e a r c h I n t e r c e p t o r "> <c o n s t r u c t o r </ b e a n> <b e a n i d=" O n l i n e I n d e x e r " c l a s s ="com . j k l a s . s e a r c h . i n d e x e r . o n l i n e .

a r g

r e f =" O n l i n e I n d e x e r " />

O n l i n e I n d e x e r "> <c o n s t r u c t o r </ b e a n> <b e a n i d=" D e f a u l t I n d e x e r S e r v i c e " c l a s s ="com . j k l a s . s e a r c h . i n d e x e r .

a r g

r e f =" D e f a u l t I n d e x e r S e r v i c e " />

D e f a u l t I n d e x e r S e r v i c e "> <c o n s t r u c t o r <c o n s t r u c t o r </ b e a n> <b e a n i d=" D e f a u l t I n d e x i n g P i p e l i n e " c l a s s ="com . j k l a s . s e a r c h . i n d e x e r .

a r g a r g

r e f =" D e f a u l t I n d e x i n g P i p e l i n e " /> r e f =" I n d e x W r i t e r F a c t o r y " />

p i p e l i n e . D e f a u l t I n d e x i n g P i p e l i n e " /> <b e a n i d=" I n d e x W r i t e r F a c t o r y " c l a s s ="com . j k l a s . s e a r c h . i n d e x . memory .

M e m o r y I n d e x W r i t e r F a c t o r y " />

Comentemos brevemente la conguracin de estos beans

2:

IndexWriterFactory: selecciona el backend/plugin con el que se escribe en el ndice invertido. En este caso se eligi el ndice en memoria que viene incluido dentro del framework. Veamos que la inyeccin de dependencias permite variar la implementacin del backend de ndices invertidos de forma transparente a PetClinic, sin modicar el cdigo de negocio. DefaultIndexerService: se ocupa de orquestar el procesamiento de los objetos para su indexacin y la posterior escritura en el ndice. Es preciso notar que estamos inyectando dos dependencias en su constructor: el backend de escritura en el ndice y el pipeline de procesamiento de objetos. Esta inyeccin de dependencias nos permite variar sustancialmente el comportamiento del framework sin cambiar una sola lnea de cdigo en el framework o PetClinic. ObjectSearchHibernateListener: este bean es inyectado en otro bean de Hibernate y congura la interceptacin de eventos por parte del framework de IR. OnlineIndexer: este bean congura el indexador online que analizamos y diseamos en las secciones (3.1.3) y (3.3.4). Editando este bean podemos hacer que nuestro framework utilice indexacin online, semi-online u oine sin tener otra consideracin de cdigo sobre la aplicacin.

Como acabamos de ver, el medio de almacenamiento del ndice invertido se puede variar por conguracin utilizando la object factory de Spring. De la misma forma podemos intercambiar el tipo de indexacin online por el semi-online o el oine. Dado que esta aplicacin fue la primera con la que probamos la integracin del framework de IR, se busc reducir la complejidad inicial para centrarse en las funcionalidades de IR y en eventuales ajustes al framework. Siguiendo este criterio, las pruebas las desarrollamos utilizando indexacin online sobre un

ndice en memoria. Si bien el ndice en memoria es volatil y slo se utiliza para pruebas, en las prximas
aplicaciones de ejemplo s utilizaremos un ndice persistente.

2 En

este contexto, un bean es un objeto Java que instanciamos utilizando la Object Factory de Spring y el cual se utiliza

en un contexto de inyeccin de dependencias.

4.2.

PRUEBAS CON APLICACIONES DE REFERENCIA

137

4.2.2. Klink
Descripcin General
Klink es una aplicacin web articial creada para esta tesis con el objetivo de probar la adecuacin del framework a distintos escenarios, siguiendo el patrn propuesto por Johnson (ver seccin 4.1). Klink implementa una red social bsica en la que las personas pueden agregar contactos libremente. Los conceptos ms importantes en Klink son: el usuario como miembro del sitio (Person), los contactos (tambin de tipo Person), el perl (atributos de la clase Person), la compaa para la que trabaja (Company) y el pas en el que esta reside (Country). Al igual que hicimos con PetClinic, esta aplicacin se construye utilizando Spring MVC como framework estructural y JSP/JSTL como framework de presentacin. Se utiliz el framework Spring Core para inyectar dependencias en los objetos y congurar la indexacin. La capa de negocio es elemental y se ocupa principalmente de la comunicacin con la capa de acceso a datos implementada con Apache iBATIS. El hecho de utilizar iBATIS para la capa de acceso a datos no es accidental sino que fue elegida para probar la adecuacin del framework a distintos entornos de persistencia (recordemos que PetClinic utilizaba Hibernate).

Casos de Uso y Modelo de Dominio


Las funcionalidades de Klink se pueden ver fcilmente en este diagrama de casos de uso:

Figura 4.7: Casos de uso en Klink.

Expliquemos brevemente este diagrama: Unregistered User: es un usuario no registrado en el sistema y por tanto slo puede ejecutar el caso de uso Signup .

3 En

rigor, tambin puede ejecutar el caso de uso Login, el cual no le permitir acceder al sistema por no estar registrado.

Preferimos no mostrar esta relacin en el diagrama porque se presta a confusin.

138

CAPTULO 4.

EXPERIMENTACIN

Signup: este caso de uso permite al usuario formar parte de la red de contactos y requiere el ingreso de ciertos datos en el sistema. Luego de ejecutarse el caso de uso, el usuario deja de estar representado por el actor unregistered user para verse representado por el registered user.

Registered User: son los usuarios que ejecutaron con xito el caso de de uso Signup.

Login: mediante una contrasea y una direccin de correo electrnico, el caso de uso valida que el usuario que lo ejecuta sea un registered user. En caso de que el usuario demuestre serlo, el sistema le permite ejecutar los casos de uso Search Friends, Add Friends, View Home Page y Logout. En caso de no vericarse que el usuario sea un registered user, se indica al usuario que revise los datos ingresados o que ejecute el caso de uso Signup.

Search Friends: este caso de uso permite al usuario encontrar personas a partir de una expresin de lenguaje natural, utilizando el motor de bsqueda. Entre los resultados de la bsqueda pueden haber tanto personas relacionadas con el usuario como personas no relacionadas. En base al listado resultante de este caso de uso, el usuario puede iniciar el caso de uso Add Friend sobre las personas no relacionadas con l.

Add Friend: este caso de uso agrega una relacin entre el usuario y la persona seleccionada en el caso de uso Search Friends.

View Home Page: el usuario inicia este caso de uso para visualizar sus datos propios. Este caso de uso permite no slo ver la pgina de inicio (Home) sino una pantalla de perl (Prole).

Logout: se ejecuta cuando el usuario desea dejar de usar el sistema. Luego de ejecutar este caso de uso, no ser posible ejecutar otro caso de uso que no sea el de Login (luego del cual se volver a permitir ejecutar el resto de los casos de uso).

El diagrama de clases de Klink es el siguiente:

Figura 4.8: Diagrama de clases en Klink.

Marcando con estereotipos las anotaciones sobre las clases:

4.2.

PRUEBAS CON APLICACIONES DE REFERENCIA

139

Figura 4.9: Diagrama de clases y anotaciones en Klink.

Hagamos una breve descripcin acerca de estas entidades:

Person: representan a los usuarios del sistema como entes sociales que se interconectan entre s. Estos objetos se indexan por sus datos de contacto: email, rstName y lastName.

Los elementos de la coleccin contacts se indexan referenciando tanto al objeto que contiene la coleccin (contenedor) como al objeto que est dentro de la coleccin (contenido). Con este mapeo, una persona se indexa referenciando a todos sus contactos y ellos a su vez referencian a ste.

Por ltimo, las personas estn asociadas a exactamente un Company, la cual se indexa a referenciando a su contenedor (objetos de tipo Person). Esto permite buscar una compaa y recuperar sus empleados.

Company: esta entidad representa una empresa donde trabajan personas y, como vimos, se indexa de forma tal de referenciar a todas las personas que trabajan en esa compaa.

Country: representa la informacin de nacionalidad en el sistema. Es un atributo de Company y no se indexa.

A continuacin presentamos algunas capturas de pantalla que muestran partes de los ujos correspondientes a los casos de uso de la gura (4.7).

Comencemos con Login y Signup:

140

CAPTULO 4.

EXPERIMENTACIN

Figura 4.10: Login. El primer paso en el sistema es la pantalla de login, desde donde podemos identicarnos o agregarnos como usuarios registrados.

Figura 4.11: Signup. Creamos un usuario en el sistema, el cual se indexar por sus datos de contacto y por la compaa a la que pertenece.

Veamos ahora los ujos del caso de uso View Home Page:

4.2.

PRUEBAS CON APLICACIONES DE REFERENCIA

141

Figura 4.12: Seccin Home. Esta seccin nos muestra un mensaje de bienvenida y, eventualmente, mensajes de otros usuarios o noticaciones (correo nuevo, invitaciones, etc).

Figura 4.13: Seccin Prole. Vemos la informacin pblica hacia el resto de la comunidad.

Ahora podemos buscar a un Juan que recordamos que trabaja en FIUBA utilizando el caso de uso Search Friends:

142

CAPTULO 4.

EXPERIMENTACIN

Figura 4.14: Search Friends. Ingresamos la query juan uba y obtenemos los resultados priorizados por el modelo vectorial.

utilizando los resultados de la gura anterior, hacemos clic en el contacto Juan Ale y seguimos el ujo de Add Friend:

Figura 4.15: Add Friend y Search. Utilizando los resultados de la bsqueda anterior agregamos a Juan Ale como contacto de Julian Klas.

4.2.

PRUEBAS CON APLICACIONES DE REFERENCIA

143

Figura 4.16: Add Friend y Search. Repetimos la bsqueda original y visualizamos que Juan Ale ya es contacto nuestro.

En el prximo apartado describimos en mayor detalle las funciones de IR de esta aplicacin.

Funciones de IR en Klink
En esta aplicacin utilizamos el framework de IR para implementar el caso de uso Search Friends. Este caso de uso es central ya que es el punto de acceso para la construccin de la red de contactos (caso de uso Add Friend). A diferencia de PetClinic, el modelo de Klink es muy simple. Las clases indexables en el dominio de esta aplicacin son las personas y compaas (instancias respectivas de Person y Company). El mapeo que hicimos de la entidad Person nos permite recuperarlas segn su correo electrnico, nombre, apellido y contactos. En el caso de las compaas, la recuperacin se da por el nombre de sta. En todos los casos es necesario establecer un identicador de las entidades ya que la hidratacin de los objetos se efecta con posterioridad a la tarea de IR. Los puntos clave que marcan el xito de este ejemplo fueron:

variacin del modelo de dominio sin impactar en el framework (portabilidad) utilizacin del plugin para iBATIS utilizacin del plugin de indexacin Berkeley

En el prximo apartado hacemos algunos comentarios tecnolgicos sobre este ejemplo/caso de estudio.

Otras caractersticas de la solucin


Al igual que en el caso anterior (PetClinic), utilizamos Spring y su object factory para la conguracin e interconexin de componentes.

144

CAPTULO 4.

EXPERIMENTACIN

Los eventos CUD se reejaron sobre el ndice mediante el plugin para iBATIS provisto por nuestro framework, el cual intercept los eventos de persistencia de manera similar al plugin de Hibernate que utilizamos en PetClinic. La base de datos utilizada para almacenamiento de datos de aplicacin fue HSQLDB (HyperSQL, 2008). Al presentar PetClinic mencionamos que utilizamos el ndice en memoria para acotar la complejidad a la indexacin y recuperacin. En Klink movimos el foco de la complejidad para abarcar otros ngulos tecnolgicos del problema. Este movimiento se materializ en la utilizacin del ndice invertido en disco Berkeley. Respecto de PetClinic, la utilizacin del backend en disco Berkeley slo requiri cambios de conguracin en Spring, lo cual prob la transparencia con la que el framework permite elegir el backend de almacenamiento del ndice invertido. Para generar el conjunto de datos de prueba se obtuvieron tablas de nombres de personas del repositorio pblico Freebase (Metaweb Techonologies, 2010). Estos datos se importaron mediante un proceso index-

ador oine. El indexador lee los datos desde un archivo de texto plano y genera objetos de tipo Person,
los cuales se persistieron con iBATIS y se indexaron automticamente por el plugin de iBATIS. Dada la simplicidad del proceso indexador, concluimos que no tiene sentido proveer un indexador genrico desde el framework. Adems, tenemos un proceso reindexador que lee todos los registros de la base de datos y los indexa en nuestro framework. Veamos el cdigo fuente de este proceso:
public class

FullReindex
void

{ args )
throws

public

static

main ( S t r i n g [ ]

IOException , {

SearchEngineMappingException ,

IndexObjectException

S e a r c h L i b r a r y . configureAndMap ( Person . c l a s s ) ;
new

B e r k e l e y G l o b a l P r o p e r t y E d i t o r ( ) . s e t B a s e D i r ( " i d x /" ) ;

BerkeleyIndex . renewAllIndexes () ; Log l o g = LogFactory . getLog ( F u l l R e i n d e x . c l a s s ) ; Person . c l a s s reindex . . . ") ;

log . info (" Starting String Reader

r e s o u r c e = "com/ k l i n k / C o n f i g u r a t i o n . x m l " ; reader = Resources . getResourceAsReader ( resource ) ; p e r s o n D a o = new P e r s o n D a o ( new SqlSessionFactoryBuilder () .

Resources . setDefaultClassLoader ( IBatisHelper . class . getClassLoader () ) ;

PersonDao

build ( reader ) . openSession () ) ; L i s t <P e r s o n >


new

personList

= personDao . r e t r i e v e A l l ( ) ; DefaultIndexingPipeline () ,

D e f a u l t I n d e x e r S e r v i c e ( new

BerkeleyIndexWriterFactory . getInstance () ) . bulkCreate ( personList ) ; log . i n f o ( " Person . c l a s s } } reindex finished . . . ") ;

Notemos del anterior fragmento de cdigo que slo 4 lneas estn relacionadas al motor de bsqueda. Esto muestra el objetivo de generar procesos simples de indexacin y reindexacin.

4.2.

PRUEBAS CON APLICACIONES DE REFERENCIA

145

4.2.3. KStore
Descripcin General
La ltima aplicacin con la que probamos la adecuacin del framework se llama KStore. KStore es una tienda virtual cuyo caso de uso principal es la bsqueda de productos. Es decir, en esta aplicacin las tareas de IR estn en el centro del problema. Las entidades principales son los productos a la venta (Item), las categoras bajo las que se agrupan los tems (Category) y los sitios en los que opera KStore (Site). Una caracterstica particular de KStore es la indexacin de anuncios publicitarios (entidad Advertising), la cual permite mostrar anuncios contextuales segn la bsqueda que el usuario est llevando adelante. Los frameworks que colaboran para implementar la arquitectura MVC, las vistas HTML e inversin del control son principalmente: Spring, JSP y las tecnologas que hemos comentado en los ejemplos previos (ver subsecciones 4.2.1 y 4.2.3).

Casos de Uso y Modelo de Dominio


Veamos los casos de uso de KStore y una breve descripcin de stos:

Figura 4.17: Casos de uso en KStore.

Buscar Productos: mediante una expresin de texto libre, el usuario indica el/los productos de inters y el sistema presenta un listado paginado de resultados. Este caso de uso puede comenzarse desde cualquier pantalla del sitio utilizando la barra de bsqueda y es particularmente importante por ser el punto de entrada desde el cual se inician el resto de los casos de uso. Agregar/Quitar Producto en Carrito de Compras: consiste en permitir al usuario administrar los productos que busc en el transcurso del caso de uso Buscar Productos, llevando cuenta de cules son de su inters. Para utilizar el caso de uso Comprar Productos en Carrito es necesario haber iniciado este caso de uso. Comprar Productos en Carrito: este caso de uso consiste en adicin de los productos agregados al carrito y la compra mediante una tarjeta de crdito simulada. Este paso requiere que el usuario demuestre ser un humano y no un robot mediante un CAPTCHA (Ahn et al., 2004).

146

CAPTULO 4.

EXPERIMENTACIN

Ver Enlace Patrocinado: este caso se inicia cuando el cliente selecciona uno de los enlaces patrocinados. Comnmente el resultado de este caso es la aparicin de una pantalla promocional o la salida de este sistema hacia otro.

El diagrama de clases de KStore es el siguiente:

Figura 4.18: Diagrama de clases de KStore.

nuevamente utilizamos estereotipos para mostrar las propiedades de indexacin:

Figura 4.19: Clases de KStore con estereotipos de indexacin.

Hagamos una descripcin breve de estas entidades y sus relaciones:

Item: representa los productos pasibles de ser comprados por los clientes. En este ejemplo indexamos slo el campo title, el cual nos da suciente informacin para la mayora de las bsquedas. A efectos de mantener la simplicidad del modelo, omitimos almacenar atributos como el stock, el cual no es requerido en nuestros casos de uso pero bien podra usarse en un sistema real.

4.2.

PRUEBAS CON APLICACIONES DE REFERENCIA

147

Category: esta entidad representa un concepto de dominio bajo el cual se agrupan items. Algunos objetos que podran ser instancias de esta clase: Electrnica, GPS, etc. En este ejemplo nos limitamos a indexar los ttulos de las categoras, lo cual da la posibilidad de construir un ndice de items por categoras.

Advertising: es una publicidad que se presenta en el contexto del caso de uso Buscar Productos. Estos objetos son recuperados por el motor de bsqueda utilizando un proceso similar al de bsqueda de items con el n de proveer al cliente una alternativa relevante a los resultados de bsqueda que se le presentan. Los objetos advertising son indexados en ndices separados de los items para evitar que participen del proceso de recuperacin y valoracin de los items.

Site: representa una instancia particular del sistema KStore para una zona determinada. Normalmente un site corresponde a un dominio web y todos los objetos que discutimos previamente se agruparn dentro de un sitio particular. El hecho de contar con un objeto site nos permite formalizar conocimiento como moneda local, dominios web, tasa de cambio respecto de monedas de referencia, etc.

Veamos algunas pantallas que muestran el ujo de compra en KStore:

Figura 4.20: Pantalla principal de bsqueda de KStore.

148

CAPTULO 4.

EXPERIMENTACIN

Figura 4.21: Resultados para la query apple ipod nano blue. En la columna central tenemos los resultados de bsqueda, a la izquierda los anuncios contextuales, a la derecha el carrito de compras y en la parte inferior el paginador.

Figura 4.22: Los resultados se agregan dinmicamente al carrito de compras, el cual luego pasa al proceso de pago (checkout).

4.2.

PRUEBAS CON APLICACIONES DE REFERENCIA

149

Figura 4.23: Conrmacin de la compra. El formulario de pago requiere que ingresemos los datos de la tarjeta de crdito y un cdigo vericador para evitar usos fraudulentos. En la parte inferior se encuentra la lista de productos que estamos comprando junto al monto total a pagar.

Figura 4.24: Pago completado. El sistema conrma la operacin y presenta un botn para continuar utilizando el sistema desde la pgina de inicio.

150

CAPTULO 4.

EXPERIMENTACIN

Funciones de IR en KStore
Las tareas de recuperacin de informacin son centrales a KStore ya que soportan el modelo de negocio de la tienda en lnea tanto en cuanto a compra de productos como respecto de la publicidad. El mapeo de entidades no present nuevos desafos ya que es relativamente simple. Sin embargo, fue conveniente separar los anuncios y los items en ndices diferentes, tal de aislar la recuperacin de unos y otros. Esto no solo permiti un cdigo ms simple, sino que facilita la paralelizacin de la bsqueda de anuncios e items en forma concurrente. Para este ejemplo utilizamos el plugin de indexacin para Hibernate y el de ndices en disco Berkeley. El primero de estos plugins fue necesario ya que el modelo de dominio se indexaba utilizando Hibernate y fue natural replicar los eventos CUD utilizando este plugin. El plugin Berkeley fue utilizado para contar con ndices persistentes. A su vez, nuestro indexador oine requiere un ndice persistente para que la aplicacin pueda consultar el ndice invertido.

Otras caractersticas de la solucin


En KStore tuvimos la intencin de generar un corpus similar al de un sitio web real de tamao pequeomediano. Para esto jamos como objetivo generar corpus de volumen no menor a los 5.000 productos (items). Para generar este corpus se construy un software ad-hoc (robot) cuya tarea fue extraer informacin real de sitios comerciales y utilizar dicha informacin en la generacin del corpus. El robot construido efectu pedidos REST (Fielding, 2000) a una API pblica del sitio web Shopping.com, desde el cual se extrajeron items con sus correspondientes categoras. El robot recibi un archivo de texto plano con 100 palabras clave ingresadas por el autor y, por cada una de ellas, efectu un llamado a la API REST de bsqueda por palabra de Shopping.com. Este proceso produjo como resultado un archivo de texto plano con ttulos, descripciones, categoras y precio en dlares estadounidenses para 6149 items. A partir de dichos items se construy el corpus de categoras, el cual se compone de 93 categoras distintas. Por ltimo, se escribi un proceso que lee el archivo producido por el robot y almacena dichas entidades en Hibernate. Los objetos almacenados en Hibernate se indexaron transparentemente por medio de los plugins para Hibernate y BerkeleyDB provistos en nuestro framework (y congurados mediante inyeccin de dependencias desde Spring). En resumen, el proceso de generacin del corpus comprendi:

1. Confeccin de lista de keywords de bsqueda para Shopping.com 2. Ejecucin del robot 3. Ejecucin del proceso indexador

Con posterioridad a la construccin de la bsqueda de items surgi la propuesta de agregar como aditamento funcional la indexacin y recuperacin de anuncios publicitarios. El hecho de agregar los anuncios publicitarios con el sistema en funcionamiento slo requiri replicar el proceso indexador variando la lectura del archivo de texto del cual provenan los items para que se lean los ttulos, subttulos y enlaces correspondientes a los anuncios. La posibilidad de particionar los ndices por entidad permiti separar la indexacin de anuncios en un ndice independiente, de forma tal que la bsqueda de estas entidades no interri con la bsqueda de items. A diferencia del corpus de items, el de anuncios se construy en forma totalmente manual por lo que cuenta pocos anuncios en relacin a la cantidad de items.

4.3.

PRUEBAS DE CALIDAD Y RENDIMIENTO

151

Notas acerca de Experimentacin y Refactorizacin


La experimentacin en situaciones de uso real produjeron una iteracin sobre el software construido, aportando una mejora signicativa al software entregado con esta tesis. En este apartado hacemos algunos comentarios puramente experimentales acerca del aprendizaje adquirido en el desarrollo de estas tres aplicaciones de ejemplo. La primera aproximacin a integrar las aplicaciones con el framework de IR y sus dependencias fue la de ubicar manualmente todos los archivos Java (JAR) en una ubicacin donde el cargador de clases Java pueda encontrarlos. Este mecanismo de administracin de dependencias es efectivo pero poco mantenible ya que se producen conictos de versiones, redundancias y esfuerzos de mantenimiento innecesarios. Para mejorar la administracin de estos proyectos se adopt un software robusto para administracin de proyectos: Apache Maven (Apache Foundation, 2010). La adopcin de Maven permiti:

que las tres aplicaciones puedan incluir el framework de IR, sus plugins y dependencias automticamente con unas pocas lneas de conguracin XML, delegar en Maven la resolucin de dependencias de cada mdulo, generar lanzamientos (releases) con automatizacin de casos de prueba, simplicar la administracin de los proyectos.

La adopcin de Maven abri la posibilidad de desacoplar partes del framework, cambiando una estructura monoltica en la cual un nico mdulo hace todo por una arquitectura de plugins. Este cambio de estructura consisti en partir el framework originalmente monoltico en:

un mdulo bsico de IR (core), plugin de interaccin con Hibernate, plugin de interaccin con iBATIS, plugin para backend de ndices en BerkeleyDB, plugin de indexacin distribuida oine con JMS.

Esta descripcin acerca de la iteracin que hicimos sobre la administracin del proyecto es ejemplo del acierto en construir distintas aplicaciones reales donde probar el framework.

4.3.

Pruebas de Calidad y Rendimiento

En esta seccin vamos a explicar cmo se prob que el software construido es correcto y cul es su rendimiento de indexacin y recuperacin de objetos, estableciendo algunas comparaciones con frameworks similares. La subseccin 4.3.1 desarrolla las pruebas de calidad. La subseccin 4.3.2 muestra las pruebas de rendimiento y las compara con lo obtenido en frameworks similares.

4.3.1. Pruebas de Calidad


El framework de IR se construy siguiendo la tcnica de programacin conocida como Test Driven De-

velopment (Beck, 2002). Esta tcnica tiene como metodologa de trabajo construir el sistema completo
a partir de pruebas unitarias. La metodologa de TDD produce naturalmente un diseo desacoplado y, dado que slo se desarrolla lo que se est probando, los tests resultantes cubren un alto porcentaje del cdigo.

152

CAPTULO 4.

EXPERIMENTACIN

Las pruebas unitarias tienen por objetivo probar el funcionamiento aislado de una funcionalidad. En esta subseccin explicamos algunos reportes y mtricas que nos indican el grado de certeza que podemos tener acerca del correcto funcionamiento del framework. La distribucin de pruebas por mdulo del framework es la siguiente (los valores que siguen corresponden al release 1.0 del framework ): Core Search Engine: 192 tests Plugins Berkeley, Hibernate, iBATIS y JMS: 27 tests Sumando estos nmeros, el release pasa con xito 219 tests. Existen varias mtricas para evaluar cun representativos son los tests. Una de las mtricas bsicas ms utilizadas en la evaluacin de los tests es la cobertura de cdigo (o simplemente cobertura ). La cobertura mide qu cantidad/porcentaje de lneas de cdigo son ejecutadas por los tests. Cuando analizamos la cobertura, debemos tener cuidado para no llegar a falsas conclusiones. Por ejemplo, el siguiente par test/programa tiene una cobertura del 100 % pero sin embargo falla en todos los casos excepto el probado:
public class

BadMathTest ( )

// t e s t que c u b r e e l 100 % d e l c d i g o c u b r i e n d o s l o e l c a s o p a r t i c u l a r que p a s a e l t e s t


@Test
public void

exponentialFunctionTest ()
new

Assert . assertEquals (1 , } }

BadMath ( ) . e x p o n e n t i a l ( 0 ) ) ;

// mal a j u s t e de f ( x )=e^x p o r g ( x )=x+1


public class int

BadMath ( )

{ x) {

public

exponential ( int

return

x +1;

} } por otro lado, las pruebas de este par test/progama son mejores que las del caso anterior, aunque logra menor cobertura:
public class

GoodMathTest ( )

// un t e s t m e j o r p e r o que c u b r e poco c d i g o
@Test
public void

exponentialFunctionTest ()

Assert . assertEquals ( Assert . assertEquals ( Assert . assertEquals ( Assert . assertEquals ( } }

1.0 f
0.0 f , 1.0 f 10.0F

, , ,

new new new new

GoodMath ( ) . l o g ( 0 . 1 d ) ) ; GoodMath ( ) . l o g ( 1 . 0 d ) ) ; GoodMath ( ) . l o g ( 1 0 . 0 d ) ) ; GoodMath ( ) . l o g ( 1 0 0 . 0 d ) ) ;

// buen a j u s t e p o r t a y l o r , p e r o con c h e q u e o s que b a j a n l a c o b e r t u r a


public class

GoodMath ( )

{ x) {

public

float

l o g ( Double {

i f ( x== n u l l ) th row new

I l l e g a l A r g u m e n t E x c e p t i o n ( " Can ' t

calculate

log

of

null ") ;

4 Los

releases se etiquetan en el repositorio de cdigo para poder ser reconstruidos con facilidad

4.3.

PRUEBAS DE CALIDAD Y RENDIMIENTO

153

if (

x <= 0 . 0 d
new

{ calculate log of negative

th row

I l l e g a l A r g u m e n t E x c e p t i o n ( " Can ' t

numbers " ) ; }

// d e s a r r o l l o en s e r i e de t a y l o r
return

taylorSeriesForLog (x) ;

} } La cada en la cobertura se da porque las excepciones no son cubiertas por los tests. Esto no quiere decir que los tests no deban provocar excepciones, sino que el slo hecho de tener una buena cobertura no es suciente para tener buenos tests. Habiendo explicado esto, podemos continuar con la cobertura de nuestro framework. Para el clculo de cobertura utilizamos un plugin de Maven llamado Cobertura (Doliner, 2006) y analizamos los reportes para el mdulo core del framework. La ejecucin inicial de Cobertura nos indica una mtrica del 54 % de cobertura (1925/3559 lneas de cdigo). Dado que inicialmente este nmero pareci bajo, analizamos los reportes y encontramos:

Muchsimas lneas de cdigo que no son cubiertas por los tests se encuentran en los stemmers. Dado que stos se asumen correctos por construccin (son cdigo auto generado utilizando Snowball), deberamos excluirlos de nuestros clculos. Existen muchas excepciones no lanzadas durante los tests que corresponden a parmetros nulos, errneos o excepciones lanzadas por la JVM como producto de operaciones, por ejemplo, de reexin. En muchas clases se auto generaron los mtodos hashCode() e equals() mediante el IDE Eclipse. Estos mtodos generalmente no son alcanzados en su totalidad por los tests, ya que su estructura suele hacer que retornen rpidamente sin ejecutar todas sus lneas. Adems, asumiendo que Eclipse fue probado correctamente, no es necesario que los test alcancen estos mtodos ya que se suponen correctos. Los mtodos toString() suelen ser triviales pero no suelen ser alcanzados por los tests. En algunos casos se presentan versiones sobrecargadas de un mtodo simplemente para adoptar un valor por defecto (haciendo que un mtodo invoque al otro). Este tipo de prcticas tampoco suelen probarse por su trivialidad.

Si eliminamos el aporte de los stemmers, la cobertura asciende a 65 % (1641/2515 lneas de cdigo). Ahora, si asumiramos que los mtodos hashCode(), equals(), excepciones y toString de las 140 clases intervinientes aportan un 15 % de cdigo adicional, la cobertura se ubicara alrededor del 80 %, lo cual parece ser una buena marca para un prototipo como el que hemos construido. Adems de la cobertura, existen muchas otras mtricas asociadas a la complejidad del cdigo, las cuales exceden el tratamiento que le queremos dar al tema.

4.3.2. Pruebas de Rendimiento


En esta subseccin vamos a exponer los resultados de algunas pruebas de rendimiento que efectuamos sobre nuestro software. Si bien el foco de este trabajo no est en que la versin actual del framework tenga un rendimiento superior a las herramientas del estado del arte, queremos vericar que no existen comportamientos anmalos. Estos comportamientos anmalos podran ser, por ejemplo, que el crecimiento lineal en el nmero de objetos a indexar incremente el tiempo de indexacin o bien el uso de memoria en forma no lineal.

154

CAPTULO 4.

EXPERIMENTACIN

Adems de detectar comportamientos anmalos, haremos un estudio acerca de dnde se encuentran los cuellos de botella en la indexacin y recuperacin, a efectos de saber dnde tenemos oportunidades de optimizacin.

Descripcin del Laboratorio de Pruebas


Todas las pruebas se realizaron en un equipo con la siguiente conguracin:

procesador de doble ncleo Intel Core 2 Duo de 1.83 GHz 2 GB RAM Ubuntu 10.04 LTS, kernel 2.6.32-23-generic Sun Java HotSpot(TM) Server VM (versin 1.6.0_21)

Prueba de Indexacin en Memoria


El objetivo de esta prueba es comprobar experimentalmente la estabilidad y linealidad del tiempo de indexacin, para lo cual vamos a utilizar el corpus de items de KStore. En esta prueba medimos los tiempos de indexacin para los 6619 items, indexndolos en lotes de a 100. Las capas de indexacin se conguraron para utilizar DefaultIndexerService, DefaultIndexerPipeline y MemoryIndexWriterFactory. En los siguientes grcos vemos los tiempos de indexacin acumulativos y promedio para los 66 lotes:

Figura 4.25: Tiempos de Indexacin Acumulativos. El grco muestra en trazos continuos de color cuatro ensayos ms dos trazos discontinuos que representan un desvo a partir del promedio de los cuatro ensayos.

4.3.

PRUEBAS DE CALIDAD Y RENDIMIENTO

155

Figura 4.26: Tiempo de Indexacin Promedio. Este grco muestra en forma de columnas el tiempo promedio de indexacin de cada lote para los cuatro ensayos de la gura anterior.

El loteo de items tiene que ver con la utilizacin del mtodo IndexerService.bulkCreate(), el cual recibe los items en listas. Variando el nmero de lotes desde 1 hasta 6619 items por lote no encontramos variaciones signicativas en los tiempos de indexacin. Esto nos induce a pensar que el loteo no es necesario cuando se trabaja en memoria.

Si repetimos la prueba anterior sin utilizar el stemmer snowball del ingls para tratar los ttulos de los items, los tiempos de indexacin se reducen signicativamente:

156

CAPTULO 4.

EXPERIMENTACIN

Figura 4.27: Tiempos de indexacin acumulativos comparativos con y sin stemming para el corpus KStore, ndice en memoria.

Figura 4.28: Tiempos de indexacin promedio por lote comparativos con y sin stemming para el corpus KStore, ndice en memoria.

Los datos de las pruebas anteriores corresponden a muestras aleatorias tomadas entre varias indexaciones,

excluyendo la primera corrida. Esta precaucin debe tomarse debido a que la primera indexacin incurre

4.3.

PRUEBAS DE CALIDAD Y RENDIMIENTO

157

en una penalidad de carga de clases y caches que en un sistema en funcionamiento ya encontraramos en memoria. Veamos cmo varan los valores de la misma estadstica tomando slo las primeras corridas del indexador:

Figura 4.29: Tiempos de Indexacin Acumulativos para Primeras Corridas. En trazos continuos de color tenemos los cuatro ensayos ms dos trazos discontinuos que representan un desvo a partir del promedio.

Figura 4.30: Tiempo de Indexacin Promedio para Primeras Corridas del Indexador. La lnea de tendencia muestra que el costo en los primeros lotes es superior al de los ltimos lotes, donde los tiempos se estabilizan.

158

CAPTULO 4.

EXPERIMENTACIN

Como se puede apreciar en la gura anterior, respecto de las indexaciones normales, la primera corrida incrementa los tiempos de ejecucin en un orden de magnitud.

Pruebas Comparativas de Indexacin en Memoria


En este apartado repetimos las pruebas del apartado previo, indexando el corpus KStore sobre Apache Lucene. La indexacin en Lucene requiere la creacin explcita de un Document. En nuestro caso, el documento se deni de la siguiente forma: Item item = itemsToBeIndexed . get ( i ) ; Field (" id " , ( ( L o n g ) i t e m . g e t I d ( ) ) . t o S t r i n g ( ) , F i e l d . S t o r e . YES , i t e m . g e t T i t l e ( ) , F i e l d . S t o r e . NO, F i e l d . I n d e x .

d o c . a d d ( new d o c . a d d ( new

F i e l d . I n d e x . NOT_ANALYZED) ) ; Field (" t i t l e " , ANALYZED) ) ; Es decir, indexamos los tems por su ttulo, almacenando su identicador en el ndice invertido, tal de poder hidratar los objetos luego de la recuperacin. Si comparamos la indexacin en memoria del corpus KStore sobre nuestro framework versus la indexacin en memoria con Lucene, tenemos el siguiente grco comparativo:

Figura 4.31: Tiempos de Indexacin Comparativos. En la prueba con el corpus KStore, nuestro framework fue ms rpido que Lucene tanto en los casos en los que procesamos el texto con stemming como en los que no lo hicimos.

Analizando la gura (4.31), vemos que los dos frameworks sufren una degradacin al aplicar anlisis sobre los textos . Un aspecto curioso de la implementacin de Lucene es que el mtodo close() de su ndice en memoria toma un tiempo similar al de toda la indexacin junta. Este tiempo puede visualizarse en el grco (4.31) como una rampa pronunciada sobre su lmite derecho.

5 En

rigor, en nuestro framework slo eliminamos el stemming, manteniendo tanto la delimitacin como la normalizacin.

4.3.

PRUEBAS DE CALIDAD Y RENDIMIENTO

159

An quitando el tiempo que toma el mtodo close(), nuestro framework es hasta un 60 % ms veloz cuando no se utiliza anlisis ni stemming y hasta un 15 % ms veloz cuando se utiliza anlisis y stemming. Incluyendo el tiempo que insume el mtodo close(), nuestro framework llega a ser un 73 % ms rpido sin anlisis ni stemming y un 43 % ms veloz cuando los incluimos.

Pruebas de Indexacin en BerkeleyDB


As como en el apartado previo hicimos pruebas de indexacin sobre memoria RAM, en este apartado vamos a estudiar el rendimiento utilizando nuestro plugin BerkeleyDB (ver subseccin 3.3.3).

Las pruebas realizadas sobre este plugin son las mismas que efectuamos en el apartado anterior, es decir, indexamos el corpus KStore en lotes de 100 items.

Antes de presentar los resultados, es preciso comentar que el plugin BerkeleyDB permite trabajar tanto en forma transaccional como no transaccional. Desde el punto de vista del rendimiento, trabajar en forma transaccional degrada la performance en forma muy fuerte. Sin embargo, es sensato trabajar en modo transaccional si el corpus es pequeo, si disponemos de hardware de altas prestaciones o si no tenemos otra opcin para resguardar la integridad de nuestro proceso.

Conociendo conceptualmente el impacto que tiene el modo transaccional, estamos en condiciones de presentar los resultados experimentales:

Figura 4.32: Indexacin No Transaccional en BerkeleyDB. La lnea superior (verde) corresponde a una primera corrida, la cual hemos visto que suele demorar ms. El resto de las lneas se corresponde con un muestreo de corridas intermedias, las cuales no sufren el efecto anterior.

160

CAPTULO 4.

EXPERIMENTACIN

Figura 4.33: Tiempos de indexacin promedio por lote para la indexacin no transaccional en BerkeleyDB. A diferencia del caso en memoria, el ndice se degrada notablemente a medida que se agregan lotes. La lnea roja marca la tendencia lineal para la evolucin del tiempo promedio por lote.

Figura 4.34: Indexacin Transaccional en BerkeleyDB. La versin transaccional toma hasta 30 veces ms tiempo en indexar los lotes y diluye el efecto de primeras corridas.

Vemos entonces que la indexacin transaccional toma aproximadamente 30 veces ms que la versin no transaccional. En el caso transaccional, tambin vemos que el retardo en la primera corrida se diluye debido a que el tiempo total de indexacin es muy largo.

4.3.

PRUEBAS DE CALIDAD Y RENDIMIENTO

161

Sin embargo, el ndice no transaccional s logra buenas marcas. La lnea de tendencia gracada en color rojo en la gura (4.33) tiene frmula:

t (Li ) = 0, 01966i + 0, 27646


donde:

[s]

t (Li )

es el tiempo de indexacin en segundos del lote

cada lote

Li

tiene 100 items

Asumiendo que la degradacin de la performance sigue esta tendencia lineal, podemos calcular cunto tiempo nos tomara indexar un corpus de

1000

lotes (100000 items):

100

t (Li ) = 10116, 29
i=1

s.

= 168, 60

min

2, 8 =

hs

Lo cual es una muy buena marca para esta versin no optimizada del ndice Berkeley.

Pruebas de Recuperacin en Memoria


En esta subseccin vamos a estudiar el rendimiento de nuestro framework en cuanto a recuperacin de objetos. Dado que los tiempos invertidos en recuperacin se exponen directamente a los usuarios nales de la aplicacin, la tarea de recuperacin es an ms importante que la de indexacin. A continuacin explicamos el diseo de las pruebas de recuperacin en memoria junto con sus resultados. El diseo de la prueba comprendi:

ndice en memoria, corpus KStore, un conjunto 4024 queries distintas, tomadas de las primeras y segundas palabras de los items del corpus KStore, un conjunto de 50 ensayos sin efectos de retardo por primeras corridas.

La variable que nos interesa medir en este caso es el

q = tiempo

promedio de ejecucin por consulta.

La medicin del tiempo promedio por consulta incluye las operaciones:

Procesamiento de Textos: normalizacin y construccin del rbol de consulta, Recuperacin: acceso a ndices, operaciones sobre posting lists y valoracin segn modelo vectorial.

Bajo este diseo, obtuvimos los resultados:

q = 4, 4376 105 [s/query] = 0, 044376 [ms/query] q = 0, 7127 105 [s/query] = 0, 007127 [ms/query]
Lo cual nuevamente es una muy buena marca. Si extrapolamos esta estadstica destinando un segundo completo a resolver consultas que toman un tiempo

, podramos recuperar:

#queries en 1 segundo

1000 ms s = 22534 [queries/s] 0, 044376 ms q

162

CAPTULO 4.

EXPERIMENTACIN

Esto es, podramos resolver ms de 22.000 consultas por segundo. Es muy importante conocer si estos resultados son comparables a los de otras alternativas como Apache Lucene. Para esto repetimos las pruebas anteriores utilizando el RAMDirectory de Lucene y efectuamos consultas sobre el atributo title de la clase Item. Ejecutando las pruebas sobre Lucene, obtuvimos los resultados:

qLucene = 6, 6634 105 [s] = 0, 066634 [ms] qLucene = 0, 6365 105 [s] = 0, 006365 [ms]
Este resultado de Lucene tambin es muy bueno, sin embargo, si extrapolamos nuevamente la estadstica, ahora podramos efectuar: #queries en 1 segundo para Lucene

1000 ms s = 15007 [queries/s] 0, 066634 ms q

En resumen, para un mismo intervalo de tiempo de un segundo, nuestro framework permite ejecutar un 50 % ms de consultas sobre el corpus KStore que lo que permite Lucene.

Pruebas de Recuperacin en BerkeleyDB


Las pruebas de recuperacin sobre el ndice BerkeleyDB son prcticamente iguales a las que hicimos sobre el ndice en memoria, con la nica excepcin de que indexamos y recuperamos los objetos hacia/desde el ndice Berkeley en modo no transaccional. La recuperacin en Berkeley tuvo el siguiente resultado:

qBerkeley = 2, 2748 [ms] qBerkeley = 0, 1811 [ms]


si repetimos la bsqueda para el caso transaccional, encontramos que el rendimiento es casi idntico:

qBerkeleyT rans = 2, 2907 [ms] qBerkeleyT rans = 0, 0386 [ms]


Vemos entonces que la transaccionalidad afecta el rendimiento de la indexacin, mientras que la recuperacin no sufre de penalizacin alguna. Con el ndice Berkeley no transaccional y un equipo como el descripto al principio de esta seccin, calculemos cuntas bsquedas por segundo podemos servir sobre el corpus KStore:

#queries en 1 segundo para Berkeley DB (no transaccional)

1000 ms s = 439 [q/s] 2, 2748 ms q

Al igual que observamos con la indexacin, el rendimiento en memoria es muy superior al obtenido en disco con BerkeleyDB. Sin embargo, en el caso de la indexacin la operatoria en memoria mejoraba los tiempos aproximadamente por un factor de factor de

400,

mientras que en el caso de la recuperacin tenemos un

50.

Esto nos permite obtener las siguientes conclusiones:

la transaccionalidad degrada el rendimiento muchsimo ms en la indexacin que en la recuperacin, BerkeleyDB mejora su rendimiento en escenarios de lecturas intensivas (recuperacin) por sobre el escenario de escrituras intensivas (indexacin).

Con esto terminamos las pruebas cuantitativas de rendimiento. En la prxima subseccin analizaremos cualitativamente la integracin de nuestro framework con PetClinic y haremos una comparativa general de caractersticas con el resto de las herramientas.

4.3.

PRUEBAS DE CALIDAD Y RENDIMIENTO

163

4.3.3. Anlisis Comparativo Cualitativo


En esta seccin vamos a comparar nuestra solucin respecto de alternativas similares en trminos cualitativos. Primero vamos a hacer una breve resea de qu similitudes y diferencias encontramos en la implementacin de PetClinic por Compass y luego vamos a escoger una serie de items sobre las que comparar las herramientas.

PetClinic sobre Compass


En este apartado seleccionamos algunos puntos clave sobre los que comparar nuestra implementacin de PetClinic con la provista por Compass:

Mapeo XML: en vez de utilizar un mapeo por medio de anotaciones (tambin soportado por Compass), se utilizan un archivo XML llamado petclinic.cpm.xml. Semntica de Mapeos: si comparamos el archivo petclinic.cpm.xml con nuestro mapeo de la gura (4.2), encontramos que el mapeo es muy similar. Los dos frameworks mapean la jerarqua de clases, incluyendo Entity, NamedEntity, Person, Vet y Pet. En el caso de Compass tambin se mapea la clase Specialty. ORM: en el ejemplo de Compass se soportan simultneamente JDBC, Hibernate y OJB mediante el intercambio de archivos de conguracin de Spring y la utilizacin del patrn de diseo DAO (Data Access Objects). En nuestro framework, si bien el ORM nos es transparente a travs de los plugins, la implementacin que hicimos de PetClinic slo trabaja con Hibernate. Indexacin: en los dos ejemplos se utiliz la indexacin por eventos. La conguracin acerca de cmo hacerlo vara signicativamente entre frameworks, pero en los dos casos el objetivo es el mismo. Recuperacin: en el caso de Compass, la recuperacin se efecta a travs de una clase interna del framework que delega la visualizacin a una vista congurada mediante Spring. En nuestro ejemplo de PetClinic no utilizamos un controlador provisto por nuestro framework sino que hicimos un controlador propio que efecta explcitamente la bsqueda.

Dado que nuestra prueba sobre PetClinic est basada en la versin que acompaa a Compass, es natural que no hayan existido grandes diferencias entre una y otra versin. Los puntos anteriores corresponden a una instancia particular de la utilizacin de los dos frameworks. En el prximo apartado seleccionamos caractersticas generales sobre las que efectuar una comparativa.

Comparacin General de Caractersticas


En este apartado seleccionamos algunos puntos sobre los que nos interesa evaluar los distintos frameworks estudiados. Esta lista coincide mayormente con los puntos elegidos para analizar Compass y Hibernate Search en la subseccin (2.4.4). Naturalmente, los trabajos ms maduros han incorporado a lo largo del tiempo mayor cobertura de casos de uso satelitales (ndices sobre RDBMS, resaltadores de resultados, etc). Sin embargo, queremos guiarnos por la adecuacin de la herramienta al problema que queremos resolver y no por los caractersticas que pueden incorporarse iterativamente. Por esto, elegimos las caractersticas que son las que consideramos fundamentales al problema de indexacin de objetos, dejando un ltimo apartado para caractersticas satelitales e integracin con otros frameworks u ORMs.

Caractersticas Generales
to estructural y semntico.

Al analizar las caractersticas generales de HS y Compass (ver subseccin

2.4.4), planteamos tres problemas: abstraccin incompleta, infraestructura correctiva y desaprovechamien-

La abstraccin incompleta tiene que ver con la presencia en HS y Compass de objetos de Lucene y conceptos de orientacin a documentos. Estas caractersticas no estn presentes en nuestro framework,

164

CAPTULO 4.

EXPERIMENTACIN

donde las consultas, ltros y ordenamiento se efectan en trminos de los objetos originales y no de documentos. La infraestructura correctiva de HS y Compass eran un conjunto de caractersticas implementadas para reutilizar Lucene y ocultar sus limitaciones (bloqueos, optimizacin de ndices, precalentamiento de lectores, etc). En la infraestructura de nuestro framework encontraremos que este tipo de problemas no aplican. El desaprovechamiento estructural tiene que ver con la delegacin en Lucene de los problemas de recuperacin, evitando consultas a partir de objetos y valoraciones estructurales del tipo PageRank y HITS. En este campo, nuestro framework crea la capacidad de efectuar consultas a partir de objetos. En cuanto a anlisis de enlaces entre objetos, esta caracterstica no fue implementada an en nuestro framework. Sin embargo, los ndices fueron diseados de forma de ser adecuados para un clculo de este tipo utilizando el registro maestro. Adems explicamos que el hecho de que Lucene sea el motor de IR de base para HS y Compass provoca dos problemas. El primer problema es que la evolucin de estas herramientas depende de la evolucin de Lucene. La segunda es que para aprovechar las mejoras en Lucene, los usuarios del framework deben esperar a que HS y Compass generen una versin compatible con la nueva versin de Lucene.

Comportamiento como Framework

Este punto tiene que ver con lo que establecimos en la proposi-

cin 1 respecto de tomar un comportamiento de framework de caja negra. En este sentido, los tres frameworks de indexacin de objetos obtienen un adecuado comportamiento de caja negra. El nico rezagado es Lucene, quien tiene comportamiento de librera.

Indexacin y Modelo de Dominio

Cuando analizamos este punto en la subseccin (2.4.4), efectu-

amos cinco proposiciones que vamos a retomar para discutir este tem. La proposicin 2 propona distintos niveles de soporte transaccional. En este sentido, Compass es el nico que da garantas transaccionales, siendo que el resto de las herramientas slo garantiza consistencia bsica del ndice. Muy relacionada a la proposicin anterior, la proposicin 3 plantea que las operaciones sobre los ndices se deben hacer evitando repetir cdigo asociado a transacciones o a lecturas y escrituras de ndices. Este es un problema que est mayormente resuelto en todos los frameworks. La siguiente es la proposicin 4, la cual hablaba de la necesidad de proveer indexacin automtica de eventos CUD en el ORM. En este sentido, los tres frameworks de indexacin de objetos soportan este sistema, siendo que nuestro framework y Compass son los nicos que permiten trabajar con distintos ORMs. HS slo indexa automticamente los eventos CUD del ORM Hibernate Core, mientras que Lucene no soporta indexacin automtica. La anteltima proposicin plantea requerimientos mnimos en cuanto a la expresividad del sistema de mapeos. En este punto, los tres frameworks de IR sobre objetos presentan una expresividad prcticamente equivalente. Mas all de pequeas diferencias de forma, no hay grandes diferencias de caractersticas entre estos tres frameworks. Sin embargo, Lucene s queda relegado frente al resto por no soportar el mapeo de entidades. Por ltimo, la proposicin 6 nos dice que la indexacin y la recuperacin deben utilizar representaciones polimrcas de los objetos de dominio. Hemos visto que HS y Compass exponen una serie de objetos no polimrcos como Document, Resource y Property. Sin embargo, tambin permiten trabajar con entidades polimrcas o idnticas a las de dominio. En nuestro framework dimos un paso adelante, eliminando cualquier objeto espejado de la entidad de dominio, referenciando los objetos nicamente mediante meta programacin, utilizando atributos de tipo Class y Field. Sin embargo, introdujimos objetos que representan el concepto de clave de objeto sin proveerlas como un reemplazo de la entidad indexada sino como un mecanismo para poder hidratarla desde el ORM.

Procesos de Indexacin

La proposicin 7 nos requera permitir una indexacin sincrnica con la

transaccin de negocio y otra asincrnica. En este sentido, todos los frameworks de indexacin de objetos implementan en la indexacin online, semi-online y oine, por lo que las diferencias tienen que ver con detalles implementativos.

4.3.

PRUEBAS DE CALIDAD Y RENDIMIENTO

165

Recuperacin, Queries, Matching y Acceso a Datos

La principal diferencia conceptual en materia

de acceso a datos es que nuestro framework incorpora un registro maestro de objetos que permite conocer qu objetos estn indexados y bajo qu trminos. Creemos que la utilidad de este registro maestro justica el espacio extra que pueda requerir, por lo que es una ventaja comparativa entre frameworks. Dado el carcter experimental de nuestros ndices en BerkeleyDB, creemos es demasiado pronto para comparar la performance de los ndices en disco. Sin embargo, es preciso comentar que Lucene implementa tcnicas como front coding o skip pointers, los cuales sin duda colaboran en un excelente rendimiento. En cuanto a recuperacin, Lucene ha implementado una serie de caractersticas satelitales que nuestro framework todava no soporta: consultas por comodines, literales, edit distance, etc. El ltrado por atributos se efecta en forma muy distinta entre frameworks. En el caso de Lucene y sus derivados, el campo por el que se quiere ltrar se debe especicar en la consulta. En nuestro framework, el ltrado de campos se efecta como un pos ltro dentro de una cadena de ltrado. El inconveniente que tiene la versin de Lucene es que asume que el valor por el que se ltra es texto plano, cuando bien podra ser un otro objeto completo sobre el que aplicaramos el mtodo equals(). En este sentido, creemos que nuestra solucin se adeca mejor al problema que queremos resolver. En el ejemplo (2.4.5) propusimos un dar un paso adelante en cuanto a recuperacin, proponiendo la

recuperacin a partir de objetos. Este tipo de recuperacin trata al objeto recibido como al indexado,
generando los trminos adecuados al procesador de texto, selector de ndices y lenguajes. Este tipo de recuperacin slo est presente en nuestro framework y seguramente es la propuesta ms innovadora que incluimos en esta versin. La implementacin de un More Like This es soportada por Compass y HS, pero slo nuestro framework admite una consulta polimrca con el objeto para el cual se quiere buscar otros similares. Por ltimo, existe una pequea controversia en cuanto a la hidratacin de objetos. La proposicin 9 nos indica que la hidratacin es responsabilidad del ORM, lo cual tanto HS como nuestro framework respetan a rajatabla. Por otro lado, Compass est orientado a recuperar los objetos desde el ndice, lo cual explicamos que no es la mejor solucin. Sin embargo, si bien por defecto Compass efecta la hidratacin desde los ndices, tambin permite obtener la clave del objeto para una hidratacin desde el ORM.

Modelos de Information Retrieval

Tanto Hibernate Search como Compass dejan en manos de

Lucene la implementacin de los modelos de IR, por lo que nos corresponde analizar a ste ltimo. Lucene implementa una versin hbrida del modelo booleano y vectorial, utilizando el modelo booleano para ltrar documentos y el vectorial para priorizarlos. Si se desactiva la priorizacin, se obtiene un modelo booleano. Si bien nuestro framework implementa tanto el modelo booleano como el vectorial, a diferencia de Lucene, los implementa por separado generando implementaciones distintas de la interfaz Search. Si bien creemos que nuestro diseo es ms desacoplado y separa mejor los objetos que hacen sentido en un modelo de los del otro, no existe una razn objetiva para descartar una u otra propuesta. En cuanto a similitud, las frmulas de Lucene son algo ms complejas que las que implementamos en esta versin de nuestro framework. Sin embargo, tuvimos especial cuidado en disear los ndices de forma tal que eventualmente permitan implementar una frmula como la de Lucene. En trminos del modelo de IR, la mayor diferencia entre frameworks tiene que ver con el hecho de que nuestro framework adopta un modelo vectorial puro. En base a la explicacin que hicimos al introducir el modelo vectorial, donde presentamos las limitaciones del modelo booleano de conjunciones y disyunciones, creemos que nuestra eleccin es la adecuada. Otra diferencia importante entre Lucene y nuestro framework tiene que ver con los factores de impulso (boost). En nuestro framework no incluimos un factor de impulso para atributos o clases. La razn por la que no incluimos los factores de impulso es porque no son completamente necesarios y no queda claro que sea la forma correcta de lograr relevancia. Dado que en nuestro framework las frmulas de similitud son parametrizables, podemos lograr los mismos o mejores resultados sin impulsos. Por ltimo, la implementacin de reglas duras y blandas con HS, Compass y Lucene es considerablemente ms compleja de implementar en dichos frameworks. Nuestro framework est diseado para permitir

166

CAPTULO 4.

EXPERIMENTACIN

incorporar este tipo de reglas con facilidad, accediendo a los atributos originales de los objetos indexados y no a una representacin como texto plano.

Funcionalidades Satelitales e Interaccin con otros Frameworks

Este punto de comparacin

reere a cmo se ha expandido la herramienta para cubrir distintos casos de uso e integrarse en el ecosistema de herramientas que componen las aplicaciones. En este punto comparativo debemos excluir a nuestra herramienta, ya que el alcance de esta primera versin slo incluy las funcionalidades esenciales de la recuperacin de objetos. Entre las herramientas Lucene, Compass y Hibernate, encontramos que Lucene tiene gran cantidad de adicionales en cuanto a tcnicas de matching y acceso a datos, mientras que Compass es quien mejor se integra con otros frameworks y ORMs. Lucene posee una variedad muy amplia de analizadores (procesadores de texto), backends de almacenamiento de ndices invertidos, frmulas de similitud, etc. Adems, a lo largo del tiempo se han ido desarrollando herramientas como inspectores de ndices invertidos. Es decir, esta librera tiene un vasto repositorio de utilidades, siempre en el campo de IR sobre documentos. Por el lado de Compass encontramos una amplia variedad de adicionales, entre los que se encuentra el soporte para Spring MVC y otros ORM como TopLink o JDBC.

Aqu concluye el captulo de experimentacin. Para nalizar este trabajo, el prximo captulo expondr las conclusiones haciendo un repaso de los puntos ms importantes de cada captulo, poniendo en contraste los avances obtenidos y agregando una seccin de trabajos futuros.

Captulo 5

Conclusiones
En este capitulo nal presentamos nuestras conclusiones respecto de qu resultados obtuvimos a lo largo de esta tesis La primera seccin presenta las conclusiones propiamente dichas, haciendo una retrospectiva desde que comenzamos a introducir el problema en los captulos introductorios, hasta que terminamos de validar nuestra propuesta a travs de comparaciones. La segunda y ltima seccin consiste en proponer caractersticas adicionales que quedaron fuera del alcance de este trabajo y que conrmaran este software como una alternativa de primer nivel.

5.1.

Conclusiones

Recordando los comienzos del captulo introductorio, vimos que existen aplicaciones cuyos objetivos de negocio parecen ser ortogonales a la recuperacin de informacin, hasta que sta se vuelve un medio para lograr sus objetivos de negocio. Cuando esto ocurre, necesitamos un framework de IR que se integre transparentemente a la aplicacin y se adece al paradigma de programacin orientada a objetos y al ecosistema de frameworks que componen una aplicacin (por ejemplo, los ORM, los frameworks web, etc). En base a estos requerimientos hemos delimitado un problema de IR sobre objetos, el cual llamamos el problema del Domain Model Search. Al estudiar el estado del arte encontramos herramientas que buscan resolver este problema reutilizando libreras de IR sobre documentos. Analizando estas herramientas, hemos desarrollado una serie de proposiciones que nos guaron en cmo resolver el problema en base al aprendizaje que adquirimos estudiando el estado del arte. En base al estudio del campo de IR, del diseo de software y las herramientas anteriores, se analiz y dise un framework que se adeca al problema del Domain Model Search. Con el anlisis de qu solucin debamos construir conseguimos uno de los primeros objetivos de la tesis: delimitar el problema en distintas actividades de IR (recuperacin, indexacin, etc.) encontrando las distintas variantes de solucin y seleccionando las mejores alternativas. Una vez que se dise e implement un prototipo del framework fue necesario vericarlo. Para esto seguimos un patrn de diseo de frameworks que propone escribir tres aplicaciones distintas sobre las que probar nuestra herramienta, las cuales seleccionamos eligiendo: una estndar (PetClinic) y dos aplicaciones nuevas creadas para esta tesis (KStore y Klink), las cuales reejan negocios reales en la web. La experimentacin con estas aplicaciones nos permiti iterar sobre el anlisis y diseo del framework, hasta que llegamos al alcance necesario para observar los frutos en trminos comparativos. La primera comparacin que hicimos permite vericar que el rendimiento de nuestro framework se mantiene en el mismo orden de magnitud que el resto de las opciones en cuanto a tiempos de indexacin y recuperacin. En estas pruebas encontramos que nuestra solucin no solo se mantuvo en el mismo orden de magnitud sino que mejora las marcas de rendimiento de herramientas maduras del estado del arte. 167

168

CAPTULO 5.

CONCLUSIONES

El segundo conjunto de comparaciones lo hicimos en trminos cualitativos. Estos trminos cualitativos fueron escogidos con el mismo criterio con el que analizamos las herramientas del estado del arte, contrastando cada herramienta con las proposiciones que efectuamos. Esta comparativa cualitativa mostr (a) que nuestro framework incorpor las mejores prcticas para la resolucin del problema y (b) una serie de caractersticas a implementar como continuacin de este trabajo. En terminos de la motivacin que describimos en el captulo introductorio, podemos decir que cumplimos con el objetivo de aplicar las tcnicas de IR para encontrar informacin almacenada en los objetos de los modelos de dominio, determinando las actividades, componentes y alternativas de un motor de bsqueda sobre objetos. Finalmente, esta la tesis logr contribuir con una solucin concreta al problema de IR sobre objetos, presentando un problema de ingeniera de software, planteando sus alternativas de solucin, desarrollando un alternativa precisa y contrastando los resultados obtenidos respecto del estado del arte.

5.2.

Trabajos Futuros

En esta seccin enumeramos las caractersticas que podramos mejorar o incluir en nuestro framework para conrmar este software como una alternativa de primer nivel.

ndices
En la capa de acceso a datos proponemos agregar caractersticas y efectuar algunas mejoras sobre la implementacin actual: La primera caracterstica a mejorar es el plugin de ndices en disco. El plugin actual se podra redisear utilizando un motor de acceso a archivos ad-hoc que implemente front coding, skip pointers, merge generacional y dems tcnicas del estado del arte. En muchas aplicaciones es conveniente contar con una implementacin del ndice sobre un RDBMS tal de poder inspeccionar y mantener el ndice utilizando herramientas estndar. Para esto proponemos desarrollar un plugin que permita almacenar el ndice en un esquema relacional. Por ltimo, dado que en este momento la inspeccin de los ndices en disco requiere un desarrollo ad-hoc, deberamos proveer una herramienta genrica de inspeccin que muestre cmo se indexaron los objetos.

Information Retrieval
Como indicamos oportunamente, las frmulas de relevancia que implementamos son algo bsicas, por lo que uno de los puntos donde deberamos trabajar es en validar su ecacia sobre un corpus estndar y eventualmente iterar sobre ellas. Tambin relacionado con las tcnicas de valoracin, creemos que una futura versin debe mejorar el soporte para el puntaje estructural del tipo HITS y PageRank, facilitando almacenar puntajes por objeto en el registro maestro.

Caractersticas Generales
Existen algunos puntos donde nuestro framework todava es poco amigable y podemos mejorarlo con facilidad: Para mejorar la usabilidad del framework deberamos implementar una forma simple de obtener informacin agregada de los resultados como el nmero total de coincidencias e informacin de paginado. La conguracin de los mapeos se debera externalizar para permitir variaciones en caliente e indexacin de dominios sobre los que no se cuenta con el cdigo fuente original (recordar que las anotaciones requieren modicar el cdigo fuente). Hacer esta conguracin desde archivos XML o JSON es muy simple, pero requiere desarrollar una clase que lea el XML y efecte un trabajo similar al AnnotationCongurationMapper.

5.2.

TRABAJOS FUTUROS

169

Una caracterstica satelital soportada por algunos frameworks y que podramos incoporar tiene que ver con soportar el resaltado de las coincidencias en el contexto original del trmino. Esto requiere implementar un resaltador (highlighter) y el llamado Keyword In Context KWIC (ver subseccin 2.1.5). Por ltimo, creemos que una futura versin debera mejorar el soporte transaccional y el logging de eventos internos al framework.

Integracin con Otros Frameworks


Dentro de los planes de desarrollo de este framework, quisiramos agregar plugins para soportar la indexacin automtica desde otros ORMs como JDO, JPA, etc. Por ltimo, ltimamente han emergido lenguajes dinmicos compilados a bytecode Java como Groovy / Grails, a los cuales podramos darles soporte beneciarse de un framework de IR como el que construimos. An fuera de lenguajes compilados a bytecode Java, se podra portar la herramienta para trabajar en otros lenguajes similares.

170

CAPTULO 5.

CONCLUSIONES

Bibliografa
Ahn, L. et al. Apache.
URL `Telling humans and computers apart automatically'. Commun. ACM, tomo 47, 2, pgs. 5660, 2004. ISSN 0001-0782. doi:http://doi.acm.org/10.1145/966389.966390. `Apache ActiveMQ', 2009a .

http://activemq.apache.org/ http://lucene.apache.org/
`iBATIS Persistence Framework for Java', 2009c . `Apache Lucene', 2009b .

Apache.
URL

Apache.
URL

http://ibatis.apache.org/
`Apache Hadoop', 2010.

Apache.
URL

http://hadoop.apache.org/
`Apache Maven Project', 2010. Maven project management & comprehension

Apache Foundation.
tool. URL

http://maven.apache.org/ http://www.ams.org/featurecolumn/archive/pagerank.html http://people.ischool.berkeley.edu/~hearst/irbook/


`How Google Finds Your Needle in the Web's Haystack', 2006.

Austin, D.
URL

Baeza-Yates, R. et al.
URL

Modern Information Retrieval. ACM Press - Addison Wesley, 1999.

Baeza-Yates, R. et al. `Design trade-os for search engine caching'. ACM Trans. Web, tomo 2, 4, pgs.
128, 2008. ISSN 1559-1131. doi:http://doi.acm.org/10.1145/1409220.1409223.

Beck, K.
URL

Test Driven Development: By Example. Addison Wesley, 2002.


`Hibernate Search - cool, but is it the right approach? Year baby!' Blog, 2007a .

Bernard, E.
html

http://blog.emmanuelbernard.com/2007/06/hibernate-search-cool-but-is-it-right.
`Hibernate Search: Googling Your Java Technology-Based Persistent Domain Model'. En

Bernard, E.

JavaOne Conference. 2007b .

Compass Project.
URL

http://www.compass-project.org/

`Compass Search Engine', 2009.

Cutting, D. et al.

`Optimization for dynamic inverted index maintenance'. En SIGIR '90: Proceedings

of the 13th annual international ACM SIGIR conference on Research and development in information retrieval, (pgs. 405411). ACM, New York, NY, USA, 1990. ISBN 0-89791-408-2. doi:http://doi.acm.
org/10.1145/96749.98245.

Cutting, D.
URL

http://cutting.wordpress.com/2004/11/ http://lucene.sourceforge.net/talks/pisa/ http://msdn.microsoft.com/en-us/magazine/ee236415.aspx#id0400005


171 `Employing the Domain Model Pattern', 2009. `Lucene Talk at University of Pisa', 2004b .

`Dynamization and Lucene', 2004a .

Cutting, D.
URL

Dahan, U.
URL

172

BIBLIOGRAFA

Dean, J.

et al. `MapReduce: Simplied Data Processing on Large Clusters'. Communications of the

ACM, tomo 51, pgs. 107113, 2008.

Doliner, M.
URL

http://cobertura.sourceforge.net/
et al.

`Cobertura Code Coverage Tool', 2006.

Fang, H.

`A formal study of information retrieval heuristics'.

En SIGIR '04: Proceedings of

the 27th annual international ACM SIGIR conference on Research and development in information retrieval, (pgs. 4956). ACM, New York, NY, USA, 2004. ISBN 1-58113-881-4. doi:http://doi.acm.
org/10.1145/1008992.1009004.

Fielding, R.T. Fowler, M.


URL

Architectural Styles and the Design of Network-based Software Architectures.

Tesis

Doctoral, University of California, 2000.

http://www.martinfowler.com/books.html

Patterns of Enterprise Application Architecture. Addison Wesley, 2002.

Fowler, M.
URL

http://martinfowler.com/articles/injection.html
`Inversion of Control', 2005.

`Inversion of Control Containers and the Dependency Injection pattern', 2004.

Fowler, M.
URL

http://martinfowler.com/bliki/InversionOfControl.html
o
21 en Oihenart. Cuadernos de Lengua y Literatura, (pgs. 331

Galceran, C.L. `Lematizacin automtica y diccionarios electrnicos'. En C.I.M. y Sara Gmez Seibane,
ed., Lingstica Vasco-Romnica, n URL 343). Eusko Ikaskuntza, Donostia-San Sebastin, 2006.

http://hedatuz.euskomedia.org/4082/
et al.

Gamma, E. Gareld, E. Google.


URL

Design patterns: elements of reusable object-oriented software.

Addison-Wesley

Professional, 1995. `The Permuterm Subject Index: An Autobiographical Review'. Journal of the American

Society for Information Science, tomo 27, pgs. 288291, 1976.


`Google Search Appliance', 2009a .

http://www.google.com/enterprise/gsa/
`Google Search Engine', 2009b .

Google.
URL

http://www.google.com

Grupo de Estructuras de Datos y Lingstica Computacional.


palabras del espaol', 2006. Accedido: Enero de 2010. URL

`Flexionador y lematizador de

http://www.gedlc.ulpgc.es/investigacion/scogeme02/lematiza.htm http://core.hibernate.org/
`Hibernate - Relational Persistence for Idiomatic Java', 2009a .

Hibernate.
URL

Hibernate.
URL

http://search.hibernate.org/
`HyperSQL Database Engine', 2008.

`Hibernate Search', 2009b .

HyperSQL.
URL

http://hsqldb.org/

JCP. JCP.

`Enterprise JavaBeans 3.0', 2006a .

URL

http://jcp.org/en/jsr/detail?id=220

`JavaTM Data Objects 2.0 - An Extension to the JDO specication', 2006b .

URL

http://www.jcp.org/en/jsr/detail?id=243

Johnson, R.E. et al.


pgs. 2235, 1988.

`Designing Reusable Classes'. Journal of Object-Oriented Programming, tomo 1,

Klas, J.
URL

http://www.scribd.com/doc/19217222/Recuperacion-de-Informacion-sobre-Modelos-de-Dominio

`Recuperacin de Informacin sobre Modelos de Dominio'. 38 JAIIO AST, 2009.

BIBLIOGRAFA

173

Kleinberg, J.M.

`Authoritative Sources in a Hyperlinked Environment', 1999. `Binary codes capable of correcting spurious insertions and deletions of ones'. Prob-

Levenshtein, V.I.

lems of Information Transmission, tomo 1, pgs. 817, 1965.

Lexis Nexis Research.


URL

http://www.lexisnexis.com/research/
`Endo-testing: unit testing with mock objects'. (pgs. 287301), 2001.

`LexisNexis', 2009.

Mackinnon, T. et al. Manning, C. et al.


URL

http://www-csli.stanford.edu/~hinrich/information-retrieval-book.html http://memcached.org/
`Memcached', 2009.

Introduction to Information Retrieval. Cambridge University Press, 2008.

Memcached.
URL

Metaweb Techonologies.
URL

http://www.freebase.com/
`Oracle TopLink', 2008.

`Freebase', 2010.

Oracle.
URL

http://www.oracle.com/technology/products/ias/toplink/index.html http://www.oracle.com/technology/products/berkeley-db/je/index.html http://www.oracle.com/technology/products/oses/index.html


`The PageRank Citation Ranking: Bringing Order to the Web', 1998. `Oracle Secure Enterprise Search', 2009b . `Oracle Berkeley DB Java Edition', 2009a .

Oracle.
URL

Oracle.
URL

Page, L. et al. PCI.


URL

`PCI Security Standards Council 2006', 2006.

https://www.pcisecuritystandards.org/
`Snowball: A language for stemming algorithms'. Published online, 2001. Accessed

Porter, M.F.
URL

11.03.2008, 15.00h.

http://snowball.tartarus.org/texts/introduction.html
`An algorithm for sux stripping'. Program, tomo 14, 3, pgs. 130137, 1980. `WordNet 3.0', 2010.

Porter, M. Princeton.
URL

http://wordnet.princeton.edu/

RAE.

Diccionario de la lengua espaola. Real Academia Espaola, 2006.


`Evolving Frameworks: A Pattern Language for Developing Object-Oriented Frame-

Roberts, D. et al.
works', 1996. URL

http://st-www.cs.illinois.edu/users/droberts/evolve.html
`The Probability Ranking Principle in IR'. Journal of Documentation, tomo 33, pgs.

Robertson, S.E.
294304, 1977.

Robertson, S.E. Rocchio, J.J. Salton, G. et SIGIR.


URL

et al.

`Relevance weighting of search terms'.

Journal of the American Society for

Information Science, tomo 27, pgs. 129146, 1976. The SMART Retrieval SystemExperiments in Automatic Document Processing, (pgs.

313323). Prentice-Hall, Inc., Upper Saddle River, NJ, USA, 1971.

al. `A vector space model for automatic indexing'. Commun. ACM, tomo 18, 11, pgs.

613620, 1975. ISSN 0001-0782. doi:http://doi.acm.org/10.1145/361219.361220. `SIGIR'2006 Workshop on Faceted Search - Call for Participation', 2006.

http://sites.google.com/site/facetedsearch/

SOX.

`Sarbanes-Oxley Act of 2002', 2002.

URL

http://www.gpo.gov/fdsys/pkg/PLAW-107publ204/content-detail.html

174

BIBLIOGRAFA

Spring.
URL

http://static.springframework.org/spring/docs/2.5.x/reference/index.html http://java.sun.com/j2se/1.5.0/docs/guide/serialization/spec/serialTOC.html http://java.sun.com/javase/6/docs/api/java/io/ObjectOutputStream.html http://xstream.codehaus.org/ http://www.yahoo.com


`Yahoo Search Engine', 2009. `XStream Serialization Framework', 2009.

`The Spring Framework 2.5 - Reference Documentation', 2008.

Sun. Sun.

`Java Object Serialization Specication', 2004.

URL

`Java Platform Standard Ed. 6 Documentation', 2008.

URL

XStream.
URL

Yahoo.
URL

Zobel, J. et al.

`Finding approximate matches in large lexicons'. Softw. Pract. Exper., tomo 25, 3, pgs.

331345, 1995. ISSN 0038-0644. doi:http://dx.doi.org/10.1002/spe.4380250307.

Apndice A

Instalacin del Software y el Cdigo Fuente


A.1. Instalacin del Software de Pruebas
Esta tesis est acompaada de un software que permite reproducir los ensayos del captulo 4 as como ejecutar PetClinic, Klink y KStore sobre nuestro sistema de IR. Para ejecutar las pruebas y demostraciones en Windows o Linux se deben seguir los siguientes pasos: 1. Desde el DVD que acompaa este trabajo se debe instalar VirtualBox (se incluye una versin para Windows y otra para Linux, en caso de no ser compatible con su sistema operativo, VirtualBox se puede descargar desde http://www.virtualbox.org/wiki/Downloads). 2. Una vez instalado VirtualBox, se debe copiar y descomprimir el archivo que contiene la imagen de la mquina virtual (vm-tesis.rar) en una carpeta cualquiera. Esto requiere aproximadamente 6 GB de espacio libre en disco. 3. Iniciar VirtualBox y agregar la imagen de disco siguiendo la secuencia:

a ) elegir el men File b ) dentro del men, seleccionar la primera opcin: Virtual Media Manager c ) en el dilogo que se abre, seleccionar la tableta Hard Disks d ) en la parte superior del dilogo, presionar el botn Add e ) elegir la imagen de disco descomprimida en el paso 2 (archivo con extensin .vdi dentro de la
subcarpeta HardDisks) y presionar el botn Ok. 4. Crear una mquina virtual siguiendo la secuencia:

a ) en la pantalla inicial de VirtualBox presionamos el botn superior New b ) ignorar la primera pantalla y presionar Next c ) ingresamos el nombre para la VM, elegimos el SO Linux, la versin Ubuntu y presionamos Next d ) en la pantalla de seleccin de memoria, elegir 512 MB RAM y presionar Next e ) elegir la opcin Use existing hard disk, seleccionar el disco agregado en el paso 3 y presionar
Next

f ) ignorar esta ltima pantalla y presionar Finish


5. Por ltimo, en la pantalla principal iniciamos la mquina virtual presionando el botn Start . 6. Al iniciar la VM, Ubuntu le pedir el password de inicio de sesin. Tanto el nombre de usuario como la contrasea se corresponden con la palabra tesis. Una vez que se inici la sesin, abrir el archivo de instrucciones situado en el escritorio y seguir los pasos indicados.

175

176

APNDICE A.

INSTALACIN DEL SOFTWARE Y EL CDIGO FUENTE

A.2.

Cdigo Fuente y Sitio Web del Proyecto

El cdigo fuente del framework puede descargarse libremente de SourceForge y GitHub:

http://modelsearch.git.sourceforge.net/git/gitweb-index.cgi http://github.com/jklas/ObjectSearch

Actualmente tambin existe una pgina web desde donde se puede seguir el proyecto:

https://sites.google.com/site/objectsearchframework/

ndice alfabtico
ndice invertido, 22 algoritmo de Rocchio, vase relevance feedback Apache Lucene, 4 aplicaciones empresariales, 44 bsqueda facetada, 29 bsquedas literales, 28 bases de datos orientadas a objetos, 64 boolean model, vase modelo booleano caches, 34 campos, 36 cobertura de cdigo, 129 desajustes de impedancia, 59 de recuperacin, 68 de sincronizacin, 68 estructural, 68 diccionario, 22 distancia de Levenshtein, vase edit distance edit distance, 29 enterprise applications, vase aplicaciones empresariales F-measure, 11 faceted search, vase bsqueda facetada ltrado, 99, 106, 126, 165 hidratacin, 34 hipnimo, 32 hipernimo, 32 HITS, 40 holnimo, 32 corpus, 8 documentos, 8 lxico, 9 modelo booleano, 13 modelo probabilstico, 19 modelo vectorial, 14 modelos, 12 precision, vase precision recall, vase Recall inversin del control, 50 inyeccin de dependencias, 50 Klink, 129 KStore, 129 lxico, 22 lematizacin, 31 mapeos avanzados, 103 mernimo, 32 modelos de dominio, 2, 46 ordenamiento, 106 overstemming, 31 PageRank, 38 parnimo, 32 patrones de arquitectura, 45 de diseo, 45 persistencia de modelos de dominio, 53 Ad-Hoc, 56 Administrada, 55 Binaria, 55 Manual, 54 Object Oriented DBMS, vase Bases de Datos Orientadas a Objetos impedance mismatch, vase desajuste de impedancia indexacin, 9 algoritmos distribuidos, 26 concurrente y distribuida, 96 dinmica, 27 oine, 95 online, 94 por Barrido Simple en Memoria, 24 por Ordenamiento en Bloques, 24 semi-online, 94 information retrieval, 1 accuracy, 11 ORM, 58 bsico, 59 completo, 63 Hibernate, 64 JDO, 64 JPA, 63 XML, 58 PetClinic, 129 plugin, 98 portabilidad, 129 posting lists, 22 precision, 9 probabilistic model, vase modelo probabilstico 177

hubs, vase HITS

178

NDICE ALFABTICO

pruebas comparativas cualitativas, 130 comparativas de rendimiento, 130 de calidad, 129 query log mining, vase relevance feedback range queries, 29 ranking, 11 recall, 9 reindexacin, 97 relevance feedback, 41 algoritmo de Rocchio, 42 explcito, 42 implcito, 42 query log mining, 42 similitud, 99 booleana, 13 probabilstica, 20 vectorial, 15 sinnimo, 32 snowball, 32 stemming, 31 tesauro, 29, 33 TF-IDF, 17 vector space model, vase modelo vectorial zonas, 36

Potrebbero piacerti anche