Cómo implementar Elasticsearch en Go

Hoy, les mostraré cómo implementar Elasticsearch en Go.

Pero claro, antes de eso voy a dar una pequeña introducción a Elasticsearch.

Si ya ha adquirido un conocimiento básico de Elasticsearch, puede pasar a la siguiente parte.

Elasticsearch

Elasticsearch ha ganado mucha popularidad últimamente. La búsqueda en una base de datos relacional siempre tiene problemas relacionados con la escalabilidad y el rendimiento.

Elasticsearch es una base de datos NoSQL que ha tenido mucho éxito al abordar esos problemas. Proporciona una gran escalabilidad y rendimiento, y una de las características más destacadas es el sistema de puntuación que permite mucha flexibilidad en los resultados de búsqueda. Después de todo, ¡no se llama Elastic-search sin razón!

Instalación de Elasticsearch

Primero, necesitará instalar Elasticsearch en su máquina local. Puede ir a su sitio web y obtener la guía de instalación. En el momento en que escribo este artículo, estoy usando Elasticsearch con el número de versión 7.4.2.

Elasticsearch ha realizado muchos cambios en sus versiones, uno de ellos es la eliminación del tipo de mapeo. Por lo tanto, no espere que esto funcione completamente si está utilizando otra versión de Elasticsearch.

Después de terminar su instalación, no olvide ejecutar su servicio elasticsearch, que se menciona con bastante claridad en su guía de instalación (para Linux, en resumen, haga esto ./bin/elasticsearch).

Asegúrese de que su elasticsearch se esté ejecutando solicitando el puerto 9200 en su máquina local.

OBTENER localhost:9200

Al presionarlo, debería aparecer algo como a continuación.

{ "name": "204371", "cluster_name": "elasticsearch", "cluster_uuid": "8Aa0PznuR1msDL9-PYsNQg", "version": { "number": "7.4.2", "build_flavor": "default", "build_type": "tar", "build_hash": "2f90bbf7b93631e52bafb59b3b049cb44ec25e96", "build_date": "2019-10-28T20:40:44.881551Z", "build_snapshot": false, "lucene_version": "8.2.0", "minimum_wire_compatibility_version": "6.8.0", "minimum_index_compatibility_version": "6.0.0-beta1" }, "tagline": "You Know, for Search" }

Si se muestra correctamente, ¡felicitaciones! Ha ejecutado con éxito su servicio de búsqueda elástica en su máquina local. Date una palmada y tómate una taza de café, ya que el día aún es joven.

Haciendo tu primer índice

En Elasticsearch, el índice es similar a una base de datos. Mientras que antes, había una tabla en elasticsearch llamada type. Pero dado que se eliminó el tipo en la versión actual, ahora solo hay index.

¿Confundido ahora? No lo estés. En pocas palabras, solo piense que solo necesita un índice y luego solo necesita insertar sus datos en Elasticsearch.

Ahora, vamos a crear un índice llamado studentshaciendo la consulta a continuación.

PONER localhost/9200/students

{ "settings": { "number_of_shards": 1, "number_of_replicas": 1 }, "mappings": { "properties": { "name": { "type": "text" }, "age": { "type": "integer" }, "average_score": { "type": "float" } } } }

Si nada sale mal, debería responder dando esto.

{ "acknowledged": true, "shards_acknowledged": true } 

Debe crearse su índice. Ahora procederemos al siguiente paso: jugar con nuestro índice Elasticsearch.

Poblando su Elasticsearch

Primero, lo que haremos ahora es completar nuestro índice de Elasticsearch con documentos. Si no está familiarizado con esa definición, sepa que es muy similar a las filas de una base de datos.

En una base de datos NoSQL, es posible que cada documento contenga diferentes campos que no coinciden con el esquema.

Pero no hagamos eso, construyamos nuestra columna con un esquema que hemos definido antes. La API anterior le permitirá completar el documento en su índice.

ENVIAR localhost:9200/students/doc

{ "name":"Alice", "age":17, "average_score":81.1 } 

Tu Elasticsearch ya debería tener un documento. Necesitaremos insertar varios datos más en nuestro Elasticsearch. Y, por supuesto, no vamos a insertar los datos de nuestros estudiantes uno por uno, ¡eso sería bastante complicado!

Elasticsearch ha preparado específicamente una API masiva para enviar múltiples solicitudes a la vez. Usemos eso para insertar varios datos a la vez.

ENVIAR /students/_bulk

{ "index":{"_index": "students" } } { "name":"john doe","age":18, "average_score":77.7 } { "index":{"_index": "students" } } { "name":"bob","age":16, "average_score":65.5 } { "index":{"_index": "students" } } { "name":"mary doe","age":18, "average_score":97.7 } { "index":{"_index": "students" } } { "name":"eve","age":15, "average_score":98.9 }

Busquemos los datos

Finalmente hemos poblado nuestro Elasticsearch con varios datos de estudiantes más. Ahora hagamos lo que es conocido por Elasticsearch: intentaremos buscar en nuestro Elasticsearch los datos que acabamos de insertar.

Elasticsearch admite muchos tipos de mecanismos de búsqueda, pero para este ejemplo usaremos una consulta de coincidencia simple.

Comencemos nuestra búsqueda presionando esta API:

ENVIAR localhost:9200/_search

{ "query" : { "match" : { "name" : "doe" } } } 

