Escuelita de Scala - Parte 5 - Typeahead con Bootstrap
Escuelita de Scala
- Parte 1 - Instalación
- Parte 2 - Configuración de Play Framework
- Parte 3 - Play MVC
- Parte 3a - Vistas
- Parte 4 - Modelos y servicios
- Parte 4a - ElasticSearch
- Parte 4b - MongoDB y Casbah
Para implementar Typeahead o Autocomplete, usamos el componente de Bootstrap Typeahead. Para integrarlo al servicio que genera la secuencia de datos sin embargo requiere de varias mejoras sustanciales. Se requiere:
- Buscar con autocomplete datos en /typeahead/{consulta}
- Seleccionar un valor
- Buscar el valor en ElasticSearch y retornar la ficha a MongoDB
- Presentar el documento en Bootstrap.
Vamos a revisar los primeros dos pasos
Escuelita de Scala - Parte 4b - MongoDB y Casbah
Escuelita de Scala
- Parte 1 - Instalación
- Parte 2 - Configuración de Play Framework
- Parte 3 - Play MVC
- Parte 3a - Vistas
- Parte 4 - Modelos y servicios
- Parte 4a - ElasticSearch
MongoDB es una base de datos NoSql, sin esquema (schemaless), que permite escritura rápida de datos, lectura por medios de comandos JavaScript y los datos son almacenados en BSON o Json binario. Los documentos son enviados al cliente en Json pero tambien tiene un API para cada plataforma, y para Scala, el componente Casbah permite interactuar de una forma orientado a Scala para manejar los datos de MongoDB. Casbah tiene lo esencial para leer, escribir y administrar los datos.
Instalación
MongoDB, similar a ElasticSearch, es un ejecutable el cual escucha en un puerto especifico, en este caso el servicio de mongo es el 27017. Para instancias de pruebas y desarrollo podemos usar esto por predeterminado. Recomendamos crear un batch file para iniciar mongo y el cliente de mongo.
run.bat
bin\mongod —dbpath “D:\mongodb\data\db”
run client.bat
bin\mongo
Como vamos a usar el snapshot de datos del Registro Público, se recomienda bajar los datos y copiar a la carpeta data.
En la implementación del buscador de sociedades usamos MongoDb para desplegar el documento de sociedad o ficha. Cada ficha contiene los directores, subscriptores, dignatarios e información con respecto a las acciones de la sociedad anónima como también notarias y fechas de registros.
Buscamos por ficha en mongodb, usando MongoDb(“ficha”-> ficha). Nos aseguramos también de indexar el campo ficha con ensureIndex, ya que de no estar MongoDb demora tiempo en retornar el valor. El registro encontrado se serializa a JSON y si no se encuentra se retorna un JSON vacío.
Indexamiento previo con RegPubRobot
El indexamiento usando RegPubRobot, creamos el modelo usando un Map (muy similar al momento de crear un modelo de JsValue). En RegPubParser.parseCompany usamos JSoup para scrap los datos HTML, convertimos el mismo en texto y creamos la estructura para guardar en MongoDB. Tenemos varios clases de extensiones o “Pimp My Library” como toTableCellsSeq, lo esencial es que retornamos un objeto Store, este llega a un resultado den un actor Akka y se envía a RegPubStorage.saveOrUpdate. Aqui validamos que la ficha (llave única) exista antes de almacenar. Al final se llama a ElasticSearch (probablemente existe una mejor forma mas loosely coupled, pero por el momento esta ligado al código de guardar a MongoDB) para indexar los datos usados en la búsqueda de la aplicación.
Escuelita de Scala - Parte 4a - ElasticSearch
Escuelita de Scala
- Parte 1 - Instalación
- Parte 2 - Configuración de Play Framework
- Parte 3 - Play MVC
- Parte 3a - Vistas
- Parte 4 - Modelos y servicios
ElasticSearch es un componente similar a Apache Solr pero más compacto y sin esquema (schemaless), lo cual permite indexar y buscar en segundos. El API de ElasticSearch es un poco confuso, pero ya cuando se comprende como se asemeja al motor de ElasticSearch Lucene, codificar aplicaciones de busqueda es realmente sencillo y efectivo a la hora de implementar con interfaz de JavaScript / JSON.
Otro aspecto adicional de ElasticSearch es que es distribuido, asi que es posible tener varios nodos. En nuestro escenario, ElasticSearch funciona solo para buscar los datos, pero en teoria podria reemplazar MongoDB por completo.
Instalación
Descargar de ElasticSearch y extraer el contenido a una carpeta. Dentro de bin ejecutar el batch file elasticsearch.bat. Si no funciona revisen su JAVA_HOME, debe estar configurado adecuadamente. Adicionalmente puedes instalar el snapshot de datos en la carpeta data (reemplazar usando copy y paste).
ElasticSearch escucha en el puerto 9200 locamente. Para probar que los datos esten configurado correctamente, ejecute el siguiente URL. Debe retornar 422 registros.
http://localhost:9200/regpub/sa/_search?q=_all:martinelli&pretty=true
Typeahead (autocomplete)
El primer servicio consta de una busqueda de empresas o sociedades, estas deben cargarse dinamicamente en un textbox y al clickearse deben retornar la empresa. Bootstrap ofrece un control de Typeahead (busqueda adelantada seria la traducción), el cual utiliza una fuente de datos un array de JavaScript.
Lo primero que realizamos es implementar typeahead en SearchService. El cliente de ElasticSearch lo usamos igual que una conexión de base de datos, debemos abrir y cerrar la conexión para evitar problemas con el servicio (en el robot no la cerramos ya que solo indexamos de un modo masivo).
Para crear consultas, QueryBuilders contiene los diferentes tipos de consultas. El más sencillo y fácil de implementar es QueryBuilders.queryString. En este configuramos algoritmos y propiedades a usar. autoGeneratePhraseQueries = true tokeniza una sentencia en sus palabras individuales. En este mismo objeto asigamos el peso o “boost” a cada campo que se quiere analizar. Tambien podemos configurar el operador para consultas entre palabras (por ejemplo Juan AND Carlos o Juan OR Carlos).
Con el builder completo, preparamos la consulta con client.prepareSearch, asignamos el nombre del indice a buscar, el tipo de consulta, el query builder en setQuery y los campos a retornar.
Finalmente, solo retornamos los primeros 10 resultados, los cuales se convierten a JSON y se navega para solo retornar el contenido de hits.
En RegPubServices preparamos un json que retorne un array de item, esto después lo transformamos en un array puro usando Underscore y Backbone. Seguramente existe una forma más rápida, pero queriamos probar el uso de Underscore a nivel de cliente. Más adelante revisamos como el código de cliente implementa correctamente el Typeahead.
Escuelita de Scala - Parte 4 - Modelos y servicios
Escuelita de Scala
- Parte 1 - Instalación
- Parte 2 - Configuración de Play Framework
- Parte 3 - Play MVC
- Parte 3a - Vistas
El modelo de la aplicación utiliza un modelo de documento, usando datos del Registro Público de Panamá. Para obtener un snapshot de los datos en MongoDb y ElasticSearch, es necesario ejecutar el robot RegPubRobot.
Si no quieres esperar, baja los datos para ElasticSearch y MongoDB y agregalo a tu instancia local.
Al tener un snapshot con registros, podemos iniciar MongoDb y ElasticSearch y crear la integración de los datos en el modelo usando Scala.
Para tener separación de servicios, se crea un trait abstracto, implementado en otro trait y el cual sera usado por una clase RegPubServices. Esta clase adicionalmene se le crea un factory con apply. El trait abstracto ademas queremos que sus métodos sean protected.
Aqui vemos un ejemplo de SearchUtil y SearchService.
RegPubServices extiende DataModelService y SearchService y simplemente se encarga de filtrar más a detalle los datos JSON o crear lógica de negocios.
Escuelita de Scala - Parte 3a - Play MVC Views
Escuelita de Scala
Los views en Play Framework son similar a los usados por ASP.NET Razor.
Para ejecutar la vista en el controlador, se llama directamente a la vista.
En views/index.scala.html al inicio anotamos los argumentos que son aceptados por la vista. En esencia, la vista funciona como una función de Scala.
@(message: String)
<h1>@message</h1>
Tambien existen otros comandos y similar a ASP.NET Razor, usamos la @ para denotar cualquier código ejecutable (ver Play Templates).
En la aplicación, usamos Twitter Bootstrap, y nuestra plantilla maestra (main.scala.html) y plantilla de index (index.scala.html), separamos los contenedores de contenido para que adapten la barra de navegación y la lateral de Bootstrap.
Main.scala.html
El HTML contiene un layout fluido similar a los disponibles por Bootstrap. Los CSS y JavaScript usan @routes.Assets.at para cargar los recursos según la definición de las rutas.
Como main es el template maestro, y queremos usar Bootstrap, hay 3 partes habilitadas en Main, las cuales son configuradas por cada implementación.
Barra de navegación
@navbar { @navbarContext }
Definen la navegación de la página, donde @navbar es un tag y @navbarContext es el HTML definido por cada página. Esta implementación podria ser más sencilla a nivel de client side script con Handlebars y Backbone, pero al definir en el server el contenido de la barra de navegación se controla mejor en caso tal se integre con un servidor de CMS como Sitecore.
@sidebar y @content definen los placeholders para la barra lateral y el contenido. Simplemente, cada página implementa su contenido especifico.
Index.scala.html
En Index.scala.html, las partes de @navbarContext, @sidebar y @content son implementadas. Para acceder al template maestro, ejecutamos main como una función, asignamos los valores y el ultimo, @content, por medio de un closure agregamos los valores HTML adicionales. Más adelante se implementa el uso de Backbone y Handlebars, y con un patrón single page, implementamos las diferentes vistas de la aplicación.
Escuelita de Scala - Parte 3 - Play MVC
Escuelita de Scala
Estructura de un proyecto Play Framework
La estructura de un proyecto Play contiene varios directorios

