20 Millionen Artikel

Alexander Girke

Universität Leipzig / Mercateo Gruppe

Wie findet man die Nadel im Heuhaufen?

Gliederung

- Motivation

- Lösung

- ElasticSearch

     Aufbau

     Suchen

     Weitere Features

- Lokale Demo

Motivation

Beispiel: Kunde/Kundin sucht ein T-Shirt

früher: Kataloge aus Papier

https://www.tagesspiegel.de/wirtschaft/versandhandel-otto-katalog-wird-eingestellt/22771476.html

Motivation

20 Millionen Artikel,
⌀ 10 Artikeln pro Seite
 = 2 Millionen Seiten

2 Millionen Seiten,
0,15mm pro Seite
 = 300000mm
 = 300m Höhe

https://commons.wikimedia.org/wiki/File:Margaret_Hamilton_-_restoration.jpg

Wie findet man da effizient ein blaues T-Shirt, das maximal 15€ kostet?

Mercateo Deutschland Sortiment:
20 Millionen Artikel

Lösung

Suchmaschinen

Gibt's da schon was Fertiges?

Wie funktioniert das?

Wozu braucht man das?

Wozu man Suchmaschinen braucht ...

... beispielsweise zur Volltextsuche ...

... also "Finde für meinen Text x alle Dokumente, die diesen enthalten ...

... und sage mir, wie gut ein Dokument zu meiner Suche passt."

Wie Suchmaschinen funktionieren ...

... beispielsweise mit Inversen Indexstrukturen

... also ein Verzeichnis aller Vorkommen von Schlüsselbegriffen

... Beispiel:

  • "Datenbank" ↔ Doc1, Doc2
  • "Index"            ↔ Doc2, Doc3

... Scoring beispielsweise durch tf-idf
                                  
(= term frequency - inverse document frequency)

... Stoppwörter werden ausgelassen

Was es schon gibt ...

... besonders beliebt: Apache Lucene

... Server basierend auf Lucene: Solr & ElasticSearch

Vorteile:

  • bewährtes Setup
  • Open-Source
  • hohe Verfügbarkeit / Lastverteilung
  • ...

ElasticSearch

ELasticSearch

  • NoSQL-Datenbank

  • RESTful (bzw. HTTP+JSON)

  • verteilt

  • Schnell

  • Skalierbar

  • Resilient

  • ...

ELasticSearch

https://www.elastic.co/static/images/elk/elk-stack-elkb-diagram.svg

Der Elastic-Stack (früher nur ELK)

https://images.contentstack.io/v3/assets/bltefdd0b53724fa2ce/blt4b5878e620695c17/5c11edeb928f832d782d0622/elk-stack-elk-bee.svg

ELasticSearch

Aufbau

ElasticSearch Cluster

Index 1

Index n

...

Shard 1

Shard 2

= Rechner

Knoten 1

Replica Shard 2

Knoten 2

Replica Shard 1

Shard x

= Lucene-Index

ELasticSearch

mit ElasticSearch REDEN

GET /articleindex/article/_search?q=tshirt

Index

Operation

Typ

Term

POST /articleindex/article/1

{ ... }
GET /articleindex/_mapping

Suchen

Dokument anlegen

Mapping anzeigen

POST /articleindex/_bulk

{ ... }
{ ... }

Mehrere Dokumente mit einem Mal anlegen

ELasticSearch

BeispielDokument ( vom Typ 'Article' )

{
    "id": ...,
    "title": ...,
    "description": ...,
    "manufacturerName": ...,
    "image": {
        "mimeType": ...,
        "href": ...
    },
    "keywords": [ ... ],
    "color": ...,
    "price": {
        "amount": ...,
        "currency": ...,
        "tax": ...
    }
}

ELasticSearch

Automatisch erzeugtes Mapping

