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

von Peter Soth

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
    }
}

Kategorien: ElasticsearchGrailsGroovy

Zurück