Monthly Archives: May 2015

Apunto y olvido … ya lo revisaré más tarde

Cuando estás trabajando, concentrado en una tarea, es muy común que te asalten nuevas ideas, tareas nuevas que tienes que hacer, errores que detectas, hasta cosas que tienes que hacer en casa o que ir a comprar. Nuestro subconsciente es muy traicionero, y está acechando continuamente para intentar interrumpir nuestra concentración, nuestra productividad.

Obviamente es algo que no quieres que se te pase, que no quieres olvidar. Yo en estos casos lo que hago es apuntarlo e intentar olvidarlo lo más rápido posible, de forma que interrumpa mi concentración lo mínimo posible, y poder seguir con la tarea que estaba.

Pero hay que tener algún cuidado en cómo apuntamos estos “pensamientos”:

Tienes que apuntarlo rápido.

Ten a mano siempre aquello que vayas a necesitar para apuntar, sea un software, una libreta o un trozo de papel. No puedes perder tiempo en ponerte a buscar donde apuntarlo cuando lo necesites.

Apúntalo siempre en el mismo sitio.

La “bandeja de entrada” debe ser única. Todo tienes que escribirlo en el mismo sitio, ya que eso te da la seguridad y tranquilidad de que luego lo encontrarás posteriormente, de que no vas a perderlo.

Se fuerte, no caigas en la tentación de hacer caso a lo que te viene a la cabeza.

Debes ser fuerte, y forzarte a ti mismo a olvidar lo que acabas de apuntar. No puedes caer en la tentación de ir a mirar eso que acabas de pensar, ni siquiera un poquito … NO. Debes seguir con el trabajo en el que estabas concentrado y recuperar la concentración lo más rápido posible.

Revisa periódicamente la bandeja de entrada.

Que puedas olvidar instantáneamente lo que acabas de olvidar solo será posible si tienes la seguridad de que posteriormente vas a revisar tu bandeja de entrada. No tiene por que ser dentro de una hora, ni hoy mismo, pero periódicamente tienes que ponerte a revisar todo lo que apuntaste en tu inbox y procesarlo.

Yo, al pasar la mayoría del tiempo delante del ordenador, utilizo Evernote como herramienta para “apuntar y olvidar”.Te ofrece unas pequeñas utilidades que te facilitan esto y consiguen que sea muy rápido, pudiendo tanto anotar texto como imágenes, capturas de pantalla, artículos, links. Además, si te pilla fuera del ordenador, también tiene apps para móvil que puedes utilizar, con lo que te aseguras que todo va a acabar en la misma bandeja de entrada.

ExtendedDismax de Solr, qué significan los parámetros qf, qs, pf, ps, pf2, ps2, pf3, ps3

El ExtendedDismax de Solr, es decir el que utiliza Solr cuando hacemos una búsqueda con defType=edismax tiene unos parámetros realmente interesantes que afectan al cálculo del score, aunque sinceramente, cuesta un poco comprender exactamente en qué consiste y qué aporta cada uno de ellos.

qf (Query Fields)

Son los campos indexados contra los que va a buscar la expresión que llega en la query (parámetro q), por lo que afecta directamente al matching de los resultados, pero además ya permite hacer boosting para cada uno de los campos que se especifiquen. Supongamos que tenemos dos campos en nuestro schema, que son titulo y descripcion, y buscamos algo asi:

        q=+patata +caliente&qf=titulo^10 descripcion

Solr buscará los términos “patata” y “caliente” en los campos titulo y descripcion, pero si lo encuentra en titulo le otorgará un boosting de 10, mientras que si lo encuentra en descripcion, lo hará con el boosting por defecto de 1.

qs (Query phrase Slop)

Viene a indicar la proximidad que exigirá Solr cuando nos llegue un término compuesto entrecomillado. Afecta al matching. Si por ejemplo buscamos:

q=”patata caliente”&qs=2

Solr buscará los términos “patata” y “caliente” con una proximidad de 2 (valor de qs). Es decir, lo que sería una búsqueda por proximidad: q=”patata caliente”~2. Pero la gracia de qs es que lo hace de forma automática con todo aquello que se pida entre comillas. Otro ejemplo.

        q=+pollo +”patata caliente” +comida +”plato menu dia”&qs=3

Acabaría buscando q=+pollo +”patata caliente”~3 +comida +”plato menu dia”~3 . Recuerda que qs afecta al matching.

pf (Phrase Fields) y ps (Phrase Slop)

Estos dos parámetros en conjunto definen el boosting a aplicar cuando se encuentren todos los términos de búsqueda con una proximidad determinada. Importante, no afecta al matching, solo afecta al cálculo del score. De este modo, si por ejemplo buscamos:

q=+pollo +patata +caliente +comida +menu&pf=titulo^20 descripcion^5&ps=7

Solr incrementará:

  • con un boosting de 20 si encuentra en el campo titulo todos los términos con una proximidad de 7 ( titulo:(“pollo patata caliente comida menu”~7)^20 )
  • con un boosting de 5 si encuentra en el campo descripcion todos los términos con una proximidad de 7 ( descripcion:(“pollo patata caliente comida menu”~7)^5 )

pf2 (Phrase bigrams Fields) y ps2 (Phrase bigram slop)

