Actualizaciones sobre un índice ya creado con información de un archivo CSV

Teníamos que actualizar un índice que teníamos en solr con el valor de un campo que nos pasaban en un archivo CSV.

Ejemplo del archivo (el primer campo se corresponde identificador único en el índice) :

"36721373_934",1

"36719138_56",5

"36719199_58",7

"36719523_338",8

"36732719_16",9

"36720095_743",10

"36732723_757",11

"36721134_877",12

"36719244_1623",13

"36719244_118",14

 

Lo que hemos hecho es añadir un campo a squema.xml

<field name="prueba" type="int" indexed="true" stored="true" omitNorms="true"/>

Añadir la request handler de update en el solrconfig.xml

<requestHandler name="/update" class="solr.UpdateRequestHandler">

</requestHandler>

Y finalmente utilizar un curl de este estilo para actualizarlo.

http://xx.xx.xx.xxxx:xxxx/core1/update?stream.file=/path/prueba.csv&stream.contentType=text/csv;charset=utf-8&fieldnames=uid,prueba
Anuncios

Rangos en SOLR

Siempre me cuesta un poco localizarlo, así que añado aquí para futuras referencias. Algunos ejemplos:

1.Coincidencia exacta: q= modify_date:”2012-07-06T9:23:43Z”

2. Menor que: q= modify_date:{* TO 2012-07-06T9:23:43Z }

3. Mayor que: q= modify_date:{ 2012-07-06T9:23:43Z TO *}

4.Menor o igual que: modify_date:[* TO 2012-07-06T9:23:43Z]

5. Mayor o igual que: modify_date:[ 2012-07-06T9:23:43Z TO *]

Cómo limitar que SOLR escuche por una sola interfaz.

Hoy hemos descubierto que el parámetro SOLR_HOST en el fichero de arranque de SOLR no representa la interfaz por la que SOLR escucha.

Por defecto levanta el listener en todas las interfaces de la máquina.

Para solucionarlo hemos añadido al script de arranque de SOLR

“-Djetty.host=$SOLR_HOST”

En la variable:

SOLR_START_OPTS=(‘-server’ ‘-Xss256k’ “${JAVA_MEM_OPTS[@]}” “${GC_TUNE[@]}” “${GC_LOG_OPTS[@]}” \

“${REMOTE_JMX_OPTS[@]}” “${CLOUD_MODE_OPTS[@]}” \

“-Djetty.port=$SOLR_PORT”  “-Djetty.host=$SOLR_HOST” “-DSTOP.PORT=$stop_port” “-DSTOP.KEY=$STOP_KEY” \

“${SOLR_HOST_ARG[@]}” “-Duser.timezone=$SOLR_TIMEZONE” \

“-Djetty.home=$SOLR_SERVER_DIR” “-Dsolr.solr.home=$SOLR_HOME” “-Dsolr.install.dir=$SOLR_TIP” \

“${LOG4J_CONFIG[@]}” “${SOLR_OPTS[@]}”)

Cómo conseguir que el SOLR escuche por dos IPs

Añadir un conector más para la nueva IP JETTY_HOME/ect/jetty-http.xml:

En este caso queremos que también escuche por la  127.0.0.1

<Call name=”addConnector”>

<Arg>

<New class=”org.eclipse.jetty.server.ServerConnector”>

<Arg name=”server”><Ref refid=”Server” /></Arg>

<Arg name=”acceptors” type=”int”><Property name=”solr.jetty.http.acceptors” default=”-1″/></Arg>

<Arg name=”selectors” type=”int”><Property name=”solr.jetty.http.selectors” default=”-1″/></Arg>

<Arg name=”factories”>

<Array type=”org.eclipse.jetty.server.ConnectionFactory”>

<Item>

<New class=”org.eclipse.jetty.server.HttpConnectionFactory”>

<Arg name=”config”><Ref refid=”httpConfig” /></Arg>

</New>

</Item>

</Array>

</Arg>

<Set name=”host”>127.0.0.1</Set>

<Set name=”port”><Property name=”jetty.port” default=”8983″ /></Set>

<Set name=”idleTimeout”><Property name=”solr.jetty.http.idleTimeout” default=”50000″/></Set>

<Set name=”soLingerTime”><Property name=”solr.jetty.http.soLingerTime” default=”-1″/></Set>

<Set name=”acceptorPriorityDelta”><Property name=”solr.jetty.http.acceptorPriorityDelta” default=”0″/></Set>

<Set name=”selectorPriorityDelta”><Property name=”solr.jetty.http.selectorPriorityDelta” default=”0″/></Set>

<Set name=”acceptQueueSize”><Property name=”solr.jetty.http.acceptQueueSize” default=”0″/></Set>

</New>

</Arg>

</Call>

Problemas de memoria en Solr java.lang.OutOfMemoryError.

En ocasiones al procesar mucha información solr se queda sin memoria. Que significa esto; que la máquina de java no es capaz de alocar memoria adicional para ejecutar el proceso que está ejecutando. El resultado es la imposibilidad de añadir información adicional a la memoria, la cual es esencial para que le proceso se ejecute correctamente.

El problema se debe normalmente a un tamaño de pila muy pequeño. La primera solución es darle más memoria a nuestra maquina virtual de Java. Para conseguir esto aumentaremos los parámetros xmx y xms. En nuestro caso estamos utilizando Tomcat y la definición de estos parámetros la encontraremos en setenv.sh

