Banot.net
nLite
Enviado por manolopm el Vie, 09/04/2009 - 08:40.A raíz de mi post sobre Wpkg, un compañero me recomendo que probase nLite (gracias Carlos).
Para quien no sepa de que va la historia, nLite es una herramienta que te permite, a golpe de ratón, personalizar tu disco de instalación de Windows. De está manera podemos preparar instalaciones desatendidas, con los service packs y las actualizaciones que queramos.
El problema es que hay que tener las actualizaciones descargadas para poderlas integrar en el cd, y por si alguien no lo ha notado ya, despues del Service Pack 3 hay como unas 50 actualizaciones. Además Microsoft, siguiendo su "politica de estandars", tiene como 5 de esas actualizaciones en un formato diferente y por lo tanto no son integrables a golpe de ratón.
Para este tipo de actualizaciones hay que preparar lo que la gente de nLite llama un Addon. Un Addon es simplemente un fichero comprimido que contiene, además de los ficheros de la actualización, un fichero ini en el que se describe que es lo que debe de hacer para instalar esa actualización. Actualmente estoy peleando con este tema, pero prometo que en cuanto tenga los ficheros listos para el nLite lo colgaré por aquí para que todo el mundo se pueda hacer su CD de instalación con sp3+actualizaciones basandose en su cd original de Windows.
Wpkg
Enviado por manolopm el Mar, 08/25/2009 - 10:09.Quién mas y quien menos todos hemos sufrido una instalación de Windows. El problema viene en que no es solo instalar el windows, también es el instalame el firefox, el plugin de flash, el acrobat reader, el winamp y si me apuras hasta el programa especifico de hace 50 años.
Para automatizar todo esto y no tener que currar una y otra vez con los 1500 clicks en pantalla aparece Wpkg. La idea es bastante simple, ya que windows trae un interprete de JScript (o sea lo que microsoft entiende por JavaScript), hagamos uso de él. La gente de wpkg se han currado un script que permite arrancar los instaladores de las aplicaciones remotamente. Además permite definir diferentes perfiles según las máquinas, con ello conseguimos que en una instalación multitudinaria de máquinas, sea tan fácil (o casi) como llegar enchufar la máquina a la red y a correr.
En la parte del servidor todo muy simple, una máquina con un recurso compartido (ya sea samba o active directory) con los scripts de wpkg y los instaladores de los programas que queremos meter.
En la parte del cliente más fácil aún.
- Opción A: Nada, simplemente arrancando el script con cscsript desde una consola de windows la magia se hace sola.
- Opción B: Instalar el cliente de Wpkg. Está opción nos permite automatizar el proceso de sincronización y arrancarlo a determinada hora o ante ciertos eventos (apagado, encendido...).
Además una opción bastante curiosa, wpkg también se puede meter en un cdrom. Si a esto le sumamos un autorun simpático, conseguimos tener un cd que nada más meterlo en el ordenador en cuestión instale todo el software que le hemos programado sin que el usuario tenga que hacer absolutamente nada.
Como no todo podía ser bonito hay una parte "dura" en todo este proceso, preparar los scripts para cada instalador. No es que sea especialmente complicado, de hecho muchos de ellos con 5 lineas están más que listos para funcionar. Pero el problema está en que en windows, por norma general, no hay dos programas que se instalen igual, así que hay que estar trasteando con los instaladores para ver que parámetros hay que pasarle para instalarlo desatendidamente. Y aunque con los instaladores en formato MSI se solventa en gran parte está problemática, siempre hay que andar que tocando algo para que el script cuadre con nuestras necesidades. Además siempre podemos utilizar como base la lista de scripts que se encuentran en la página de wpkg. Pero aviso a navegantes, al menos yo he tenido que tocar todos los scripts que he cogido de ahí por una u otra razón.
Calculus: La arquitectura
Enviado por manolopm el Mar, 08/04/2009 - 09:47.Como comentaba en el post anterior, en este artículo voy a hablar sobre la solución que estamos adoptando y porque hemos descartado algunas de las alternativas.
El modelo de datos
Lo primero que consideramos fue como modelar la realidad que tenemos. Pensamos, inicialmente, en un modelo como el que se muestra a continuación:
Inicialmente nos centramos en modelar los cálculos. Los cálculos deberían tener una magnitud a medir, las unidades en las que se mide esta magnitud, y el valor calculado. Así mismo, podría tener uno o varios valores de entrada o condiciones iniciales. Y además debería de tener un origen para identificar de donde proviene ese calculo.
Lo siguiente en ser modelado fueron los valores de entrada o condiciones iniciales, ya que queríamos que el sistema fuera bastante dinámico pensamos en condiciones iniciales como una magnitud, con la unidad correspondiente y su valor. Esto nos permitiría meter valores de entrada bastante complejos, pero tendríamos que crear unidades ficticias para aquellos valores de entrada que no tengan unidades de medida, como por ejemplo la configuración electrónica.
Teniendo ya los cálculos y los valores de entrada, lo siguiente a modelar fueron las unidades. Cada unidad podía tener un símbolo y un valor que contendrá una descripción más detallada de la unidad.
Finalmente modelamos las magnitudes que contendrán un valor con una descripción de la magnitud, y las fuentes con una descripción del origen como valor.
Implementación
Para implementar el modelo descrito decidimos usar CouchDB, como ya hemos comentado anteriormente, ya que nos permite trasladar fácilmente el modelo dinámico que hemos explicado.
Pensamos en usar vistas para generar las posibles búsquedas sobre los diferentes parámetros, pero nos dimos cuenta de que la forma de filtrar y realizar búsquedas se nos quedaba muy corta para nuestras necesidades. Así que finalmente optamos por usar CouchDB-Lucene para generar indices de los documentos y poder realizar búsquedas más complejas.
Luego pensamos en donde colocar la aplicación. Primero pensamos que sería una idea genial aprovechar las ventajas de CouchDB e intentar que la aplicación migrase como mismo lo hacen los datos. Pero esta solución no nos era válida, ya que queríamos ofrecer una interfaz REST y al almacenar la aplicación como un documento en CouchDB siempre tendríamos que hacer un GET. La alternativa era tener un servidor web que se encargase de recibir la petición REST y generase las llamadas a CouchDB. Con esto obtendríamos varias ventajas de una sola vez, tendríamos la interfaz REST, podríamos definir un API mucho más cercano a nuestro problema en vez de atacar a CouchDB directamente, y además tendríamos autenticación web. Además podríamos programar la aplicación en el lenguaje que quisiéramos y no nos veríamos atados a JavaScript. Así que finalmente optamos por esta opción, programando la aplicación en Ruby con Sinatra (aún en desarrollo), pero no hemos abandonado del todo la idea de que la aplicación migre.
En los próximos post hablaré de todo el desarrollo en concreto, como generamos los indices con CouchDB-Lucene, como usamos Sinatra y demás. Prometo que serán mucho más técnicos.
Calculus: The architecture
Enviado por manolopm el Mar, 08/04/2009 - 09:07.As I told in the last post, in this article I will talk about the solution that we are using and why we take apart some alternatives.
The data model
The first thing we treat was how to model the reality that we have. We think, initially, in a model like the next one:
The first thing that we try to model was the calculations. The calculations shoudl have a magnitude to meassure, the units of this magnitude and the calculated value. We can also have one or many input values or initial conditions. We also have a source to identify where the calculation was generated.
The next thing that we try to reprresent was the input values or initial conditions, we wan't a really dinamyc system so we model the initial conditions as a magnitude, associated to a unit and a value. It let us use complex input values, but we have to create false units for some input values that don't have units, like electronic configuration.
The next thing modelled were the units. Every unit would have a symbol, and a value that holds a detailled description of the unit.
Finally we model the magnitudes that will have a value with the description of the magnitude, and the sources with a description of the origin as value.
Implementation
To implement the model described we decided to use CouchDB, as we told before, because it let to translate easilly the dinamic model that we explain before.
We thought use views to generate all the searches over the differents parameters, but we reallized that the way that views use to filter and make searchs was too weak for our needs. So finally we choose to use CouchDB-Lucene to generate the index of the documents. That let us make more complex searchs.
The next problem was where to put the application. Our first idea was use CouchDB advantages and try to put the application inside CouchDB, so our application will migrate throught our network as the data does. But That solution was not good, because we wan't to have a REST interface and if we put the application like a document in CouchDB we have to call every time with a GET http command. The alternative way was have a web server that receive the REST petition and generate CouchDB petitions. With this solution we will have a REST interface, we can define a nearest to our problem API, and we get HTTP authentification too. We can also make our application in the language that we want and we will not tied to use JavaScript. Finally we dediced to use this option, making the application in Ruby with Sinatra (still in developtment), but we don't forget the idea to make the application travels arround the net.
In the next post I will talk about the details of the development, how we make the index in CouchDB-Lucene, how we use Sinatra and so on. I promise that the next post will be more technicals than the previous one.
Calculus: The problem
Enviado por manolopm el Mar, 07/28/2009 - 09:22.We have been working in a software using CouchDB and now it's time to tell something about it.
The first thing will be an explanation of the problem, and in the next posts we will talk about the solution that we're using y why we choose it.
The problem
The physics deparment of the University of Las Palmas de Gran Canaria (from now ULPGC) was making a lot of their calculations using data from other physics departments arround the world. But there is no place to hold this data, not their own results from their calculations, neither the data from others departments in an standard way. Futhermore, the calculations made by a department can use previous calculated results, experimental results or a mix of both.
As well, they told us that physics congress were used, among other things, to share results from the same calculation and to check that their experimental or calculated results were correct.
So we have to seek a solution and we propose a system which could have saved all the calculus in a distributed and synchronized way. All the machines that decided to use this net could share their calculations and receive automagically the calculations from others. The system also should have a REST interface to talk with the database. The saved calculations should have differents initials conditions, or input data, or even differents approximations to a same calculation.
This system should let, save any kind of calculation, not taking care of the calculation itself, the number of conditions or the magnitude that it's using.
With all these preconditions, we realized that we need a quite dinamic system. It could be done with a relational database, but that implies a complex and harder model, and a lot of work to make the synchronization with the other nodes.
So, our solution was CouchDB.
In the next post I will talk about the architecture that we are using by the moment.
Calculus: El problema
Enviado por manolopm el Jue, 07/23/2009 - 13:52.Hace tiempo que estamos trabajando en un software sobre CouchDB y va siendo hora de que contemos algo sobre él.
Lo primero va a ser explicar el problema, y en los posts siguientes hablaremos de la solución que estamos adoptando y el porqué decidimos seguir ese camino.
El problema
El departamento de física de la Universidad de Las Palmas de Gran Canaria (en adelante ULPGC), nos comentó que ellos realizaban muchos de sus cálculos apoyándose en resultados de otros departamentos de física. Pero que no existía ningún sitio donde residieran, ni los resultados en los que ellos se apoyaban, ni los que ellos mismos generaban de forma unificada. Para complicar aún más la cosa, los cálculos realizados por un departamento se pueden apoyar en resultados experimentales, en resultados calculados matemáticamente o en una combinación de ambos.
Además nos contaban que los congresos de física los utilizan, entre otras cosas, para comparar resultados de los mismos experimentos y comprobar que los software que están desarrollando o los resultados experimentales que han obtenido son correctos.
Así que había que buscar una solución y propusimos un sistema que permita tener almacenados todos estos cálculos de forma distribuida y sincronizada. De manera que todas las máquinas que decidan unirse a está red puedan aportar sus cáculos y recibir los de los demás automágicamente. Ademas debería tener una interfaz REST para poder interactuar con la base de datos. Los calculos deberían permitir diferentes condiciones iniciales, o datos de entrada, o incluso diferentes aproximaciones para un mismo cálculo.
Este sistema permitiría, teóricamente, almacenar resultados de cualquier tipo de cálculo, sin importar el cálculo en si mismo, el número de condiciones o la magnitud que se esté midiendo.
Con todas estas precondiciones, nos dimos cuenta que necesitabamos un sistema bastante dinámico. Se podría hacer con una base de datos clásica, pero implicaría un modelo mucho mas forzado y complejo, y mucho más trabajo a la hora de intercomunicar las bases de datos para sincronizarlas.
Así que la decisión fué CouchDB.
En el siguiente post contaré un poco más de la arquitectura que hemos adoptado por el momento.
CouchDB: A brief introduction (Part IV)
Enviado por manolopm el Mar, 07/21/2009 - 13:54.Using CouchDB-Lucene
CouchDB-Lucene is an interface between CouchDB and Lucene, a document indexer. Using this interface we can make really complex queries to get the documents.
Configuring CouchDB-Lucene
The first thing to do to configure CouchDB-Lucene, is configure CouchDB to run the CouchDB-Lucene proccess every time that CouchDB is launched, and every time that a document is updated. We also want that using an URL, http://url_del_servidor:5984/base_de_datos/_fti, the CouchDB-Lucene process will be lauched too. To make this we need to edit the CouchDB configuration file, local.ini, adding this lines:
[external]
fti = /usr/bin/java -jar /path-couchdb-lucene/couchdb-lucene-0.3-SNAPSHOT-jar-with-dependencies.jar -search[update_notification]
indexer = /usr/bin/java -jar /path-couchdb-lucene/couchdb-lucene-0.3-SNAPSHOT-jar-with-dependencies.jar -index[httpd_db_handlers]
_fti = {couch_httpd_external, handle_external_req, <<"fti">>}
We alse need to adjust the timeout parameter, because between the time used to launch the Java Virtual Machine and the time used to make the search we can have a really big stop. The next line will give us a timeout of 6 seconds:
[couchdb]
os_process_timeout = 60000
With all of this we have CouchDB-Lucene configured, now it's time to create the design documents to configure the indexation process. We must take into account that the proccess that we have just followed can be used to launch any other proccess when a document is updated in CouchDB.
Creating the indexation documents
In order to use CouchDB-Lucene, we must create, at least, one design document that let us especify the fields and how we will index our documents. This document must have a field called fulltext, which will have an array called like our index. Inside this array we will have another array to indicate the parameters to our index, and an entry, called index, that holds the function to indicate the fields that we wan't to include in our index. This function will be executed once per document added, edited or erased. With an example is clear:
{
"_id":"_design/lucene",
"fulltext": {
"by_everything": {
"defaults": {
"store":"yes"
},
"index":"function(doc){
var ret=new Document();
function idx(previous,obj) {
if (previous!='') previous+='.';
for (var key in obj){
switch (typeof obj[key]){
case 'object':
idx(previous+key, obj[key]);
break;
case 'function':
break;
default:
ret.add(obj[key],{'field':previous+key});break;}}};
idx('',doc);
return ret;
}"
}
}
}
As we can see, we have change the default value of the property store, because if we don't put it to true the index will be only in memory and will not be saved to disk.
We can also see the code of the index function. This function should return a Document object with the fields that we wan't to add to the index. To add a field to the index we should use the add method, using as first parameter the value that we wan't to index and as second parameter an array with the options. This second parameter is optional but we will use it to select the name of the field.
In the example function we will index all the fields, so if the field is an array we will save it using this structure "array.field: value", this will be really usefull to make advanced searchs.
Making advanced searchs
To make searchs using CouchDB-Lucene we just need to access to the document that we previouslly maded. And we use the URL parameters as parameters to the search that we wan't to make. For example:
http://localhost:5984/database/_fti/lucene/by_everything/?q=Configuration.Value:[3 TO 9] AND Element.Value:Fe&sort=\Score&include_docs=true
This url will search every document that have a Configuration array with a Value property between 3 and 9, and also have an Element array with a Value property with the "Fe" value (q=Configuration.Value:[3 TO 9] AND Element.Value:Fe). We have another two parameters, sort=\Score, that will sort all the results by the Score property from back to front and include_docs, that will give us all the document body and not only the identification field. To sort from front to back we have to remove the slash ( \ ) or change it by the other slash ( / ).
Next ...
This is the last article about CouchDB itself. There are some things to be explained, like how to change the format of the views, but the API is changing right now so it's better to wait for an stable version of this API. The following articles related with CouchDB will talk about the project that we are making with CouchDB. The interesting part begins.
CouchDB: Una pequeña introducción (Parte IV)
Enviado por manolopm el Mar, 07/21/2009 - 12:28.Usando CouchDB-Lucene
CouchDB-Lucene es una interfaz entre CouchDB y Lucene, un indexador de documentos. Gracias a esta interfaz podremos hacer consultas bastante complejas.
Configurando CouchDB-Lucene
Lo primero que debemos hacer para configurar CouchDB-Lucene, es informar a CouchDB que queremos que lance el proceso adecuado tanto cuando se arranca CouchDB como cuando se actualiza un documento. Además queremos que ante determinada URL, http://url_del_servidor:5984/base_de_datos/_fti, también se lance el proceso de CouchDB-Lucene. Para ello, editaremos el fichero de configuración de CouchDB, local.ini, y añadiremos las siguientes líneas.
[external]
fti = /usr/bin/java -jar /path-couchdb-lucene/couchdb-lucene-0.3-SNAPSHOT-jar-with-dependencies.jar -search[update_notification]
indexer = /usr/bin/java -jar /path-couchdb-lucene/couchdb-lucene-0.3-SNAPSHOT-jar-with-dependencies.jar -index[httpd_db_handlers]
_fti = {couch_httpd_external, handle_external_req, <<"fti">>}
Además de estas líneas hemos de aumentar el tiempo de espera, ya que entre arrancar la máquina virtual de Java y hacer la busqueda podemos tener un parón importante. Así que también añadiremos lo siguiente para establecer un timeout de 6 segundos:
[couchdb]
os_process_timeout = 60000
Con esto ya tendremos configurado CouchDB-Lucene, ahora habrá que crear los documentos apropiados para configurar la indexación. Hay que tener en cuenta que el proceso que acabamos de seguir para configurar CouchDB-Lucene se puede utilizar para lanzar cualquier otro proceso cuando se produzca una consulta y/o una actualización en CouchDB.
Estableciendo los documentos de indexación
Para poder utilizar CouchDB-Lucene, debemos crear, al menos, un documento de diseño que nos permita especificar que campos y como queremos indexar nuestros documentos. Este documento tiene que tener un campo llamado fulltext, que contendrá un vector con el nombre de nuestro indice. Dentro de este vector tendremos un vector para especificar los parámetros a nuestro indice, y una entrada, index , donde estará la función para indicar que campos indexar. Está función se ejecutará una vez por cada documento que añadamos, mofiquemos o eliminemos. Es más claro verlo con un ejemplo:
{
"_id":"_design/lucene",
"fulltext": {
"by_everything": {
"defaults": {
"store":"yes"
},
"index":"function(doc){
var ret=new Document();
function idx(previous,obj) {
if (previous!='') previous+='.';
for (var key in obj){
switch (typeof obj[key]){
case 'object':
idx(previous+key, obj[key]);
break;
case 'function':
break;
default:
ret.add(obj[key],{'field':previous+key});break;}}};
idx('',doc);
return ret;
}"
}
}
}
Como podemos observar, hemos establecido un valor por defecto a la propiedad store, ya que si no la ponemos a true nuestros indices serán temporales en lugar de almacenarse en disco.
Además podemos ver el código de la función index que comentabamos antes. Esta función debe devolver un objeto de tipo Document al que se le han añadido los campos que queremos indexar . Para añadir un campo a index hemos de hacer uso del método add , pasandole como primer parámetro el valor que queremos indexar y como segundo parámetro un array con las opciones. El segundo parámetro es opcional pero lo vamos a utilizar para personalizar el nombre del campo.
En la función del ejemplo indexamos recursivamente todos los campos, de manera que si se trata de un vector se guarde bajo el campo "vector.campo: valor", esto nos resultará muy útil a la hora de lanzar las busquedas complejas.
Realizando busquedas complejas
Como veiamos anteriormente, para hacer busquedas usando CouchDB-Lucene simplemente tendremos que acceder a través de un documento especial, y le pasaremos como parámetros en la URL los parámetros de la busqueda que queramos realizar. Por ejemplo:
http://localhost:5984/base_de_datos/_fti/lucene/by_everything/?q=Configuration.Value:[3 TO 9] AND Element.Value:Fe&sort=\Score&include_docs=true
Está url buscará todos los elementos que tengan un vector Configuration con una propiedad Value entre 3 y 9, y que además tengan un vector Element con una propiedad Value igual a Fe (q=Configuration.Value:[3 TO 9] AND Element.Value:Fe). Además tenemos dos parámetros más, sort=\Score, que ordena los resultados inversamente por la propiedad Score e include_docs, que nos devolverá el documento entero y no solo su identificador . Para ordenar de forma normal, simplemente hay que omitir el simbolo \ o sustituirlo por /.
A continuación...
En principio, doy está serie de artículos por acabados. Aún queda ver la forma de formatear la salida de las vistas, pero es un API que actualmente se está cambiando así que lo dejaré hasta que se estabilice un poco. Los siguientes artículos relacionados con CouchDB hablaran sobre el proyecto que estamos desarrollando con CouchDB. Empieza lo interesante.
CouchDB: Una pequeña introducción (Parte III)
Enviado por manolopm el Lun, 07/20/2009 - 12:15.Filtrado de vistas y View Collations
CouchDB permite únicamente filtrar por la clave de las parejas clave-valor generadas por una vista. Para ello en la URL simplemente hay que añadirle los campos keystart y/o keyend. Así, por ejemplo si quisieramos filtrar todos los telefonos que empiezan por 123, usariamos la siguiente funcion map:
function (doc){
for (ph in doc.Teléfono)
emit(doc.Teléfono[ph], doc.Nombre);
}
Y llamaríamos a nuestra vista pasandole startkey="123-" y endkey="124-":
http://url_del_servidor:5984/base_de_datos/_design/nombre_documento/_view/nombre_vista&startkey="123-"&endkey="124-"
View Collations
View Collations es una técnica utilizada para obtener resultados de diferentes tipos de documentos y poder filtrarlos. Para ello usaremos la función map para generar parejas clave-valor, pero nos aprovecharemos de las capacidades de filtrado por clave que nos suministra CouchDB para obtener los resultados deseados.
Por ejemplo, supongamos que a nuestra base de datos de tarjetas de presentación le añadimos documentos que indican quien ha introducido esa tarjeta de presentación. Para realizar esta modificación añadiremos a los documentos de tarjeta de visita dos propiedades nuevas, el tipo y el autor. El tipo nos permitirá diferenciar entre los dos tipos de documentos, y el autor contendrá el identificador de un documento con información del autor.
{
"Tipo": "Tarjeta de visita",
"Nombre": "Jane Doe",
"Telefono": [ "456-789-465", "999-876-543" ],
"Dirección": "Cl. Void, 21",
"Skype": "JaneDoe",
"Autor": "FrankDoe"
}
Y además añadiremos los documentos de tipo 'Autor' que seguiran el siguiente esquema:
{
"Tipo": "Autor",
"Nombre": "Frank Doe",
}
Para obtener un listado de teléfonos y autores, a modo de foreign key de una base de datos clásica, tendríamos que crear esta función map:
function(doc) {
if (doc.Tipo == "Autor")
emit(doc.Nombre,doc);
else
emit(doc.Autor,doc);
}
Esta función nos suministrará una lista de clave-valor, en la cual tendremos parejas del tipo Nombre - Documento para los documentos de tipo "Autor" y Autor - Documento para los documentos de tipo "Tarjeta de visita".
Ahora añadiremos una función reduce para completar nuestro listado:
function(keys, values, rereduce)
{
var autorestelefono = [];
for(var i = 0; i < values.length; i++)
{
if(values[i].Tipo == "Tarjeta de visita")
{
autorestelefono.push([values[i].Nombre,values[i].Teléfono]);
}
}
return autorestelefono;
}
Con esta función buscaremos todos los elementos de tipo "Tarjeta de visita" y para ellos devolveremos un array con el Nombre de la tarjeta de visita y los telefonos. Como la clave de estos elementos coincide con la clave de los elementos de tipo Autor generados en la función map, es decir coincide con el nombre de la Foreign Key, tendremos una lista con clave : Nombre del autor y valor: Nombre de la tarjeta de visita y teléfono.
Esta técnica nos permite hacer busquedas y filtrados avanzados, pero no permite hacer filtrados del estilo de una base de datos clásica. Para este tipo de filtrados la mejor solución es usar Couchdb-Lucene ( http://github.com/rnewson/couchdb-lucene/tree/master ).
A continuación...
Hasta aquí hemos visto la mayoría de los conceptos básicos de CouchDB, faltaría ver los _lists y los _shows para formatear las salidas de las vistas, pero esto lo dejaremos para más adelante. En el siguiente post hablaremos sobre CouchDB-Lucene y como utilizarlo para realizar busquedas de texto completas. Si tienen alguna duda, pregunta o sugerencia, dejen un comentario.
CouchDB: A brief introduction (Part III)
Enviado por manolopm el Lun, 07/20/2009 - 11:56.Filtering with views and ViewCollation
CouchDB lets search only for the key-value pairs generated by a view. To make this , just simply add the fields keystart and/or keyend to the URL of the view. So, if we want to filter all the telephone numbers that begins with 123, we will use the next map function:
function (doc){
for (ph in doc.Telephone)
emit(doc.Telephone[ph], doc.Name);
}
And we make a call to the view with startkey="123-" and endkey="124-":
http://url_of_the_server:5984/data_base/_design/document_name/_view/view_name&startkey="123-"&endkey="124-"
View Collations
View Collations is a technique used to get results from diferents kinds of documents and then filter them. To make this we will use a map function to generate the key-value pairs but we use the filtering capabilities from CouchDB to get the results that we want.
For example, let's thing in our presentation card database. We want to add information about the person that put that information card into the database. To make this modification we add two new properties, the type of document and the author. The type of document will be used to identify the type of document, I mean, its an information card or its an author information document. And the author is like a foreing key in a traditional database that would be used to reference the document that holds information about the author.
{
"Type": "Information card",
"Name": "Jane Doe",
"Telephone": [ "456-789-465", "999-876-543" ],
"Address": "St. Void, 21",
"Skype": "JaneDoe",
"Author": "FrankDoe"
}
We will also make another type of document , the Author document. This type of documents will contain all the information related to the author following the next schema:
{
"Type": "Author",
"Name": "Frank Doe",
}
To get a view with the telephone numbers and the authors, we should use a map function like this:
function(doc) {
if (doc.Tipo == "Author")
emit(doc.Name,doc);
else
emit(doc.Author,doc);
}
This function will return a list of key-value paires , with pairs Name - Document for every document of the type "Author" and Author - Document pairs for the documents of the type "Information Card".
To complete our view we will use a reduce function that builds the "Join":
function(keys, values, rereduce)
{
var authorstelephone = [];
for(var i = 0; i < values.length; i++)
{
if(values[i].Type == "Information card")
{
authortelephone.push([values[i].Name,values[i].Telephone]);
}
}
return authorstelephone;
}
With this function we will search all the elements of type "Information card" and we return an array with the Name that is in the card and the telephone of that person. As the key of this elements is the same that the key of the elements of the type "Author" generated with the map function, I mean is equal as the name of the "Foreing key", we will have a list with keys with the name of the author and value with the name of the person in the information card and the telephone.
This technique is great to make advanced filters and searchs, but isn't similar to a classic database. To make searchs like the classic one, the best solution is Couchdb-Lucene ( http://github.com/rnewson/couchdb-lucene/tree/master ).
Next...
We have seen almost all the basic concepts of CouchDB. We need to explain something of _lists and _shows to make a complete review of CouchDB, this functions are used to give format to the output of the views, but we let them to a later post. In the next one we will talk about how to use CouchDB-Lucene and how to use it to make complete text searchs. f you have any comment, doubt or sugestion fell free of leave a comment.




Comentarios recientes
hace 13 semanas 9 horas
hace 13 semanas 6 días
hace 28 semanas 5 días
hace 1 año 3 días
hace 1 año 3 días
hace 1 año 1 semana
hace 1 año 1 semana
hace 1 año 49 semanas
hace 1 año 49 semanas
hace 1 año 52 semanas