· 6 min read

Ruby on Rails Volltextsuche mit ElasticSearch und Tire

Installation

OS X Unter OS X kann man sich die aktuelle Version via homebrew [tooltip title=“Help” content=“Homebrew ist ein OpenSource Paketmanager für OS X” type=“info”](?)[/tooltip] installieren: [caption id=“attachment_3645” align=“aligncenter” width=“616”]Bash Screenshot von der Installation auf OSX[/caption] Debian / Ubuntu Eine Installationsanleitung für Debian basierte Systeme befindet sich direkt auf elasticsearch.org: http://www.elasticsearch.org/tutorials/2010/07/02/setting-up-elasticsearch-on-debian.html

RedHat / CentOS … Für RedHat basierte Systeme hat Tavisto (https://github.com/tavisto/elasticsearch-rpms) entsprechende SPEC-Files für die ElasticSearch RPM Erstellung bereitgestellt.

andere Systeme Alternativ kann die aktuelle Version hier heruntergeladen und installiert werden: http://www.elasticsearch.org/download/

Nach der Installation und dem Start des Services sollte der ElasticSearch Server erreichbar sein. Der ElasticSearch Server liefert den Status, seine Versionsnummer und weitere Zusatzinformationen als JSON zurück: [caption id=“attachment_3644” align=“aligncenter” width=“589”]JSON-Dokument mit Installationsdetails[/caption]

Zustand der ElasticSearch überwachen

Für einen späteren produktiven Einsatz der ElasticSearch sollte das Monitoring nicht außer Acht gelassen werden. Hierbei haben sich verschiedene Monitoring-Tools bewährt:

  • Elasticsearch-head mobz.github.com/elasticsearch-head Elasticsearch-head ist eine statische Webseite mit JavaScript. Hilft die Performance der einzelnen Shards [tooltip title=“Help” content=“engl. für Scherben” type=“info”](?)[/tooltip] zu überwachen. Man kann sich direkt ähnlich wie bei PHPMyAdmin oder Futon(CouchDB) direkt die Daten anzeigen lassen.
  • Kibana github.com/rashidkpc/Kibana Kibana ist eine eigene Rails-Anwendung und sehr benutzerfreundlich. Manuelles Suchen, komplette Visualisierungen und Analysen z.B. auf Basis der Logs können konfiguriert und dargestellt werden.
  • Bigdesk github.com/lukas-vlcek/bigdesk Bigdesk eignet sich gut für das Monitoring der Hauptparameter des ElasticSearch Servers (Speicher, CPU, …).

ElasticSearch Funktionsweise / Daten speichern

Angenommen wir möchten eine Suche für einen Blog anlegen. Der Blog besteht aus mehreren Artikeln. Jeder Artikel enthält einen Text, eine Überschrift, ein Datum, sowie einen User. Da ElasticSearch eine RESTful-HTTP Schnittstelle bereitstellt, können wir mit Hilfe von z.B. curl [tooltip title=“Help” content=“Curl ist ein Kommandozeilen-Programm zum Übertragen von Dateien im Netzwerk” type=“info”](?)[/tooltip] alle Artikeldatensätze im JSON-Format an die ElasticSearch übergeben. Im nachfolgenden Beispiel übermitteln wir zwei Artikel, samt Inhalt an die ElasticSearch. [ruby] curl -XPUT ‘http://localhost:9200/artikel/text/1’ -d ’{ “user” : “Alex”, “post_date” : “2012-10-05T14:12:12”, “ueberschrift” : “Alles wird schlechter”, “text” : “Hamburg - Immer mehr Arbeitnehmer in Deutschland haben zwei Jobs…”}’ curl -XPUT ‘http://localhost:9200/artikel/text/2’ -d ’{ “user” : “Alex”, “post_date” : “2012-10-04T14:12:12”, “ueberschrift” : “96 gewinnt”, “text” : “Hannover 96 - Der neue große HSV von 1896 schlägt Levante daheim in Unterzahl 2:1”}’ [/ruby]

Jeder einzelne Request wird bestätigt: [ruby] {“ok”:true,“_index”:“artikel”,“_type”:“text”,“_id”:“1”,“_version”:1} [/ruby]

Wir sehen, dass der Index automatisch von der ElasticSearch erstellt wird, falls dieser noch nicht existiert. In unserem Fall heißt der Index “artikel”. Jeder Index besteht aus mehreren sogenannten Shards[tooltip title=“Help” content=“engl. für Scherbe” type=“info”](?)[/tooltip]. Diese wiederum werden automatisch über die einzelnen Nodes (Server), falls vorhanden, verteilt. Standardmäßig hat jeder Index fünf primäre Shards (0-4). Die Anzahl der primären Shards können nach Erstellung des Index nicht mehr geändert werden. Jede Shard kann null oder mehr Replica-Shards haben. Ein Replica-Shard ist eine Kopie einer primären Shard. Die Anzahl der Replica-Shards kann zur Laufzeit dynamisch geändert werden. Die Hauptaufgabe der Replica-Shards sind das Failover Verhalten zu verbessern, falls die primäre Shard nicht mehr zur Verfügung steht und die Performance der Elasticsearch bei Get- und Search-Requests zu verbessern.

[caption id=“attachment_3642” align=“aligncenter” width=“446”]Architektur im Clusterverbund[/caption] Möchte man andere Parameter bei der Indexerstellung setzen, hilft einem die Reference Guide weiter (elasticsearch.org/guide/reference/api/admin-indices-create-index.html). Die ElasticSearch arbeitet mit Versionierung. D.h. laden wir unseren ersten Artikel erneut, z.B. mit korrigiertem Text hoch, so erhalten wir nachfolgende Artwort: [ruby] {“ok”:true,“_index”:“artikel”,“_type”:“text”,“_id”:“1”,“_version”:2} [/ruby] Anders als z.B. bei CouchDB oder anderen NoSQL-Datenbanken hat man bei ElasticSearch keinen Zugriff mehr auf eine ältere Version eines Dokuments.

ElasticSearch gespeicherte Daten ausgeben

Wir können uns, wie bei einer RESTful NoSQL-Datenbank zum Beispiel CouchDB, einen Eintrag zurückgeben lassen: [ruby] curl -XGET ‘http://localhost:9200/artikel/text/1’ { “_index” : “artikel”, “_type” : “text”, “_id” : “1”, “_version” : 1, “exists” : true, “_source” : { “user” : “Alex”, “post_date” : “2012-10-05T14:12:12”, “ueberschrift” : “Alles wird schlechter”, “text” : “Hamburg - Immer mehr Arbeitnehmer in Deutschland haben zwei Jobs…“} } [/ruby]

Datensätze suchen

Ausführliche Informationen findet man unter dem Stichwort Query-DSL sowie Search-API der Reference Guide. An dieser Stelle möchte ich lediglich beispielhaft alle Datensätze des Users Alex finden: [ruby] curl -XGET ‘http://localhost:9200/artikel/\_search?q=user:Alex’ { “took” : 1, “timed_out” : false, “_shards” : { “total” : 5, “successful” : 5, “failed” : 0 }, “hits” : { “total” : 2, “max_score” : 1.0, “hits” : [ { “_index” : “artikel”, “_type” : “text”, “_id” : “1”, “_score” : 1.0, “_source” : { “user” : “Alex”, “post_date” : “2012-10-05T14:12:12”, “ueberschrift” : “Alles wird schlechter”, “text” : “Hamburg - Immer mehr Arbeitnehmer in Deutschland haben zwei Jobs…“} }, { “_index” : “artikel”, “_type” : “text”, “_id” : “2”, “_score” : 1.0, “_source” : { “user” : “Alex”, “post_date” : “2012-10-04T14:12:12”, “ueberschrift” : “96 gewinnt”, “text” : “Hannover 96 - Der neue große HSV von 1896 schlägt Levante daheim in Unterzahl 2:1”} } ] } } [/ruby]

ElasticSearch in Ruby on Rails Anwendungen mit dem Gem Tire einbinden

Wir clonen uns nachfolgende Rails-Anwendung und initialisieren diese: [ruby] git clone https://github.com/agilastic/blog-search-with-tire-and-elasticsearch [/ruby] [ruby] cd blog-search-with-tire-and-elasticsearch bundle install bundle exec rake db:setup [/ruby] Die “blog-search-with-tire-and-elasticsearch”-Railsanwendung ist sehr überschaubar gehalten. Via Scaffolding haben wir “Article” erzeugt. [ruby] rails generate scaffold Article author:string, content:text, tag:string, published_at:date, title:string [/ruby]

Durchsucht werden sollen die Inhalte unseres Models “Article”. Hierzu muss das Model “Article” angepasst werden. Um Tire einzubinden müssen im “Article”-Model zwei Module eingebunden werden. Das erste Modul dient zur Einstellung der Suche und der Indizierung. Das zweite Modul kümmert sich um die Callbacks und führt die automatische Updates des Index bei jede Änderung des Artikels aus. Außerdem muss ein Block für das Mapping definiert werden. Des Weiteren passen wir die search-Methode etwas an. [ruby] class Article < ActiveRecord::Base include Tire::Model::Search include Tire::Model::Callbacks attr_accessible :author, :tag, :content, :published_at, :title

mapping do indexes :id, :index => :not_analyzed indexes :title, :analyzer => ‘snowball’, :boost => 100 indexes :content, :analyzer => ‘snowball’ indexes :author, :analyzer => ‘keyword’ indexes :tag, :analyzer => ‘keyword’ indexes :published_at, :type => ‘date’, :include_in_all => false end

def self.search(params) tire.search(load: true) do query {string params[:query]} if params[:query].present? end end end [/ruby]

Wer sich wundert was der “Snowball-Analyzer” ist, kann sich auf der Projekt-Webseite genauer informieren snowball.tartarus.org/texts/introduction.html Der Schneeball Analyzer kommt von Lucene und wurde ursprünglich in einem Projekt von snowball.tartarus.org entwickelt.

Das Suchformular in der articles#index-View wird angelegt: [ruby]

[/ruby] Abschließend können Suchanfragen im Google-Stil durchgeführt werden: [caption id=“attachment_3643” align=“aligncenter” width=“589”]Browserscreenshot mit Auflistung der Artikel[/caption]

Sollten bereits mehrere Artikel vor der Integration von Tire im Blog vorhanden sein oder der ElasticSearch-”Artikel”-Index korrupt sein, so kann dieser neu angelegt und reindeziert werden. Dazu kann beispielsweise der nachfolgende Raketask genutzt werden: [ruby] rake elasticsearch:recreate_index [/ruby]

[ruby] namespace :elasticsearch do task :recreate_index => :environment do @data_tables = ActiveRecord::Base.connection.tables @data_tables.delete(“schema_migrations”) @data_tables.each do |single_table| model = single_table.capitalize.singularize.constantize model.all.each do |a| a.tire.update_index end end end [/ruby]

Viel Spaß beim Ausprobieren :)