Siempre conviene revisar los índices antes de modificar los parámetros por si estuviéramos consumiendo memoria de más.

El parámetro xms representa el tamaño de la pila al inicio y Xmx. El máximo tamaño que debe alcanzarla pila. En ocasiones es conveniente igualar ambos parameters para no perder tiempo y recursos recalculando el tamaño de la pila.

Una de las formas de monitorear la pila es utilizar estos dos parámetros  XX:+HeapDumpOnOutOfMemory y  XX:HeapDumpPath. Estos parámetros le dan la instrucción a solr de volcar a un log la pila cuando se quede sin memoria.

java –jar –XX:+HeapDumpOnOutOfMemoryError –XX:HeapDumpPath=/opt

Solr

Sol res un servidor de búsquedas con una API tipo REST.. Se colocan documentos (llamados índices y se consultan via HHTP GET. Es un motor de búsqueda basado en Lucene. Permite búsquedas de texto de alto rendimiento utilizando índices invertidos. Se obtiene mayor flexibilidad en la búsqueda de cadenas de texto y en la ordenación y ponderación

Solr se divide en dos partes:

  • Índice: Sistema de ficheros que almacenan la información. Contiene la configuración de Solr y la definición de la estructura de datos.
  • Servidor: Proporciona el acceso a los índices y las características adicionales. Admite plugins para añadir funcionalidades.

Fuente: Seminario Apache Solr de Parádigma

Los pasos para montar un servidor solr serían:

    • Crear los índices.
    • Despliegue de servidor sobre el servidor de aplicaciones.
    • Configuración de enlace entre servidor e índice. (Modificación del fichero web.xml)

Vamos a ir poco a poco desgranando cada uno de estos pasos.

Creación de índices:

Lo primero es definir la estructura que va tener el índice los datos que va a almacenar:

schema.xml: Archivo XML que define las estructura de datos a indexar.

Estructura de campo:

Tipos de Datos: Definidos por clases java.

Parámetros opcionales:

  • default: Valor a usar si no se recibe ninguno
  • required: Define si un campo es obligatorio.
  • indexed: Determina si un campo se puede buscar y ordenable.
  • stored: Determina si un campo se puede recuperar en una cónsul
  • multiValued: El campo contiene más de un valor

Fuentes de datos para la indexación:

Podemos utilizar varias fuentes de datos para los índices.

  • XML: Coherente con la estructura de datos definida.
  • Objetos Java: Representación binaria del documento XML.
  • CSV: Documento de texto con valores separados.
  • Documentos enriquecidos: PDF, XLS, DOC, PPT, …
  • Base de Datos: Adaptador intermedio (DataImportHandler).

La query donde se define los datos que se van a sacar de la base de datos es desde el fichero data-config.xml.

Búsquedas

Una vez que se tenemos los datos indexados necesitamos definir las búsquedas:

Utilizaremos el fichero solrconfig.xml

Parámetros de búsqueda:

  • q: Petición con formato “campo:valor” start: Documento inicial a partir del cual se van a mostrar los resultados.
  • rows: Indica el número máximo de resultados a mostrar.
  • sort: Define la ordenación de los resultados. Ordenaciones combinadas. Formato de ordenaciones: “precio desc, nombre asc”
  • fl: Campos que se devuelven en la respuesta

Si queremos mostrar todos los datos *

  • fq: Mismo formato que “q”. Limita la query (actúa como filtro). Los resultados se cachean.

Operadores:

  • AND: edad:15 && nombre:”Pepe”
  • OR: edad:15 ||nombre:”Pepe”
  • NOT:  edad:15  – nombre:”Pepe”
  • IN: edad:(12 15)
  • RANGOS edad:[12 TO 15]

Fuente: http://es.slideshare.net/paradigmatecnologico/seminario-apache-solr-39931871

Índices invertidos

Acercando me un poco en el mundo solr, encontré la referencia a índices invertidos. Este tipo de índices se utilizan muy frecuentemente en la recuperación de palabras.  Lo que hacen es almacenar cada término junto la lista de documentos donde vamos a encontrar ese término. De esta forma conseguimos un acceso directo a los documentos que contiene esa palabra. Existen dos tipos principales: índice invertido a nivel registro que guarda la referencia al documento que contiene la palabra y índice invertido a nivel palabra que guarda también la posición de la palabra dentro del documento. Este último requiere más tiempo para crearlo y más espacio.

Utilizando un ejemplo de la wikipedia es muy fácil de entender:

Dados los textos:

T[0] = "it is what it is"
T[1] = "what is it"
T[2] = "it is a banana"

Creamos los siguientes índices indicando en que documento encontramos las palabras:

"a":      {2}
"banana": {2}
"is":     {0, 1, 2}
"it":     {0, 1, 2}
"what":   {0, 1}

Utilizando el mismo texto vemos un ejemplo de índice invertido a nivel palabra. Cómo los documentos la posición de las palabras también comienza con 0. Con lo cual banana”: {(2, 3) }significa que la palabra “banana” es la cuarta palabra (posición 3) del tercer.

"a":      {(2, 2)}
"banana": {(2, 3)}
"is":     {(0, 1), (0, 4), (1, 1), (2, 1)}
"it":     {(0, 0), (0, 3), (1, 2), (2, 0)}
"what":   {(0, 2), (1, 0)}

Más información:

http://en.wikipedia.org/wiki/Inverted_index

http://indiceri.netne.net/Indices%20Invertidos.html