Python Elasticsearch: una introducción | Interno
En este artículo, aprenderá qué es Elasticsearch y por qué puede usarlo. En resumen, Elasticsearch es un motor de búsqueda optimizado sobre un No SQL Base de datos. Elasticsearch se distribuye, lo que significa que puede escalar horizontalmente en muchas máquinas diferentes. Esto lo convierte en una buena opción para manejar grandes cantidades de datos. Elasticsearch se usa a menudo para aplicaciones que requieren búsqueda de texto completo, búsqueda en tiempo real y análisis. También aprenderá cómo configurar un clúster de Elasticsearch localmente y un ejemplo de cómo usar su cliente de Python. Vamos a empezar.
¿Qué es Python Elasticsearch?
Elasticsearch es un motor de búsqueda optimizado en una base de datos NoSQL. Elasticsearch se distribuye, lo que significa que puede escalar horizontalmente en muchas máquinas diferentes. Esto lo convierte en una buena opción para manejar grandes cantidades de datos. Elasticsearch se usa a menudo para aplicaciones que requieren búsqueda de texto completo, búsqueda en tiempo real y análisis.
¿Para qué se usa Elasticsearch?
Puede usar Elastisearch para administrar diferentes tipos de datos, como texto y datos numéricos. Datos no estructurados almacenado en formato JSON serializado, lo que hace que Elasticsearch NoSQL Base de datos. A diferencia de la mayoría de las bases de datos NoSQL, Elasticsearch está optimizado para las capacidades del motor de búsqueda.
Elasticsearch es de código abierto, rápido, fácil de escalar y distribuido. Estos factores lo hacen atractivo para sitios web, aplicaciones web y otras aplicaciones con mucho contenido dinámico, así como para diversas aplicaciones, como análisis de acceso.
Internamente, cuando instala Elasticsearch por primera vez, indexa sus datos. Aquí, índice significa un conjunto optimizado de documentos. Además, los documentos son colecciones de campos con pares clave-valor que contienen sus datos. De manera predeterminada, Elasticsearch indexa todos los datos y tiene sus propias optimizaciones para diferentes tipos de datos. estructura de datos.
Elasticsearch es muy rápido debido al índice que crea al ingerir datos que utilizan estructuras de datos óptimas para diferentes dominios. Puede recuperar datos rápidamente consultando el índice en lugar de los datos originales.
Por ejemplo, almacena campos de texto en algo llamado índice invertido (almacena campos numéricos en árboles BKD). En resumen, un índice invertido es una estructura de datos que admite búsquedas rápidas de texto completo. Un índice invertido enumera cada palabra única que aparece en cualquier documento e identifica todos los documentos en los que aparece cada palabra. Esta es una estructura de datos importante porque permite búsquedas de texto completo ultrarrápidas, una de las principales ventajas de Elasticsearch.
Puede usar Elasticsearch sin esquema, lo que significa que puede indexar automáticamente documentos sin especificaciones precisas sobre cómo manejar diferentes tipos de datos. Este principio hace que sea fácil comenzar con Elasticsearch. Sin embargo, a veces es posible que desee definir explícitamente las asignaciones para tener un control total sobre la indexación de sus datos. Elasticsearch también permite este enfoque.
Cómo configurar y usar Elasticsearch
Para seguir este ejemplo en su computadora, necesita algunas cosas. Antes de comenzar, debe:
A continuación se explica cómo crear un entorno virtual mediante la línea de comandos. Pitón:
$ python -m venv .venv
$ source .venv/bin/activate
$ python -m pip install pandas notebook elasticsearch==8.5.2
Si está utilizando Windows, ejecute lo siguiente en lugar del segundo comando:
$ .venv\Scripts\activate.bat
Aquí, por supuesto, pip es el instalador de paquetes para Python. Instala paquetes desde el índice de paquetes de Python y otros índices.
Usar Docker es una forma sencilla de ejecutar Elasticsearch localmente, por lo que solo necesita instalarlo y ejecutarlo. Para iniciar un clúster de Elasticsearch de un solo nodo que se puede usar para el desarrollo localmente, puede ejecutar la siguiente línea (que se puede dividir en varias líneas en su pantalla) en una terminal:
$ docker run --rm -p 9200:9200 -p 9300:9300 -e "xpack.security.enabled=false" -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:8.5.2
Cuando ejecute este comando, debería ver una gran cantidad de texto, algo como esto:
El comando inició el clúster de Elasticsearch en su máquina local. Aquí hay un resumen de lo que hacen las diferentes partes del equipo:
los docker run
El comando se usa para ejecutar una imagen dentro de un contenedor, en este caso, Elasticsearch con la versión 8.5.2.
los –rm
El parámetro le dice a Docker que limpie y elimine el sistema de archivos del contenedor, que se inicia cuando el contenedor sale.
los -p 9200:9200 -p 9300:9300
El parámetro especifica los puertos utilizados para la interfaz de red del contenedor.
los -e "xpack.security.enabled=false"
la configuración desactiva las funciones de seguridad. Esto es útil para el desarrollo local, pero nunca debe usarse en producción.
los -e "discovery.type=single-node"
La configuración obliga a Docker a crear un clúster con un solo nodo.
Ahora podemos probar la conexión al clúster de Elasticsearch creando y ejecutando el siguiente script de Python:
from elasticsearch import Elasticsearch
es = Elasticsearch("http://localhost:9200")
print(es.info().body)
Ejecutarlo en su entorno virtual debería devolver un resultado similar a este:

