Schnelleinstieg in die Volltextsuche mit ElasticSearch

Schneller Einstieg in die Volltextsuche mit ElasticSearch

1. Überblick

Volltextsuche fragt ab und führt sprachliche Suchen nach Dokumenten durch. Es enthält einzelne oder mehrere Wörter oder Ausdrücke und gibt Dokumente zurück, die den Suchbedingungen entsprechen.

ElasticSearch ist eine Suchmaschine, die aufApache Lucene basiert, einer kostenlosen Open-Source-Softwarebibliothek zum Abrufen von Informationen. Es bietet eine verteilte Volltextsuchmaschine mit einer HTTP-Weboberfläche und schemafreien JSON-Dokumenten.

Dieser Artikel untersucht die ElasticSearch-REST-API und beschreibt grundlegende Vorgänge, die nur HTTP-Anforderungen verwenden.

2. Konfiguration

Informationen zum Installieren von ElasticSearch auf Ihrem Computer finden Sie unterofficial setup guide.

Die RESTful-API wird auf Port 9200 ausgeführt. Lassen Sie uns testen, ob es ordnungsgemäß ausgeführt wird. Verwenden Sie dazu den folgenden Befehl curl:

curl -XGET 'http://localhost:9200/'

Wenn Sie die folgende Antwort beobachten, wird die Instanz ordnungsgemäß ausgeführt:

{
  "name": "NaIlQWU",
  "cluster_name": "elasticsearch",
  "cluster_uuid": "enkBkWqqQrS0vp_NXmjQMQ",
  "version": {
    "number": "5.1.2",
    "build_hash": "c8c4c16",
    "build_date": "2017-01-11T20:18:39.146Z",
    "build_snapshot": false,
    "lucene_version": "6.3.0"
  },
  "tagline": "You Know, for Search"
}

3. Indizieren von Dokumenten

ElasticSearch ist dokumentorientiert. Es speichert und indiziert Dokumente. Indizierung erstellt oder aktualisiert Dokumente. Nach der Indizierung können Sie komplette Dokumente suchen, sortieren und filtern - keine Zeilen mit spaltenweisen Daten. Dies ist eine grundlegend andere Art, über Daten nachzudenken, und einer der Gründe, warum ElasticSearch eine komplexe Volltextsuche durchführen kann.

Dokumente werden als JSON-Objekte dargestellt. Die JSON-Serialisierung wird von den meisten Programmiersprachen unterstützt und ist das Standardformat, das von der NoSQL-Bewegung verwendet wird. Es ist einfach, übersichtlich und leicht zu lesen.

Wir werden die folgenden zufälligen Einträge verwenden, um unsere Volltextsuche durchzuführen:

{
  "title": "He went",
  "random_text": "He went such dare good fact. The small own seven saved man age."
}

{
  "title": "He oppose",
  "random_text":
    "He oppose at thrown desire of no. \
      Announcing impression unaffected day his are unreserved indulgence."
}

{
  "title": "Repulsive questions",
  "random_text": "Repulsive questions contented him few extensive supported."
}

{
  "title": "Old education",
  "random_text": "Old education him departure any arranging one prevailed."
}

Bevor wir ein Dokument indizieren können, müssen wir entscheiden, wo es gespeichert werden soll. Es ist möglich, mehrere Indizes zu haben, die wiederum mehrere Typen enthalten. Diese Typen enthalten mehrere Dokumente und jedes Dokument enthält mehrere Felder.

Wir werden unsere Dokumente nach folgendem Schema speichern:

text: Der Indexname. article: Der Typname. id: Die ID dieser speziellen Beispieltexteingabe.

Um ein Dokument hinzuzufügen, führen wir den folgenden Befehl aus:

curl -XPUT 'localhost:9200/text/article/1?pretty'
  -H 'Content-Type: application/json' -d '
{
  "title": "He went",
  "random_text":
    "He went such dare good fact. The small own seven saved man age."
}'

Hier verwenden wirid=1, wir können andere Einträge mit demselben Befehl und derselben inkrementierten ID hinzufügen.

4. Dokumente abrufen

Nachdem wir alle unsere Dokumente hinzugefügt haben, können wir mit dem folgenden Befehl überprüfen, wie viele Dokumente sich im Cluster befinden:

curl -XGET 'http://localhost:9200/_count?pretty' -d '
{
  "query": {
    "match_all": {}
  }
}'

Mit dem folgenden Befehl können wir ein Dokument auch anhand seiner ID abrufen:

curl -XGET 'localhost:9200/text/article/1?pretty'

Und wir sollten die folgende Antwort von der elastischen Suche bekommen:

{
  "_index": "text",
  "_type": "article",
  "_id": "1",
  "_version": 1,
  "found": true,
  "_source": {
    "title": "He went",
    "random_text":
      "He went such dare good fact. The small own seven saved man age."
  }
}

Wie wir sehen können, entspricht diese Antwort dem Eintrag, der mit der ID 1 hinzugefügt wurde.