app
Contiene el MVC a nivel de Scala. En nuestro ejemplo, services es un namespace adicional, en la practica estaria separado en otro proyecto usando Akka.
Global.scala
Similar a Global.asax de ASP.NET.
conf
Contiene application.conf con los parámetros usados por la aplicación. Mientras que routes detalla las rutas disponibles por la aplicación siguiendo el modelo REST.
lib (no aplica para Eclipse)
Dependencias que no estan creadas en build.scala son agregadas en lib, esta se agregaran al classpath de la aplicación.
project
Build.scala contiene las dependencias del proyecto.
plugins.sbt contiene los plugins, en este caso Play y SbtEclipse.
public
Todos los recursos de clientes, como HTML, Imágenes, JavaScript y CSS se almacenan en este directorio.
Rutas (Routes)
Como vemos en este Gist (pedazo de código hosteado en Github), las rutas siguen un patrón REST que es ideal para aplicaciones MVC e igual como Ruby on Rails y ASP.NET MVC.
Controladores (Controllers)
Cada ruta ejecuta el controlador determinado según el archivo routes. Para llamar al método search en el controlador Application se ejecuta un HTTP GET /search/hola. Se busca los datos de hola en el modelo y retornamos un resultado con HTTP código 200 OK. El controlador tambien retorna varias variaciones de search en formato JSON, que seran usados por el cliente para desplegar los datos adecuadamente.
Modelo (Models)
En nuestra aplicación tenemos los datos en base de datos de indexamiento ElasticSearch y en MongoDB, que es una base de datos key-value NoSql. Idealmente en una arquitectura más detallada, se crea un proyecto separado que solo contenga los servicios, y usando un contenedor como Akka para tener más tolerancia a los fallos y rendimiento.
En la siguiente parte de la Escuelita de Scala veremos más a detalle las vistas, estas usan un template engine inspirado en ASP.NET llamado Razor, pero orientado a Scala.
Escuelita de Scala - Parte 2 - Configurando Play Framework
Escuelita de Scala
Configurando Play Framework
Crear un proyecto Play es realmente sencillo, pero algo diferente a crear una aplicación en por ejemplo Eclipse o Microsoft Visual Studio .NET.
Play Framework y al igual que SBT estan orientados a consolas de comando. De este modo, para crear un proyecto Play se requiere iniciar bajando las plantillas. Esto es algo nuevo introducido por Typesafe Stack. Usan giter8, el cual baja las plantillas para cada proyecto desde Github.
Para crear la plantilla Play dentro de un folder (por ejemplo dentro del folder de workspace de Eclipse):
g8 typesafehub/play-scala
verbatim: usar valores predeterminados
application_secret: usar valores predeterminados
application_name: nombre del proyecto o folder
play_version: usar valores predeterminados
Ahora entramos al proyecto por medio de consola, ejecutamos SBT, creamos el proyecto para Eclipse y ejecutamos por primera vez.
cd nombreDelProyecto
sbt
Sbt inicia cargando de la web cualquier dependencia requerida por el proyecto
eclipsify (o eclipse)
Eclipsify plugin configura el proyecto para uso de Eclipse. Se ejecuta cada vez que se actualiza el build con dependencias nuevas.
play
run

