Herzlich willkommen auf dem Blog der exensio GmbH

exensio ist ein unabhängiges Software-Unternehmen von erfahrenen IT Beratern und Architekten. Zu unseren Kunden zählen namhafte deutsche Großunternehmen.

exensio verbessert das Kommunikations- und Informationsmanagement von Unternehmen. Auf Basis sinnvoller und zweckmäßiger Technologien erarbeiten wir flexible und übergreifende Lösungen für webbasierte Informationssysteme. Abhängig von den Kundenanforderungen realisieren wir Web Applikationen sowie Lösungen auf Basis von Web Content Management- und Portalsystemen. Integrativ, wirtschaftlich und anwenderfreundlich!

Hier gelangen Sie zur exensio GmbH.

Sonntag, 7. Juni 2015

Wie frage ich Elasticsearch mit der Elastic Groovy API in Grails ab?

Es gibt verschiedene Möglichkeiten, Elasticsearch in Grails zu integrieren. Am Besten finde ich die Groovy API von Elasticsearch. Das Ganze wird über folgende Zeilen in der BuildConfig.groovy konfiguriert.

com.spatial4j und com.vividsolutions werden für die Geo Location und Search Funktionalität von Elasticsearch benötigt.

dependencies {
       ...
        compile group: 'org.elasticsearch', name: 'elasticsearch-groovy', version: '1.5.0', classifier: 'grails'
        compile group: 'com.spatial4j', name: 'spatial4j' , version : '0.4.1'
        compile group: 'com.vividsolutions', name: 'jts' , version : '1.13', excludes: 'xerces'
    }

Und folgendes Beispiel zeigt eine Grails Service Methode, die Elasticsearch abfrägt. Hierbei sieht man m.E. sehr schön, wie elegant man die Queries in Groovy definieren und später die Response verarbeiten kann.
package competition

import grails.transaction.Transactional
import org.elasticsearch.action.search.SearchRequestBuilder
import org.elasticsearch.action.search.SearchResponse
import org.elasticsearch.client.Client
import org.elasticsearch.client.transport.TransportClient
import org.elasticsearch.common.settings.ImmutableSettings
import org.elasticsearch.common.settings.Settings
import org.elasticsearch.common.transport.InetSocketTransportAddress
import org.elasticsearch.index.query.QueryBuilders
import org.elasticsearch.search.aggregations.AggregationBuilders

@Transactional
class ElasticGroovyClientInGrailsService {
    static transactional = false

    def query() {

        Client client = getESClient()
        SearchRequestBuilder requestBuilder = client.prepareSearch("weinsuche")

        requestBuilder
                .setQuery(QueryBuilders.matchAllQuery())
                .addFields("shopname", "shopurl", "kategorie", "herkunftsland", "anbauregion", "weingut", "preiseinheit")
                .setSize(15)
                .addAggregation(AggregationBuilders.terms("Händler").field("shopurl"))
                .addAggregation(AggregationBuilders.terms("Kategorie").field("kategorie_raw"))
                .addAggregation(AggregationBuilders.terms("Land").field("herkunftsland_raw"))
                .addAggregation(AggregationBuilders.terms("Anbauregion").field("anbauregion_raw"))
                .addAggregation(AggregationBuilders.terms("Weingut").field("weingut_raw"))
                .addAggregation(AggregationBuilders.range("Preis").field("preiseinheit")
                .addUnboundedTo(10.0f)
                .addRange(10.0f, 15.0f)
                .addRange(15.0f, 20.0f)
                .addRange(20.0f, 30.0f)
                .addRange(30.0f, 50.0f)
                .addRange(50.0f, 100.0f)
                .addUnboundedFrom(100.0f)
        )

        SearchResponse response = requestBuilder.execute().actionGet()
        printResponse(response)

        client.close()

        return response
    }

    private printResponse(SearchResponse response) {
        response.getHits().getHits().each { searchHit ->
            println searchHit.fields.shopname?.value
            println searchHit.fields.shopurl?.value
            println searchHit.fields.kategorie?.value
            println searchHit.fields.herkunftsland?.value
            println searchHit.fields.anbauregion?.value
            println searchHit.fields.weingut?.value
            println searchHit.fields.preiseinheit?.value
        }
    }

    private getESClient() {
        Client retVal
        // clustername is defined in the elastic file elasticsearch.yml
        Settings settings = ImmutableSettings.settingsBuilder().put("cluster.name", "---ClusterName---").build()
        TransportClient transportClient = new TransportClient(settings)
        retVal = transportClient.addTransportAddress(new InetSocketTransportAddress("localhost", 9300))
        return retVal
    }
}

Kommentare:

  1. Hallo Peter, danke für den informativen Post. Ich versuche es gerade mit Grails 3.1.1 nachzubauen und scheitere leider am Groovy Client. Ich habe ihn mit compile "org.elasticsearch:elasticsearch-groovy:2.1.2" im build.gradle hinzugefügt. Leider bekomme ich immer einen Fehler Unable to load class org.elasticsearch.groovy.action.fieldstats.FieldStatsRequestExtensions due to missing dependency beim Start. Hast Du einen Tipp für mich?

    Viele Grüße

    Robert

    AntwortenLöschen
  2. Hallo Robert,

    leider habe ich keine Erfahrung mit dem Elasticsearch Groovy Client unter Grails 3.1.x.

    Danke und Grüße
    Peter

    AntwortenLöschen