Instalación y Configuración de Apache Solr
Apache Solr es una plataforma de búsqueda empresarial de código abierto, basada en Apache Lucene, que destaca por su escalabilidad, alta disponibilidad y la capacidad de indexar y buscar en millones de documentos con gran velocidad. Solr soporta búsqueda de texto completo, búsqueda facetada, geoespacial, sugerencias y clustering mediante SolrCloud, siendo una opción probada en entornos empresariales exigentes. Esta guía cubre la instalación en Linux, creación de cores y colecciones, diseño del schema y la configuración de SolrCloud.
Requisitos Previos
- Ubuntu 20.04/22.04 o CentOS 8+/Rocky Linux 8+
- Java 11 o Java 17
- 4 GB de RAM mínimo (8 GB recomendado)
- 20 GB de espacio en disco
- Puerto 8983 disponible
Instalación de Apache Solr
# Instalar Java si no está disponible
sudo apt update && sudo apt install -y openjdk-17-jdk # Ubuntu/Debian
sudo dnf install -y java-17-openjdk # CentOS/Rocky
java -version
# Descargar la versión estable más reciente de Solr
SOLR_VERSION=9.5.0
wget https://downloads.apache.org/solr/solr/${SOLR_VERSION}/solr-${SOLR_VERSION}.tgz -P /tmp
# Verificar la descarga con SHA512
wget https://downloads.apache.org/solr/solr/${SOLR_VERSION}/solr-${SOLR_VERSION}.tgz.sha512 -P /tmp
sha512sum -c /tmp/solr-${SOLR_VERSION}.tgz.sha512
# Extraer el instalador del paquete
tar xzf /tmp/solr-${SOLR_VERSION}.tgz solr-${SOLR_VERSION}/bin/install_solr_service.sh --strip-components=2 -C /tmp
# Instalar Solr como servicio (crea usuario solr, directorio /opt/solr y servicio systemd)
sudo bash /tmp/install_solr_service.sh /tmp/solr-${SOLR_VERSION}.tgz
# Verificar el estado del servicio
sudo systemctl status solr
# Acceder a la interfaz web de administración
# http://tu-ip:8983/solr
Instalación manual (sin script)
# Si prefieres instalación manual
sudo useradd -r -s /bin/false solr
sudo mkdir -p /opt/solr /var/solr
tar xzf /tmp/solr-${SOLR_VERSION}.tgz -C /opt/
sudo ln -s /opt/solr-${SOLR_VERSION} /opt/solr
sudo chown -R solr:solr /opt/solr /opt/solr-${SOLR_VERSION} /var/solr
# Configurar variables de entorno
sudo tee /etc/default/solr > /dev/null <<EOF
SOLR_HOME=/var/solr
SOLR_HEAP=2g
SOLR_PORT=8983
SOLR_HOST=0.0.0.0
JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
EOF
Creación de Cores
En Solr, un core es una instancia de índice con su propio schema y configuración:
# Crear un core usando la API (modo standalone)
curl "http://localhost:8983/solr/admin/cores?action=CREATE&name=productos&configSet=_default"
# O usando el script de Solr
sudo -u solr /opt/solr/bin/solr create -c productos -n _default
# Listar cores existentes
curl "http://localhost:8983/solr/admin/cores?action=STATUS"
# Recargar un core después de cambios de configuración
curl "http://localhost:8983/solr/admin/cores?action=RELOAD&core=productos"
# Eliminar un core
curl "http://localhost:8983/solr/admin/cores?action=UNLOAD&core=productos&deleteIndex=true&deleteDataDir=true&deleteInstanceDir=true"
Diseño del Schema
Solr usa managed-schema (schema gestionado via API) o el archivo schema.xml:
# Añadir campos al schema via API (Schema API)
# Añadir un campo de texto
curl -X POST http://localhost:8983/solr/productos/schema \
-H "Content-Type: application/json" \
-d '{
"add-field": {
"name": "nombre",
"type": "text_general",
"stored": true,
"indexed": true,
"multiValued": false
}
}'
# Añadir múltiples campos en una sola petición
curl -X POST http://localhost:8983/solr/productos/schema \
-H "Content-Type: application/json" \
-d '{
"add-field": [
{"name": "descripcion", "type": "text_general", "stored": true, "indexed": true},
{"name": "categoria", "type": "string", "stored": true, "indexed": true, "docValues": true},
{"name": "marca", "type": "string", "stored": true, "indexed": true, "docValues": true},
{"name": "precio", "type": "pfloat", "stored": true, "indexed": true, "docValues": true},
{"name": "stock", "type": "pint", "stored": true, "indexed": true},
{"name": "activo", "type": "boolean", "stored": true, "indexed": true},
{"name": "fecha_alta", "type": "pdate", "stored": true, "indexed": true, "docValues": true},
{"name": "etiquetas", "type": "string", "stored": true, "indexed": true, "multiValued": true, "docValues": true}
]
}'
# Ver el schema completo
curl "http://localhost:8983/solr/productos/schema?wt=json" | python3 -m json.tool
Tipos de campo comunes en Solr
| Tipo | Uso |
|---|---|
text_general | Texto con análisis estándar |
text_es | Texto con análisis en español (stemming, stopwords) |
string | Cadena exacta (para facetas y ordenación) |
pint / pfloat / plong | Números enteros/decimales |
pdate | Fechas |
boolean | Verdadero/falso |
location | Coordenadas geoespaciales (latitud/longitud) |
Indexación de Documentos
# Indexar documentos vía JSON
curl -X POST "http://localhost:8983/solr/productos/update?commit=true" \
-H "Content-Type: application/json" \
-d '[
{
"id": "prod-001",
"nombre": "Camiseta básica algodón",
"descripcion": "Camiseta unisex de algodón 100% disponible en varios colores",
"categoria": "Ropa",
"marca": "BasicWear",
"precio": 19.99,
"stock": 150,
"activo": true,
"fecha_alta": "2024-01-15T00:00:00Z",
"etiquetas": ["ropa", "casual", "algodón"]
},
{
"id": "prod-002",
"nombre": "Zapatillas deportivas running",
"descripcion": "Zapatillas ligeras para correr con amortiguación extra",
"categoria": "Calzado",
"marca": "SpeedRun",
"precio": 89.99,
"stock": 45,
"activo": true,
"fecha_alta": "2024-02-01T00:00:00Z",
"etiquetas": ["deporte", "running", "calzado"]
}
]'
# Actualización atómica de campos (sin reindexar el documento completo)
curl -X POST "http://localhost:8983/solr/productos/update?commit=true" \
-H "Content-Type: application/json" \
-d '[{"id": "prod-001", "precio": {"set": 17.99}, "stock": {"inc": 50}}]'
# Eliminar un documento por ID
curl -X POST "http://localhost:8983/solr/productos/update?commit=true" \
-H "Content-Type: application/json" \
-d '{"delete": {"id": "prod-001"}}'
# Eliminar con una consulta
curl -X POST "http://localhost:8983/solr/productos/update?commit=true" \
-H "Content-Type: application/json" \
-d '{"delete": {"query": "activo:false"}}'
# Commit manual (sin commit=true en la URL)
curl "http://localhost:8983/solr/productos/update?commit=true"
# Optimizar el índice (consolida segmentos, mejora rendimiento)
curl "http://localhost:8983/solr/productos/update?optimize=true"
Consultas y Búsqueda Facetada
# Búsqueda básica
curl "http://localhost:8983/solr/productos/select?q=zapatillas&wt=json&indent=true"
# Búsqueda con parámetros avanzados
curl "http://localhost:8983/solr/productos/select?wt=json&indent=true" \
--data-urlencode "q=zapatillas deporte" \
--data-urlencode "qf=nombre^3 descripcion etiquetas^2" \
--data-urlencode "defType=edismax" \
--data-urlencode "fq=activo:true" \
--data-urlencode "fq=precio:[0 TO 100]" \
--data-urlencode "sort=precio asc" \
--data-urlencode "rows=20" \
--data-urlencode "start=0" \
--data-urlencode "fl=id,nombre,precio,categoria,score"
Búsqueda facetada
# Facetas de campo (para filtros de navegación)
curl "http://localhost:8983/solr/productos/select?wt=json&indent=true" \
--data-urlencode "q=*:*" \
--data-urlencode "fq=activo:true" \
--data-urlencode "facet=true" \
--data-urlencode "facet.field=categoria" \
--data-urlencode "facet.field=marca" \
--data-urlencode "facet.field=etiquetas" \
--data-urlencode "facet.mincount=1" \
--data-urlencode "facet.limit=10" \
--data-urlencode "facet.range=precio" \
--data-urlencode "facet.range.start=0" \
--data-urlencode "facet.range.end=500" \
--data-urlencode "facet.range.gap=50" \
--data-urlencode "rows=0"
Búsqueda geoespacial
# Buscar productos en un radio de 10 km de unas coordenadas
curl "http://localhost:8983/solr/tiendas/select?wt=json" \
--data-urlencode "q=*:*" \
--data-urlencode "fq={!geofilt sfield=ubicacion pt=40.416775,-3.703790 d=10}" \
--data-urlencode "sort=geodist() asc" \
--data-urlencode "fl=nombre,ciudad,geodist()"
SolrCloud con ZooKeeper
SolrCloud permite distribuir los índices entre múltiples nodos:
# Iniciar ZooKeeper embebido en Solr (solo para pruebas)
sudo -u solr /opt/solr/bin/solr start -c
# Para producción, usar un ensemble de ZooKeeper externo (3 nodos)
# En cada nodo Solr, indicar la dirección de ZooKeeper
sudo -u solr /opt/solr/bin/solr start -c -z zk1:2181,zk2:2181,zk3:2181
# Crear una colección en SolrCloud con 2 shards y 2 réplicas
curl "http://localhost:8983/solr/admin/collections?action=CREATE&name=productos&numShards=2&replicationFactor=2&collection.configName=_default"
# Ver el estado del clúster
curl "http://localhost:8983/solr/admin/collections?action=CLUSTERSTATUS&wt=json" | python3 -m json.tool
# Subir configuración personalizada a ZooKeeper
sudo -u solr /opt/solr/bin/solr zk upconfig \
-z localhost:9983 \
-n mi-config \
-d /opt/solr/server/solr/configsets/mi-config/
Seguridad y Autenticación
# Habilitar autenticación básica
# Crear archivo de configuración de seguridad en ZooKeeper
curl http://localhost:8983/solr/admin/authentication -H 'Content-type:application/json' \
-d '{"set-user": {"admin": "contraseña_admin", "usuario": "contraseña_usuario"}}'
# Habilitar el handler de seguridad en solr.xml
# Editar /var/solr/data/solr.xml y añadir autenticación
# Configurar HTTPS
# Generar keystore Java
keytool -genkeypair -alias solr-ssl \
-keyalg RSA \
-keysize 2048 \
-keystore /etc/solr/ssl/solr-ssl.keystore.p12 \
-storetype PKCS12 \
-storepass contraseña_keystore \
-validity 3650 \
-dname "CN=solr.tudominio.com, OU=IT, O=MiEmpresa, L=Madrid, ST=Madrid, C=ES"
Solución de Problemas
Solr no arranca:
# Revisar logs
sudo tail -100 /var/solr/logs/solr.log | grep -i "error\|exception"
# Verificar que Java está disponible
java -version
# Comprobar permisos
ls -la /var/solr/
sudo chown -R solr:solr /var/solr/
Core en estado de error:
# Ver el estado detallado del core
curl "http://localhost:8983/solr/admin/cores?action=STATUS&core=productos&wt=json" | python3 -m json.tool
# Los errores de core suelen ser por schema inconsistente o archivos de índice corruptos
# Intentar recargar el core
curl "http://localhost:8983/solr/admin/cores?action=RELOAD&core=productos"
Rendimiento lento en consultas:
# Habilitar caché de consultas en solrconfig.xml
# Revisar el plan de ejecución de la consulta con debugQuery
curl "http://localhost:8983/solr/productos/select?q=zapatillas&debugQuery=true&wt=json" | python3 -m json.tool
# Añadir docValues a los campos usados en facetas y ordenación
# Aumentar la caché de filtros (filterCache) en solrconfig.xml
Alta memoria heap:
# Ajustar SOLR_HEAP en /etc/default/solr
SOLR_HEAP=4g # Usar máximo el 50% de la RAM disponible
sudo systemctl restart solr
Conclusión
Apache Solr es una solución de búsqueda probada en producción durante más de 15 años, con una comunidad activa y un ecosistema maduro de integraciones. Su soporte nativo para SolrCloud, las actualizaciones atómicas de campos y las capacidades geoespaciales lo hacen especialmente adecuado para aplicaciones empresariales que requieren búsqueda avanzada a escala. La curva de aprendizaje es mayor que la de soluciones más modernas como Meilisearch o Typesense, pero las posibilidades de personalización y el rendimiento en grandes volúmenes de datos justifican la inversión.