Este es un archivo JSON impreso en la terminal, por lo que parece un poco desordenado, pero nos conectamos con éxito al clúster de Elasticsearch que acabamos de crear.
¡Ahora estamos listos para crear un índice de Elasticsearch y agregarle algunos datos!
Usémoslo primero pandas para leer el conjunto de datos que descargamos al principio. Esto se puede hacer con las siguientes dos líneas de código Python:
import pandas as pd
dataframe = pd.read_csv("netflix_titles.csv", keep_default_na=False)
los keep_default_na=False
el parámetro almacena valores vacíos en el conjunto de datos como cadenas vacías en su lugar NaN
que a Elasticsearch no le gusta.
Ahora los datos se almacenan en la variable del marco de datos. Vamos a crear un índice en el clúster de Elasticsearch que configuramos anteriormente mediante la creación de un mapa que le indique al índice cómo almacenar documentos. Define los diferentes tipos de datos de diferentes campos en sus documentos de mapeo. Puede crear dinámicamente (es decir, automáticamente) o explícitamente. Vamos a dejarlo claro aquí para ver cómo se hace. Aquí está el código:
mappings = {
"properties": {
"type": {"type": "text", "analyzer": "english"},
"title": {"type": "text", "analyzer": "english"},
"director": {"type": "text", "analyzer": "standard"},
"cast": {"type": "text", "analyzer": "standard"},
"country": {"type": "text", "analyzer": "standard"},
"date_added": {"type": "text", "analyzer": "standard"},
"release_year": {"type": "integer"},
"rating": {"type": "text", "analyzer": "standard"},
"duration": {"type": "text", "analyzer": "standard"},
"listed_in": {"type": "keyword"},
"description": {"type": "text", "analyzer": "english"}
}
}
es.indices.create(index="netflix_shows", mappings=mappings)
Esto creará un nuevo índice llamado netflix_shows
en el clúster de Elasticsearch que configuramos hace unos minutos.
Ahora podemos comenzar a agregar datos al índice. Dos comandos pueden hacer esto: es.index()
y agregue datos un elemento a la vez bulk()
para agregar varios elementos a la vez.
Puede agregar información usando aquí es.index()
:
for i, row in dataframe.iterrows():
data = {
"type": row["type"],
"title": row["title"],
"director": row["director"],
"cast": row["cast"],
"country": row["country"],
"date_added": row["date_added"],
"release_year": row["release_year"],
"rating": row["rating"],
"duration": row["duration"],
"listed_in": row["listed_in"],
"description": row["description"]
}
es.index(index="netflix_shows", id=i, document=data)
Este código agregará los datos a la variable. data
al índice de Elasticsearch netflix_shows
(se puede almacenar más de un índice en un clúster) con id i
. Porque todo esto sucede dentro de un para el bucle todos los datos en el conjunto se agregarán una fila a la vez, iterando entre todas las filas en nuestro conjunto de datos previamente cargado.
Puede agregar información usando aquí bulk()
:
from elasticsearch.helpers import bulk
bulk_data = []
for i,row in dataframe.iterrows():
bulk_data.append(
{
"_index": "netflix_shows",
"_id": i,
"_source": {
"type": row["type"],
"title": row["title"],
"director": row["director"],
"cast": row["cast"],
"country": row["country"],
"date_added": row["date_added"],
"release_year": row["release_year"],
"rating": row["rating"],
"duration": row["duration"],
"listed_in": row["listed_in"],
"description": row["description"]
}
}
)
bulk(es, bulk_data)
Este código hace lo mismo que el código es.index()
anterior y requiere la misma información (es decir, nombre de índice, identificador y documento). La diferencia es que en lugar de agregar documentos línea por línea, creamos una lista de diccionarios con todos los documentos en el conjunto de datos. A continuación, pase esta lista de diccionarios y el objeto de clúster como argumentos bulk()
, todos los documentos se agregan al índice en un solo comando. usando bulk()
el comando para agregar varios documentos a la vez es un poco más rápido que agregar varios documentos a la vez.
Después de agregar los datos, podemos asegurarnos de que todo funcione contando la cantidad de elementos netflix_shows
índice con el siguiente código:
es.indices.refresh(index="netflix_shows")
print(es.cat.count(index="netflix_shows", format="json"))
Entonces deberías ver algo como esto:

Esto muestra que un total de 8807 documentos están almacenados en el índice.
Finalmente, podemos comenzar a usar Elasticsearch para la funcionalidad de búsqueda. Solicitud de ADSL (Lenguaje específico del dominio). Este enlace es un buen lugar para comenzar a crear y comprender consultas en Elasticsearch.
A continuación, se muestra una consulta de muestra para encontrar programas estadounidenses de Netflix que no se emitieron antes de 2015. netflix_shows
índice:
query = {
"bool": {
"filter": {
"match_phrase": {
"country": "United States"
}
},
"must_not": {
"range": {
"release_year": {"lte": 2015}
}
}
}
}
result = es.search(index="netflix_shows", query=query)
print(result)
Debería ver algo como esto:

En la primera fila, puede ver que se encontraron un total de 2232 documentos coincidentes en la consulta. De forma predeterminada, Elasticsearch devuelve los 10 mejores documentos coincidentes al realizar una consulta. En nuestro ejemplo, puede ver estos documentos impresos en la terminal de arriba.
Finalmente, veamos cómo puedes eliminarlo. elimine datos de su índice o incluso elimine todo el índice. La siguiente línea de código elimina el documento con id 1337 del índice netflix_shows
:
es.delete(index="netflix_shows", id="1337")
Y la siguiente línea de código elimina todo netflix_shows
índice y todos sus documentos si necesita hacerlo por cualquier motivo:
es.indices.delete(index="netflix_shows")
Otras lecturas
Ahora conoce los conceptos básicos de Elasticsearch y su cliente Python. Si quieres profundizar, te recomiendo ver Documentación de Elasticsearch y Documentación del cliente Python de Elasticsearch.