Estoy creando una página de búsqueda para mi aplicación web y necesito poder seleccionar el campo que deseo ordenar en la dirección de la clasificación. Al igual que :

enter image description here

Parece simple pero no puedo hacerlo funcionar.

Si configuro id como propiedad, aparece el siguiente error:

fullTextQuery.setSort(new Sort(new SortField("id",SortField.Type.LONG,true)));
org.hibernate.search.exception.SearchException: HSEARCH000307: Sort type LONG is not compatible with string type of field 'id'.

Aunque mi campo es:

@Id
@GeneratedValue
@SortableField
private Long id;

¿Tiene alguna idea de por qué mi campo "id" es una cadena en el índice de búsqueda de Hibernate y cómo lo cambio?

EDITAR:

Mi segundo problema es cuándo fue cuando quería ordenar por relevancia. Normalmente solo usarías SortField.FIELD_SCORE como tu SortField y se ordenará por puntaje. Pero quiero establecer la dirección del tipo. Entonces busqué en la clase descompilada SortField y encontré dónde se define FIELD_SCORE. Y se ve así:

static {
    FIELD_SCORE = new SortField((String)null, SortField.Type.SCORE);
    FIELD_DOC = new SortField((String)null, SortField.Type.DOC);
    ...
}

La solución es usar:

fullTextQuery.setSort(new Sort(new SortField(SortField.FIELD_SCORE.getField(),SortField.Type.SCORE,true)));
0
Servietsky 24 jun. 2020 a las 10:40

2 respuestas

La mejor respuesta

Primero, no puede ordenar la ID directamente. La ID siempre es de tipo cadena interna, por lo que ordenar en ese campo dará como resultado resultados inesperados.

Debe definir un campo separado, hacer que ese campo se pueda ordenar y ordenar en ese campo en lugar de la identificación:

@Id
@Field(name = "id_sort", index = Index.NO)
@SortableField(forField = "id_sort")
private Long id;

Segundo ... hazte un favor y usa el DSL de clasificación. Debería detectar estos problemas temprano, y hace que todo tipo de clases sea más fácil de escribir.

Para ordenar por valor de campo:

QueryBuilder builder = fullTextSession.getSearchFactory()
    .buildQueryBuilder().forEntity(Book.class).get();
Query luceneQuery = /* ... */;
FullTextQuery query = s.createFullTextQuery( luceneQuery, Book.class );
Sort sort = builder.sort().byField("id_sort").asc().createSort();
query.setSort(sort);
List results = query.list();

Y para un orden por relevancia inversa (puntaje ascendente):

QueryBuilder builder = fullTextSession.getSearchFactory()
    .buildQueryBuilder().forEntity(Book.class).get();
Query luceneQuery = /* ... */;
FullTextQuery query = s.createFullTextQuery( luceneQuery, Book.class );
Sort sort = builder.sort().byScore().asc().createSort();
query.setSort(sort);
List results = query.list();

Más información en esta sección de la documentación.

Sin embargo, tenga en cuenta que es probable que los resultados menos relevantes sean completamente inútiles, por lo que ponerlos primero en su lista de resultados es muy dudoso ...

1
yrodiere 24 jun. 2020 a las 08:22

El campo id debe estar reservado por Hibernate Search y debe ser de tipo cadena.

Cambié mi definición de campo a:

@Id
@GeneratedValue
@Field(name = "identifier", analyze = Analyze.NO, store = Store.NO, index = Index.YES)
@SortableField(forField = "identifier")
private Long id;

Y ordeno por campo identifier en lugar de id y funciona.

0
Servietsky 24 jun. 2020 a las 08:28