使用 Hibernate 搜索按 SortField.Type.LONG 排序

Sorting by SortField.Type.LONG with Hibernate search

我正在为我的 webapp 创建一个搜索页面,我需要能够 select 我想按排序方向对字段进行排序。像这样:

它看起来很简单,但我无法让它工作。

如果我将 id 设置为 属性,我会收到以下错误:

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'.

即使我的领域是:

@Id
@GeneratedValue
@SortableField
private Long id;

您知道为什么我的“id”字段在 Hibernate 搜索索引中是一个字符串吗?我该如何更改它?

编辑:

我的第二个问题是什么时候我想按相关性排序。通常你只需使用 SortField.FIELD_SCORE 作为你的 SortField 并且它会按分数排序。但是我想设置排序的方向。所以我查看了反编译的 SortField class 并找到了定义 FIELD_SCORE 的位置。看起来像这样:

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

解决方案是使用:

fullTextQuery.setSort(new Sort(new SortField(SortField.FIELD_SCORE.getField(),SortField.Type.SCORE,true)));

字段 id 必须由 Hibernate Search 保留,并且必须是字符串类型。

我将字段定义更改为:

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

我按字段 identifier 而不是 id 排序并且它有效。

首先,您不能直接按 ID 排序。 ID在内部始终为字符串类型,因此对该字段进行排序将导致意外结果。

您需要定义一个单独的字段,使该字段可排序,并根据该字段而不是 id 进行排序:

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

其次...帮自己一个忙,使用 Sort DSL。它应该早点发现这样的问题,让各种更容易写。

对于按字段值排序:

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();

对于按反向相关性排序(分数升序):

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();

更多信息见this section of the documentation

但是请注意,最不相关的点击可能完全没有用,因此将它们放在结果列表的第一位是非常可疑的...