Як реалізувати Elasticsearch у Go

Сьогодні я збираюся показати вам, як реалізувати Elasticsearch у Go.

Але, звичайно, перед цим я збираюся зробити невеликий вступ до Elasticsearch.

Якщо ви вже отримали базове розуміння Elasticsearch, ви можете перейти до наступної частини.

Еластичний пошук

Elasticsearch останнім часом набирає великої популярності. Пошук у реляційній базі даних завжди має проблеми з масштабованістю та продуктивністю.

Elasticsearch - це база даних NoSQL, яка дуже успішно вирішила ці проблеми. Це забезпечує велику масштабованість та продуктивність, і однією з найвизначніших особливостей є система підрахунку балів, яка забезпечує велику гнучкість у результатах пошуку. Зрештою, це не називається Еластичний пошук без причини!

Встановлення Elasticsearch

По-перше, вам потрібно буде встановити Elasticsearch на локальній машині. Ви можете зайти на їх веб-сайт і отримати керівництво з його встановлення. На момент написання цієї статті я використовую Elasticsearch з номером версії 7.4.2.

Elasticsearch вніс багато змін у свої версії, однією з яких було видалення типу відображення. Тому не сподівайтесь, що це повністю спрацює, якщо ви використовуєте іншу версію Elasticsearch.

Закінчивши встановлення, не забудьте запустити службу elasticsearch, про яку досить чітко згадується в їх керівництві з установки (для Linux це коротше ./bin/elasticsearch).

Переконайтесь, що ваш еластичний пошук запущений , запитувавши порт 9200 на вашому локальному комп'ютері.

ОТРИМАТИ localhost:9200

Натискання на ньому повинно показати щось подібне нижче.

{ "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" }

Якщо він відображається правильно, тоді вітаємо! Ви успішно запустили свою послугу еластичного пошуку на своїй локальній машині. Дайте собі хлопати і візьміть чашку кави, оскільки день ще молодий.

Створення першого індексу

В Elasticsearch індекс подібний до бази даних. Тоді як раніше в еластичному пошуку існувала таблиця типу. Але оскільки тип був видалений у поточній версії, зараз є лише індекс.

Збентежений зараз? Не бути. У двох словах, просто подумайте, що вам потрібен лише індекс, тоді згодом вам просто потрібно вставити ваші дані в Elasticsearch.

Тепер ми збираємося зробити індекс, названий studentsза допомогою запиту нижче.

ВСТАНОВИТИ localhost/9200/students

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

Якщо нічого не піде не так, він повинен відповісти, давши це.

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

Ваш індекс повинен бути створений. Тепер ми перейдемо до нашого наступного кроку: пограємо з нашим індексом Elasticsearch.

Заповнюйте свій Elasticsearch

По-перше, те, що ми будемо робити зараз, - це заповнення нашого індексу Elasticsearch документами. Якщо ви не знайомі з цим визначенням, просто знайте, що воно дуже схоже на рядки в базі даних.

У базі даних NoSQL насправді можливо, щоб кожен документ містив різні поля, які не відповідають схемі.

Але не будемо цього робити - давайте побудуємо наш стовпець із схемою, яку ми визначили раніше. Попередній API дозволить заповнити документ у вашому індексі.

ПОСТ localhost:9200/students/doc

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

Наразі ваш Elasticsearch повинен мати один документ. Нам потрібно буде вставити ще кілька даних у наш Elasticsearch. І звичайно, ми не збираємося вставляти дані про студентів по одному - це було б досить клопотом!

Elasticsearch спеціально підготував масовий API для того, щоб надсилати кілька запитів одночасно. Давайте використаємо це, щоб вставити кілька даних одночасно.

ПОСТ /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 }

Давайте запитаємо дані

Ми нарешті заповнили наш Elasticsearch ще кількома даними студентів. Тепер давайте зробимо те, чим відомий Elasticsearch: ми спробуємо шукати в нашому Elasticsearch дані, які ми щойно вставили.

Elasticsearch підтримує багато типів механізмів пошуку, але для цього прикладу ми будемо використовувати простий відповідний запит.

Почнемо наш пошук, натиснувши цей API:

ПОСТ localhost:9200/_search

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

Ви отримаєте свою відповідь разом із даними студентів, які відповідають вашому відповідному запиту. Тепер ви офіційно пошуковий інженер!

{ "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 } } ] } }

А тепер приступимо до Go!

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!

На цьому мій підручник про те, як реалізувати Elasticsearch у Go, закінчується. Сподіваюся, я розглянув основні частини використання Elasticsearch у Go.

Щоб отримати додаткову інформацію з цієї теми, вам слід прочитати про запит DSL та оцінку функцій в Elasticsearch, що, на мій погляд, одна з найкращих речей про Elasticsearch.

І не хвилюйтеся, бібліотека, використана в цьому прикладі, також підтримує багато функцій Elasticsearch, навіть запит оцінки функцій в Elasticsearch.

Дякуємо, що прочитали мою статтю! Я сподіваюся, що це буде корисно і може допомогти вам розпочати роботу з Elasticsearch.

Ніколи не припиняйте вчитися; знання подвоюються кожні чотирнадцять місяців. ~ Ентоні Дж. Д'Анджело