Estos dos parámetros en conjunto definen el boosting a apicar cuando se encuentre cada uno de los bigramas de los términos de búsqueda con una proximidad determinada. Estos parámetros tampoco afectan al matching, solo al score. Así si buscamos:

q=+pollo +patata +caliente +comida +menu&pf2=titulo^40 descripcion^15&ps2=3

Solr incrementará:

  • titulo:(“patata caliente”~3)^40 , es decir, con un boosting de 40 (pf2=titulo^40) si encuentra en el campo titulo el bigrama “patata caliente” con una proximidad de 3 (ps2=3).
  • titulo:(“caliente comida”~3)^40, idem.
  • titulo:(“comida menu”~3)^40, idem.
  • descripcion:(“patata caliente”~3)^15, es decir, con un boostingde 15 (pf2=descripcion^15) si encuentra en el campo descripcion el bigrama “patata caliente” con una proximidad de 3 (ps2=3)
  • descripcion:(“caliente comida”~3)^15, idem.
  • descripcion:(“comida menu”~3)^15, idem.

pf3 (Phrase trigram Fields) y ps3 (Phrase trigram slop)

Estos dos parámetros en conjunto definen el boosting a aplicar cuando se encuentre cada uno de los trigramas de los términos de búsqueda con una proximidad determinada. Estos parámetros tampoco afectan al matching, solo al score. Así si buscamos:

q=+pollo +patata +caliente +comida +menu&pf3=titulo^60 descripcion^25&ps3=5

Solr incrementará:

    • titulo:(“patata caliente comida”~5)^60 , es decir, con un boosting de 40 (pf3=titulo^60) si encuentra en el campo titulo el trigrama “patata caliente comida” con una proximidad de 5 (ps3=5).
    • titulo:(“caliente comida menu”~5)^60, idem.
    • descripcion:(“patata caliente comida”~5)^25, es decir, con un boostingde 25 (pf3=descripcion^25) si encuentra en el campo descripcion el trigrama “patata caliente comida” con una proximidad de 5 (ps3=5)
    • descripcion:(“caliente comida menu”~5)^25, idem.

Y hasta aquí el intento de explicación, buena suerte con el ajuste del scoring.

Como optimizar procesos de inserción masiva en MongoDB

Mongo DB es un document storage NoSql que tiene una capacidad de escritura muy alta, y realmente la tiene, por mi experiencia mucho más que por ejemplo MySql. Pero cuando empiezas a cargarlo de verdad, con procesos de inserción masiva, del orden de millones de documentos, la cosa ya no va sola, y necesitas empezar a desarrollar de una forma determinada para conseguir que tus procesos sigan yendo a toda pastilla. Aquí te cuento algunos de los que he descubierto a base de leer en algunos casos, y de tortas en otros.

No gestionar las transacciones

Ni se te ocurra gestionar las transacciones en este tipo de procesos. Mongo tiene la virtud de poder “insertar y olvidar”, es decir, de enviar los datos a insertar al servidor, y no esperar ningún tipo de respuesta, ni de confirmación por su parte. Esto lo consigues especificando un WriteConcern.UNACKNOWLEDGED, que quiere decir eso, que no te interesa si la inserción ha ido bien o mal. Eso si, para utilizar esto, ya te tienes que haber preocupado previamente de asegurarte que tus inserciones no van a fallar, sino, mal lo tendrás para poder verificar lo que ha ido bien o mal.

Ejecuta un único save para cada documento, nunca update

El método save es mucho más rápido que el método update, ya que directamente escribe, sin verificar si previamente existe el registro o no. Nunca, repito, nunca desarrolles procesos de inserción masiva que quieras que vayan rápido y que no se degraden al crecer las colecciones en los que hagas uno o varios updates. Nuevamente, en este proceso, tendrás que preocuparte de tener a tu alcance toda la información que quieres guardar para cada documento, júntala durante N procesos e inserta una única vez.

Contra colecciones vacías

El tiempo de inserción en colecciones vacías en Mongo es mas bajo que cuando tiene datos. Plantéate en tu proceso si es posible al inicio del mismo borrar completamente la colección y volver a generarla de nuevo con los datos que vas a insertar. Aunque parezca mentira, en muchos casos puede ser más rápido hacer de nuevo una inserción completa que N parciales.

Contra colecciones sin índices

Si tus colecciones tienen índices, bórralos con dropIndex antes de empezar a insertar, ejecutas, y al finalizar vuelves a crear el indice con ensureIndex. El tiempo de creación del índice global es mucho menor que el tiempo que se tiene que invertir en actualizar el mismo índice ya creado en cada inserción de cada documento.

En colecciones más pequeñas

Trocea tus colecciones, tanto la inserción como la recuperación de datos van a ir más rápidas contra diez colecciones de 2 millones de documentos, que contra una única colección de 20 millones. Además, esto te permitirá paralelizar tus procesos y reducir la duración total.

Utiliza diferentes databases

Es incluso preferible utilizar diferentes databases para datos temporales o que vayas a regenerar por completo en ese ciclo, que diferentes colecciones en la misma base de datos. Esto te permitirá incluso hacer dropDatabase que liberará el espacio en disco que Mongo reserva para la db, cosa que no hace si eliminas la colección.

Y hasta aquí mis pequeños trucos para optimizar la inserción masiva en Mongo. Si tienes algún truco que no haya dicho, no dudes en comentármelo.