jhipster – configure elasticsearch analyzer for a field

jhipster-elastic

We have an Entity with an Enum field. This enum field gets saved in the database as string.

enum

public enum TipoContrato {
    ADJUDICACION_DIRECTA,  INVITACION_RESTRINGIDA,  LICITACION_PUBLICA
}

entity

@Entity
@Table(name = "contrato")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Document(indexName = "contrato")
public class Contrato implements Serializable {

    ...

    @Enumerated(EnumType.STRING)
    @Column(name = "tipo")
    private TipoContrato tipo;

the thing is, it includes underscore. Elasticsearch by default uses the standard analyzer which stores it and searches for it as one word. So, i.e. searching for ‘directa’ would not produce any results, but searching for ‘adjudicacion_directa’ would.

First you should enable http access to elasticsearch on your jhipster project to test if you’re getting results with a simple request, i.e using curl

curl -XPOST 'localhost:9200/contrato/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "query": {
    "bool" : {
      "should" : [
        { "match" : { "tipo" : "directa" } }
      ]
    }             
  }                                         
}
'

to get the results we’re expecting we need to change the analyzer that’s being used to index the field. We do this by changing the mapping. You could change it by using the REST api, and then reindexing your data. In development, we can reconfigure our mapping and then just do a mvn clean to regenerate it all.

Let’s change the mapping in our entity (we just need to add an annotation).

    @Enumerated(EnumType.STRING)
    @Column(name = "tipo")
    @Field(type = FieldType.String, analyzer = "simple")
    private TipoContrato tipo;

now, the results that came back from the curl request were fine. But the results from the search box didn’t. We had to include a custom search for it to work, cause the more general search doesn’t do a full text search apparently i.e. if you open in a new tab the url http://localhost:9200/contrato/_search?q=directa it doesn’t work but if you include the field it works http://localhost:9200/contrato/_search?q=tipo:directa

public interface ContratoSearchRepository extends ElasticsearchRepository<Contrato, Long> {

    @Query("{\n" +
        "  \"query\": {\n" +
        "    \"bool\" : {\n" +
        "      \"should\" : [\n" +
        "        { \"match\" : { \"_all\" : \"?0\" } },\n" +
        "        { \"match\" : { \"tipo\" : \"?0\" } }\n" +
        "      ]\n" +
        "    }             \n" +
        "  }                                         \n" +
        "}")
    Page<Contrato> buscarContrato(String query, Pageable page);

}

sources:
http://www.baeldung.com/spring-data-elasticsearch-tutorial
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html
https://stackoverflow.com/questions/31837546/elasticsearch-splitting-words-on-underscore-search-founds-nothing
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html
https://docs.spring.io/spring-data/elasticsearch/docs/3.0.2.RELEASE/api/

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s