Gastbeitrag von: Alexander Ebeling-Hoppe Alexander Ebeling-Hoppe arbeitet bei der Zentralen Polizeidirektion Niedersachsen als Ruby on Rails, sowie als freiberuflicher Webentwickler (agilastic.de) und Lehrbeauftragter.

Werbung in eigener Sache:

Ich bieten Ihnen eine viertägige Ruby on Rails Grundlagenschulung bei der VHS Hannover (Büssingweg 9, 30165 Hannover) an:

27./28.10.2012, 09:00 Uhr – 16:00 Uhr (Sa/So) 03./04.11.2012, 09:00 Uhr – 16:00 Uhr (Sa/So) Kursnummer: 54079D8 Gebühr: 156,40 € (regulär) Schüler, Studenten, Azubis etc. 113,20 €

Weitere Details: VHS on RAILS

    Share:
    Back to Blog

    Related Posts

    View All Posts »

    Leichte Einführung in mruby

    Ruby 3.3.5 wurde veröffentlicht. Das Update behebt kleinere Fehler und wird allen Nutzern empfohlen. Weitere Details sind in den GitHub Release Notes verfügbar.

    Ruby on Rails World 2024

    Rails 8 verfolgt einen radikal vereinfachten Ansatz, um die Komplexität moderner Webentwicklung zu reduzieren. Mit dem \#NOBUILD-Prinzip werden CSS und JavaScript ohne Build-Prozesse direkt an den Browser geliefert. Die neuen Technologien Propshaft, Solid Cable und Solid Queue ermöglichen performante Lösungen ohne den Einsatz externer Dienste. Rails will damit die Abhängigkeit von teuren PaaS-Diensten minimieren und setzt auf offene, kostengünstige Alternativen für die Bereitstellung auf eigener Hardware. Gleichzeitig werden leistungsfähige Tools wie Thruster und Kamal 2 eingeführt, die Deployment-Prozesse weiter optimieren. Rails 8 kombiniert bewährte Prinzipien mit innovativen Features, um Entwicklern maximale Flexibilität und Effizienz zu bieten.

    Ruby 3.3.5 Released

    Ruby 3.3.5 wurde veröffentlicht. Das Update behebt kleinere Fehler und wird allen Nutzern empfohlen. Weitere Details sind in den GitHub Release Notes verfügbar.