# Dec 1st, 2019 \[FIN\]\[ES\] Datatieteilijän työkalut: Elasticsearch ja Python

**URL:** <https://discuss.elastic.co/t/dec-1st-2019-fin-es-datatieteilijan-tyokalut-elasticsearch-ja-python/209773>\
**Category:** Advent Calendar\
**Tags:** elastic-stack-machine-learning\
**Created:** [December 1, 2019, 8:00am UTC](https://discuss.elastic.co/t/dec-1st-2019-fin-es-datatieteilijan-tyokalut-elasticsearch-ja-python/209773 "2019-12-01T08:00:03Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Camilla\_Montonen](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/camilla_montonen/32/58449_2.png) [@Camilla\_Montonen](https://discuss.elastic.co/u/Camilla_Montonen)\
**Post date:** [December 1, 2019, 8:00am UTC](https://discuss.elastic.co/t/dec-1st-2019-fin-es-datatieteilijan-tyokalut-elasticsearch-ja-python/209773/1 "2019-12-01T08:00:03Z")

</div>

## Datatieteilijän työkalut: Elasticsearch ja Python

Yleensä suurin osa datatieteilijän työajasta saattaa kulua datan keräämiseen ja puhdistamiseen ennen kuin päästään itse koneoppimisalgoritmien käyttämiseen. Yksi osa tätä prosessia on datan varastoiminen sopivaan tietokantaan. Yhä useammat sovellukset käyttävät Elasticsearchia tietojen tallentamiseen, hakemiseen ja analysoimiseen. Tietojen analysoimiseen voidaan Elasticsearchin sisäänrakennettujen toimintojen lisäksi käyttää myös ulkoisia, asiaan soveltuvia ohjelmistoja ja kirjastoja. Yksi tällä hetkellä suosituimmista datatieteeseen soveltuvista ohjelmointikielistä on ehdottomasti avoimen lähdekoodin omaava Python, jolle on ohjelmoitu lukuisia datan analysoimiseen ja koneoppimiseen soveltuvia kirjastoja.

Tässä lyhyessä artikkelissa tarkastelemme sitä, miten voimme käyttää Pythonin funktioita ja toimintoja Elasticsearchiin tallennetun datan analysoimiseen. Koska Python 2 on hiljalleen poistumassa käytöstä, tulevat kyseisen artikkelin esimerkit käyttämään Python 3:n syntaksia.

### REST-rajapinnat ja elasticsearch-py ohjelmistokirjasto

Elasticsearch tarjoaa REST-ohjelmointirajapinnan. Jotta työskenteleminen tämän rajapinnan kanssa kävisi joutuisammin, on olemassa lukuisia pääteohjelmistoja ja -kirjastoja, joista löytyy hyödyllisiä toimintoja ja funktioita juuri tähän tarkoitukseen. Tässä artikkelissa esittelemme virallisen Python kirjaston [elasticsearch-py:n](https://github.com/elastic/elasticsearch-py), mutta vastaavia kirjastoja löytyy muun muassa seuraaville ohjelmointikielille: Ruby ([elasticsearch-ruby](https://github.com/elastic/elasticsearch-ruby)), .NET([elasticsearch-net](https://github.com/elastic/elasticsearch-net)), PHP([elasticsearch-php](https://github.com/elastic/elasticsearch-php)) ja Javascript([elasticsearch-js](https://github.com/elastic/elasticsearch-js)).

[elasticsearch-py:n](https://github.com/elastic/elasticsearch-py) ohjelman asentaminen onnistuu parhaiten käyttämällä Pythonin pip kirjastonhallintasovellusta. Jotta ohjelmointiympäristösi pysyisi mahdollisimman siistinä, on suositeltavaa, että käytämme niin kutsuttua Pythonin virtuaaliympäristöä (engl. `virtualenv`) . Tämän luominen Python 3:n avulla onnistuu näin

```auto
python3 -m venv es_env

```

Virtuaaliympäristölle annamme esimerkissä nimeksi `es_env`, mutta nimen voi tietenkin mukauttaa omaan tarkoitukseensa. Luomisen jälkeen, virtuaaliympäristö tulee ns. aktivoida, jolloin kaikki asennetut kirjastot pysyvät omassa nimiavaruudessaan eivätkä sotkeennu tietokoneen käyttöjärjestelmässä oleviin Python-kirjastoihin.

```auto
source es_env/bin/activate

```

 ![49%20AM](https://us1.discourse-cdn.com/elastic/original/3X/b/2/b2569ce2e701c8f55ecb7302774e127b756c9d0c.png)

Seuraavaksi asennetaan [elasticsearch-py](https://github.com/elastic/elasticsearch-py) pip-ohjelmaa käyttäen. Huomaathan, että pip-ohjelman tietokannassa tämän kirjaston nimestä on jätetty py-pääte pois.

```auto
pip install elasticsearch

```

Kun ohjelma on asennettu, voimme aloittaa sen käytön Python-ohjelmissamme.

### Jupyter - interaktiivinen ohjelmointiympäristö

Tässä vaiheessa on sopiva puhua hieman eri ohjelmointiympäristöistä, joissa Python-ohjelmia voidaan kehittää. Usein Python-ohjelma kirjoitetaan tekstieditorilla ja käynnistetään käyttämällä konsolin `python` komentoa esimerkiksi näin.

 ![14%20PM](https://us1.discourse-cdn.com/elastic/original/3X/f/0/f0448f7326e2601503680a02e8840516089791b8.png)

Datatiedettä varten sopivampi ympäristö on kuitenkin yleensä visuaalinen, selaimessa toimiva ympäristö nimeltä [Jupyter](https://jupyter.org/).

[Jupyter](https://jupyter.org/) on avoimeen lähdekoodiin pohjautuva projekti ja sen voi asentaa samaan virtuaaliympäristöön käyttämällä `pip` ohjelmaa.

```auto
pip install jupyter

```

Niin kutsuttu Jupyter-palvelin käynnistetään seuraavalla tavalla

```auto
jupyter notebook

```

Kun palvelin on käynnistynyt, voimme navigoida selaimellamme osoitteeseen

```auto
localhost:8888

```

ja avata uuden Jupyter-ymparistön. Tässä interaktiivisessa ympäristössä on hyvä analysoida dataa, sillä koodin lomaan voi tallentaa myös kaavioita ja tekstiä.

 ![27%20PM](https://us1.discourse-cdn.com/elastic/original/3X/d/1/d1400bfa27f22e541767571f60669d6b578781a3.png)

## Datan tallentaminen ja lukeminen

Ensiksi käytämme `import`-komentoa ja tuomme elasticsearch-py -ohjelmistokirjaston luokan nimeltä `Elasticsearch`, josta voimme luoda niin kutsutun pääteolion (engl. client object)

```auto
from elasticsearch import Elasticsearch

# luomme olion nimeltä es_client
es_client = Elasticsearch()

```

Tässä tapauksessa meillä on Elasticsearch-palvelin samalla koneella kuin Python-ohjelma, joten meidän ei tarvitse erikseen muokata `es_client`-olion asetuksia, sillä oletusasetukset muodostavat yhteyden paikallisella koneella, eli `localhostilla` olevalle Elasticsearch-palvelimelle.

Elasticsearch tallentaa dataa JSON (Javascript Object Notation) -olioina. Yksinkertaisimmillään olion muodostuvat aaltosulkeiden välissä olevista avain-arvo pareista. Esimerkiksi alla olevat JSON-oliot kuvailevat kuvitteellisella jouluruokalistalla olevia tuotteita

```auto
{"nimike":"porkkanalaatikko",
 "maidoton": true, 
 "hinta": 5.00,
 "valuutta": "EUR",
  "paino": 0.1,
"ainekset": ["porkkana", "puuroriisi", "tumma siirappi"]}

{"nimike":"joulupuuro",
 "maidoton": false, 
 "hinta": 2.00,
 "valuutta": "EUR",
  "paino": 0.2,
"ainekset": ["puuroriisi", "maito", "sokeri", "manteli"]}

{"nimike":"piparkakkutaikina",
 "maidoton": true, 
 "hinta": 4.35,
 "valuutta": "EUR",
  "paino": 0.2,
"ainekset": ["vesi", "vehnäjauho", "tumma siirappi", "sokeri", "piparkakkumauste"]}

```

Tallenetaan nämä JSON-oliot Elasticsearch-indeksiin nimeltä `jouluruokalista`.

```auto
# luodaan Pythonille natiivi tietorakenne, sanakirja, yllä olevasta Python oliosta
# ja annetaan sitä merkitsevälle muuttujalle nimeksi porkkana_laatikko.
# Huomaathan, että yllä JSON-oliossa oleva totuusarvo false
# on muttunut Pythonille ominaiseksi False:ksi

porkkana_laatikko = {"nimike":"porkkanalaatikko",
 "maidoton": True, 
 "hinta": 5.00,
 "valuutta": "EUR",
  "paino": 0.1,
"ainekset": ["porkkana", "puuroriisi", "tumma siirappi"]}

# käytetään yllä luomaamme es_client olion
# index-metodia tämän olion tallentamiseen

es_client.index(index='jouluruokalista', body=porkkana_laatikko)

```

Tämän onnistuessa, saamme Elasticsearchilta seuraavanlaisen vastauksen (kuvakaappaus Jupyter- ymparistöstä)

 ![35%20AM](https://us1.discourse-cdn.com/elastic/original/3X/0/6/06e397a1f732805b5a2ab9c6c79aad4df4f584e4.png)

## Datan tallentaminen Bulk API rajapinnan kautta

Dataintensiivisissä sovelluksissa kuitenkin harvoin tallennetaan tai luetaan vain yhtä JSON-oliota kerrallaan ja tämä on otettu huomioon myös elasticsearch-py kirjastojen funktioissa. Mikäli haluamme tallentaa Elasticsearchiin useamman kuin yhden JSON-olion, voimme käyttää niin kutsuttua [Bulk API](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html) ohjelmointirajapintaa, jonka toimintoja voi käyttää `helpers`-moduulin funktioiden avulla. Katsotaan seuraavaksi esimerkki siitä, miten tämä onnistuu käytännössä.

Ensiksi käytämme `import`-käskyä ja tuomme `helpers`-moduulin Python-ohjelmaamme.

```auto

from elasticsearch import helpers

```

Funktio, jota tulemme käyttämään fiktiivisen jouluruokalistamme tallentamiseen Elasticsearchiin, on nimeltään [`bulk`](https://elasticsearch-py.readthedocs.io/en/master/helpers.html#elasticsearch.helpers.bulk) ja se tarvitsee argumentteinaan luomamme pääteolion `es_client`:in sekä listan niistä JSON-olioista, jotka haluamme tallentaa.

```auto
# luodaan JSON-olioita kuvaavat sanakirja-tietorakenteet 
# ja annetaan niille nimet

porkkana_laatikko = {"nimike":"porkkanalaatikko",
 "maidoton": True, 
 "hinta": 5.00,
 "valuutta": "EUR",
  "paino": 0.1,
"ainekset": ["porkkana", "puuroriisi", "tumma siirappi"]}

joulupuuro = {"nimike":"joulupuuro",
 "maidoton": False, 
 "hinta": 2.00,
 "valuutta": "EUR",
  "paino": 0.2,
"ainekset": ["puuroriisi", "maito", "sokeri", "manteli"]}

piparkakku = {"nimike":"piparkakkutaikina",
 "maidoton": True, 
 "hinta": 4.35,
 "valuutta": "EUR",
  "paino": 0.2,
"ainekset": ["vesi", "vehnäjauho", "tumma siirappi", "sokeri", "piparkakkumauste"]}

```

```auto

# tallenetaan sanakirjat listaan
# ja kaytetaan helpers-moduulin bulk-funktiota
# jolle argumenteiksi annetaan pääteolio, data-lista 
# sekä indeksin nimi
data = [porkkana_laatikko, joulupuuro, piparkakku]
helpers.bulk(es_client, data, index='jouluruokalista', 
 raise_on_error=True)

```

### Datan lukeminen Elasticsearchista

Datan tallentamisen lisäksi on hyvä myös käydä läpi, miten jo tallennettuja olioita voi lukea Elasticsearchista Python-ohjelmaamme. Tämä voi tulla tarpeeseen esimerkiksi, jos haluat analysoida dataasi käyttäen koneoppimisalgoritmeja tai funktioita, joita ei ole Elasticsearchissa.

Elasticsearch sisältää useita eri toimintoja tietyn datan hakemiseen esimerkiksi hakusanoilla, mutta tässä tapauksessa haluamme lukea kaikki indeksissä olevat JSON-oliot. Tähän tarkoitukseen solveltuu Elasticsearchin [Scroll](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html#request-body-search-scroll)-toiminto, joka [elasticsearch-py:n](https://github.com/elastic/elasticsearch-py) kirjastossa on implementoitu `helpers` moduulin `scan`-funktioon.

Olemme jo aikaisemmassa esimerkissämme tuoneet `helpers`-moduulin ohjelmaamme. Näin ollen voimme suoraan siirtyä käyttämään `scan`-funktiota ja sen jälkeen voimme lukea JSON-olioita valitsemastamme indeksistä.

```auto
# luetaan kaikki oliot indeksistä jouluruokalista
# tallennetaan tulos muuttujaan "hakutulokset"

hakutulokset = helpers.scan(es_client, index='jouluruokalista')

```

Yksittäiset JSON-oliot on mahdollista lukea hakutulokset muuttujasta käyttämällä for-silmukkaa.

```auto
for olio in hakutulokset:
    print(olio)

```

Alla olevasta Jupyter-ympäristössä otetutta kuvakaappauksessa näkyy, että indeksissämme on yhteensä neljä JSON-oliota: yksi, jonka tallensimme käyttäen `es_client.index`-funktiota ja kolme, jotka tallensimme käyttäen `Bulk API`-rajapintaa.

 ![04%20PM](https://us1.discourse-cdn.com/elastic/original/3X/d/6/d667c9e91d06dbe09f97a5d3704be5e7d8918ec5.png)

---

<div class="post-metadata">

**Author:** ![saif3r](https://avatars.discourse-cdn.com/v4/letter/s/49beb7/32.png) [@saif3r](https://discuss.elastic.co/u/saif3r)\
**Post date:** [January 30, 2020, 10:04am UTC](https://discuss.elastic.co/t/dec-1st-2019-fin-es-datatieteilijan-tyokalut-elasticsearch-ja-python/209773/2 "2020-01-30T10:04:33Z")

</div>

Hello @Camilla_Montonen,  
Any chance to get this translated to English? I don't want to rely on automatic translator 🙂  
Cheers.

---

<div class="post-metadata">

**Author:** ![Camilla\_Montonen](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/camilla_montonen/32/58449_2.png) [@Camilla\_Montonen](https://discuss.elastic.co/u/Camilla_Montonen)\
**Post date:** [February 3, 2020, 12:04pm UTC](https://discuss.elastic.co/t/dec-1st-2019-fin-es-datatieteilijan-tyokalut-elasticsearch-ja-python/209773/3 "2020-02-03T12:04:47Z")

</div>

Hey @saif3r - I think that would be possible for me to do at some point this week. Will ping you when it's done!

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [November 4, 2022, 7:35am UTC](https://discuss.elastic.co/t/dec-1st-2019-fin-es-datatieteilijan-tyokalut-elasticsearch-ja-python/209773/4 "2022-11-04T07:35:17Z")

</div>