Recibirá su respuesta junto con los datos de los estudiantes que coincidieron con su consulta correspondiente. ¡Ahora eres oficialmente un ingeniero de búsqueda!

{ "took": 608, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 2, "relation": "eq" }, "max_score": 0.74487394, "hits": [ { "_index": "students", "_type": "_doc", "_id": "rgpef24BTFuh7kXolTpo", "_score": 0.74487394, "_source": { "name": "john doe", "age": 18, "average_score": 77.7 } }, { "_index": "students", "_type": "_doc", "_id": "sApef24BTFuh7kXolTpo", "_score": 0.74487394, "_source": { "name": "mary doe", "age": 18, "average_score": 97.7 } } ] } }

¡Ahora vamos a ir!

If you have reached this part, you should have grasped the very minimum concepts of using Elasticsearch. Now, we are going to implement Elasticsearch in Go.

A very primitive way of implementing Elasticsearch is that you can keep doing http requests into your Elasticsearch IP. But we are not going to do that.

I found this very helpful library for implementing Elasticsearch in Go. You should install that library before you proceed in your Go modules.

Make your struct

First of all, you will definitely need to make a struct for your Model. In this example, we are going to use the same modeling as in our previous example which in this case is the Student struct.

package main type Student struct { Name string `json:"name"` Age int64 `json:"age"` AverageScore float64 `json:"average_score"` }

Making a Client Connection

Now, let's make a function that'll allow us to initialize our ES Client connection.

If you have a running instance of Elasticsearch outside of your localhost, you can simply change the part inside SetURL.

func GetESClient() (*elastic.Client, error) { client, err := elastic.NewClient(elastic.SetURL("//localhost:9200"), elastic.SetSniff(false), elastic.SetHealthcheck(false)) fmt.Println("ES initialized...") return client, err }

Data Insertion

After that, the first thing we can do is try to insert our data into Elasticsearch via Go. We will be making a model of Student and inserting it into our Elasticsearch client.

package main import ( "context" "encoding/json" "fmt" elastic "gopkg.in/olivere/elastic.v7" ) func main() { ctx := context.Background() esclient, err := GetESClient() if err != nil { fmt.Println("Error initializing : ", err) panic("Client fail ") } //creating student object newStudent := Student{ Name: "Gopher doe", Age: 10, AverageScore: 99.9, } dataJSON, err := json.Marshal(newStudent) js := string(dataJSON) ind, err := esclient.Index(). Index("students"). BodyJson(js). Do(ctx) if err != nil { panic(err) } fmt.Println("[Elastic][InsertProduct]Insertion Successful") }

Querying our Data

Finally, we can do some searching. The below code might look a bit complex. But rest assured, it will make more sense to you after you go through it carefully. I will be using a basic matching query in the below example.

package main import ( "context" "encoding/json" "fmt" elastic "gopkg.in/olivere/elastic.v7" ) func main() { ctx := context.Background() esclient, err := GetESClient() if err != nil { fmt.Println("Error initializing : ", err) panic("Client fail ") } var students []Student searchSource := elastic.NewSearchSource() searchSource.Query(elastic.NewMatchQuery("name", "Doe")) /* this block will basically print out the es query */ queryStr, err1 := searchSource.Source() queryJs, err2 := json.Marshal(queryStr) if err1 != nil || err2 != nil { fmt.Println("[esclient][GetResponse]err during query marshal=", err1, err2) } fmt.Println("[esclient]Final ESQuery=\n", string(queryJs)) /* until this block */ searchService := esclient.Search().Index("students").SearchSource(searchSource) searchResult, err := searchService.Do(ctx) if err != nil { fmt.Println("[ProductsES][GetPIds]Error=", err) return } for _, hit := range searchResult.Hits.Hits { var student Student err := json.Unmarshal(hit.Source, &student) if err != nil { fmt.Println("[Getting Students][Unmarshal] Err=", err) } students = append(students, student) } if err != nil { fmt.Println("Fetching student fail: ", err) } else { for _, s := range students { fmt.Printf("Student found Name: %s, Age: %d, Score: %f \n", s.Name, s.Age, s.AverageScore) } } }

The query should be printed out like this:

ES initialized... [esclient]Final ESQuery= {"query":{"match":{"name":{"query":"Doe"}}}}

And yes that query is what will be posted into the Elasticsearch.

The result of your query should also come out like this if you have followed my example since the very start:

Student found Name: john doe, Age: 18, Score: 77.700000 Student found Name: mary doe, Age: 18, Score: 97.700000 Student found Name: Gopher doe, Age: 10, Score: 99.900000 

And there you go!

Ese es el final de mi tutorial sobre cómo implementar Elasticsearch en Go. Espero haber cubierto las partes más básicas del uso de Elasticsearch en Go.

Para obtener más información sobre este tema, debe leer sobre Query DSL y Function Scoring en Elasticsearch, que en mi opinión es una de las mejores cosas de Elasticsearch.

Y no se preocupe, la biblioteca utilizada en este ejemplo también es compatible con muchas funciones de Elasticsearch, incluso la consulta de puntuación de funciones en Elasticsearch.

¡Gracias por leer mi artículo! Espero que sea útil y pueda ayudarlo a comenzar a usar Elasticsearch.

Nunca dejes de aprender; el conocimiento se duplica cada catorce meses. ~ Anthony J. D'Angelo