Iniciamos play y ejecutamos run que nos permite ver la aplicación desde localhost:9000
Escuelita de Scala - Parte 1 - Instalación
Introducción
En la primera Escuelita de Scala, el lenguage que ejecuta encima del Java Virtual Machine (JVM) y que mezcla lo mejor de lo funcional y orientación a objetos, iniciamos con lo esencial, como instalar las herramientas para iniciar el desarrollo de Scala.
Nota: Asegurese de tener Oracle JDK versión 6 (se usara para el plugin de Eclipse) y 7 configurar correctamente JAVA_HOME, por ejemplo C:\program files\Oracle\java\jdk_6.
Instalación Scala y Typesafe Stack
Para instalar en Windows, bajar el instalador en code.google.com. Complete la instalación y con esto debe tener el PATH de Scala correctamente configurado. Para comprobar que Scala este instalado, abra una consola de comando y escriba scala (puede requerir reiniciar la computadora).
Al tener Scala y Java correctamente en el sistema, ahora instalamos el stack de Typesafe. Typesafe es la empresa que se encarga de mantener Scala y sus componentes: Akka, Play y SBT.
La Typesafe Stack versión 2 incluye solamente SBT y algunos templates. Más adelante se explica como utilizar esto a su potencial completo. En este caso SBT es el sistema de build y creación de proyectos.
Bajar Typesafe Stack desde http://typesafe.com/stack/download. Al finalizar la instalación asegurese que este bien configurado SBT.
$ sbt sbt-version
Al tener SBT funcionado correctamente, completamos la primera fase de la Escuelita de Scala.
Resumen
- Instalación de Oracle JDK 6 y 7 con JAVA_HOME apuntado a JDK7.
- Instalación de Scala para uso en consola.
- Instalación de Typesafe Stack 2 que configura SBT y giter8.
Admios Team 2011, un álbum en Flickr.