{
    "articleindex": {
        "mappings": {
            "article": {
                "properties": {
                    "description": {
                        "type": "text"
                    },
                    "id": {
                        "type": "text"
                    },
                    "image": {
                        "properties": {
                            "href": {
                                "type": "text"
                            },
                            "mimeType": {
                                "type": "text"
                            }
                        }
                    },
                    "keywords": {
                        "type": "text"
                    },
                    "manufacturerName": {
                        "type": "text"
                    },
                    "price": {
                        "properties": {
                            "amount": {
                                "type": "float"
                            },
                            "currency": {
                                "type": "text"
                            },
                            "tax": {
                                "type": "float"
                            }
                        }
                    },
                    "title": {
                        "type": "text"
                    }
                }
            }
        }
    }
}

ELasticSearch

Suchen

POST /articleindex/article/_search

{
    "query": {
        "match_all": {}
    }
}

Match All Query

ELasticSearch

Suchen

POST /articleindex/article/_search

{
    "query": {
        "match": {
            "_all": "Lorem ipsum dolor"
        }
    }
}

Match Query (Volltext-Query)

ELasticSearch

Suchen

POST /articleindex/article/_search

{
    "query": {
        "term": {
            "manufacturerName": "Super Manufacturer"
        }
    }
}

Term Query

ELasticSearch

Suchen

POST /articleindex/article/_search

{
    "query": {
        "prefix" : { "title" : "shir" }
    }
}

Prefix Query

ELasticSearch

POST /articleindex/article/_search

{
    "query": {
        "bool" : {
            "must" : {
                "term" : { "image.mimeType" : "image/jpeg" }
            },
            "filter": {
                "term" : { "manufacturerName" : "Super Manufacturer" }
            },
            "should" : [
                {
                    "match" : { "title" : "Shirt" }
                }
            ]
        }
    }
}

Bool Query

(Compound Query)

Suchen

ELasticSearch

{
    "id": ...,
    "title": ...,
    "variations": [
        {
            "color": "blue",
            "size": "L"
        }, 
        {
            "color": "red",
            "size": "M"
        }
    ]
}

Suchen

{ "article" : {
        "properties" : {
            "variations" : {
                "type" : "nested",
                "properties": { 
                    "color": { "type": "keyword" }, 
                    "size": { "type": "keyword" } 
                }}}}}

Nested Property

(Index Definition)

{
    "id": ...,
    "title": ...,
    "variations": [
        {
            "color": "blue",
            "size": "M"
        }
    ]
}

blau & M

ELasticSearch

POST /articleindex/article/_search

{
    "query": {
        "nested" : {
            "path" : "article",
            "query" : {
                "bool" : {
                    "must" : [
                        {
                            "match" : {"article.variations.color" : "blue"}
                        },
                        {
                            "match" : {"article.variations.size" : "M"}
                        }
                    ]
                }
            }
        }
    }
}

Nested Query

(Joining Query)

Suchen

findet alle Dokumente, bei denen blau & M in einem Subdokument sind

ELasticSearch

Viele weitere Suchen

  • Range Query
  • Exists Query
  • Wildcard Query
  • Regex Query
  • IDs Query
  • Constant Score Query
  • Geo-Query
  • ...

ELasticSearch

Zusätzlich:

  • Suggestions
    • Auto-Completion
  • Aggregations
    • z.B. Bucket (Metrik pro Kategorie)
  • Index-Operationen
    • z.B. Mapping updaten
  • vieles mehr ...

Live Demo

ELasticSearch

  • Beispiel vom Anfang: blaues T-Shirt, 15 €
  • ES lokal als Docker Image starten
  • Http-Requests mithilfe von Postman
  • Dokumente indizieren
  • Suchen

Performance erhöhen

ELasticSearch

  • auf Cluster verteilen
  • genug RAM pro Maschine (min. 30GB)
  • wenn möglich, nested Strukturen vermeiden
  • möglichst Analyse während Ingestion
    • doppelte, suchoptimierte Felder sind gut
    • Trade-Off: umfassender Index ↔ Ingestion-Zeit
  • Ingestion-Zeit:
    • dedizierte Ingestion-Nodes
    • asynchron (abhängig von Client-Performanz)
    • Bulks
  • ...

Fazit

ELasticSearch

  • ElasticSearch ist schnell aufgesetzt
  • leicht zu bedienen
  • viele Features
  • auch für riesige Datenmengen geeignet

Fragen?

ELasticSearch

Made with Slides.com