5. Dokumente abfragen

OK, führen Sie eine Volltextsuche mit dem folgenden Befehl durch:

curl -XGET 'localhost:9200/text/article/_search?pretty'
  -H 'Content-Type: application/json' -d '
{
  "query": {
    "match": {
      "random_text": "him departure"
    }
  }
}'

Und wir bekommen folgendes Ergebnis:

{
  "took": 32,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 1.4513469,
    "hits": [
      {
        "_index": "text",
        "_type": "article",
        "_id": "4",
        "_score": 1.4513469,
        "_source": {
          "title": "Old education",
          "random_text": "Old education him departure any arranging one prevailed."
        }
      },
      {
        "_index": "text",
        "_type": "article",
        "_id": "3",
        "_score": 0.28582606,
        "_source": {
          "title": "Repulsive questions",
          "random_text": "Repulsive questions contented him few extensive supported."
        }
      }
    ]
  }
}

Wie wir sehen können, suchen wir nach“him departure” und erhalten zwei Ergebnisse mit unterschiedlichen Werten. Das erste Ergebnis ist offensichtlich, da der Text die durchgeführte Suche enthält und wir, wie wir sehen können, die Punktzahl1.4513469 haben.

Das zweite Ergebnis wird abgerufen, da das Zieldokument das Wort "er" enthält.

Standardmäßig sortiert ElasticSearch Übereinstimmungsergebnisse nach ihrer Relevanzbewertung, dh danach, wie gut jedes Dokument mit der Abfrage übereinstimmt. Beachten Sie, dass die Punktzahl des zweiten Ergebnisses im Vergleich zum ersten Treffer gering ist, was auf eine geringere Relevanz hinweist.

Fuzzy Matching behandelt zwei Wörter, die sich „unscharf“ ähneln, als ob sie dasselbe Wort wären. Zunächst müssen wir definieren, was wir unter Unschärfe verstehen.

Elasticsearch unterstützt eine maximale Bearbeitungsentfernung, die mit dem Fuzziness-Parameter angegeben wird, von 2. Der Fuzziness-Parameter kann auf AUTO eingestellt werden, wodurch sich die folgenden maximalen Bearbeitungsabstände ergeben:

  • 0 für Zeichenfolgen mit einem oder zwei Zeichen

  • 1 für Zeichenfolgen mit drei, vier oder fünf Zeichen

  • 2 für Zeichenfolgen mit mehr als fünf Zeichen

Möglicherweise stellen Sie fest, dass ein Bearbeitungsabstand von2 Ergebnisse liefert, die nicht in Beziehung zu stehen scheinen.

Mit einer maximalen Unschärfe von 1 erzielen Sie möglicherweise bessere Ergebnisse und eine bessere Leistung. Entfernung bezieht sich auf die Levenshtein-Entfernung, die eine Zeichenfolgenmetrik zum Messen der Differenz zwischen zwei Sequenzen ist. Informell ist dasLevenshtein distance zwischen zwei Wörtern die Mindestanzahl von Einzelzeichenbearbeitungen.

OK, lassen Sie uns unsere Suche mit Unschärfe durchführen:

curl -XGET 'localhost:9200/text/article/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "query":
  {
    "match":
    {
      "random_text":
      {
        "query": "him departure",
        "fuzziness": "2"
      }
    }
  }
}'

Und hier ist das Ergebnis:

{
  "took": 88,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": 1.5834423,
    "hits": [
      {
        "_index": "text",
        "_type": "article",
        "_id": "4",
        "_score": 1.4513469,
        "_source": {
          "title": "Old education",
          "random_text": "Old education him departure any arranging one prevailed."
        }
      },
      {
        "_index": "text",
        "_type": "article",
        "_id": "2",
        "_score": 0.41093433,
        "_source": {
          "title": "He oppose",
          "random_text":
            "He oppose at thrown desire of no.
              \ Announcing impression unaffected day his are unreserved indulgence."
        }
      },
      {
        "_index": "text",
        "_type": "article",
        "_id": "3",
        "_score": 0.2876821,
        "_source": {
          "title": "Repulsive questions",
          "random_text": "Repulsive questions contented him few extensive supported."
        }
      },
      {
        "_index": "text",
        "_type": "article",
        "_id": "1",
        "_score": 0.0,
        "_source": {
          "title": "He went",
          "random_text": "He went such dare good fact. The small own seven saved man age."
        }
      }
    ]
  }
}'

Wie wir sehen können, gibt uns die Unschärfe mehr Ergebnisse.

Wir müssen mit Unschärfe vorsichtig umgehen, da sie dazu neigt, Ergebnisse zu erhalten, die nicht in Beziehung stehen.

7. Fazit

In diesem kurzen Tutorial haben wir uns aufindexing documents and querying Elasticsearch for full-text search, directly via it’s REST API konzentriert.

Natürlich stehen APIs für mehrere Programmiersprachen zur Verfügung, wenn dies erforderlich ist - aber die API ist immer noch recht praktisch und sprachunabhängig.