使用ResultTransformer(DTO)进行休眠搜索

问题描述 投票:0回答:1

我需要从Hibernate搜索结果中收集特定的DTO,我连接了Maven中的所有依赖项,并根据官方文档编写了以下请求(我删除了不必要的代码,这只会造成混淆,只留下了需要的内容搜索):

public List<QuestionDto> search(String text) {

    FullTextQuery query = fullTextEntityManager.createFullTextQuery(queryBuilder
            .simpleQueryString()
            .onField("description")
            .matching(text)
            .createQuery())
            .setProjection("id", "description", "title", "countValuable", "persistDateTime", "user.fullName", "tags")
            .setResultTransformer(new ResultTransformer() {

                @Override
                public Object transformTuple(Object[] tuple, String[] aliases) {
                    return QuestionDto.builder()
                            .id(((Number) tuple[0]).longValue())
                            .title((String) tuple[2])
                            .description((String) tuple[1])
                            .countValuable(((Number) tuple[3]).intValue())
                            .persistDateTime((LocalDateTime) tuple[4])
                            .username((String) tuple[5])
                            .tags((List<TagDto>) tuple[6])
                            .build();
                }

                @Override
                public List transformList(List collection) {
                    return collection;
                }
            });
    return query.getResultList();
}

但由于某种原因而不是标记,所以标记为NULL可能有人知道吗?

实体问题

@Indexed
public class Question {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Field(store = Store.YES)
private String title;

private Integer viewCount = 0;

@Field(store = Store.YES)
private String description;

@Field(store = Store.YES)
private LocalDateTime persistDateTime;

@Field(store = Store.YES)
private Integer countValuable = 0;

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@IndexedEmbedded(includePaths = "fullName")
private User user;

@ManyToMany(fetch = FetchType.LAZY)
@IndexedEmbedded(includeEmbeddedObjectId = true, includePaths = {"name", "description"})
private List<Tag> tags;

实体标签

public class Tag {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Field(store = Store.YES)
private String name;

@Field(store = Store.YES)
private String description;
private LocalDateTime persistDateTime;

@ManyToMany(mappedBy = "tags", fetch = FetchType.LAZY)
@ContainedIn
private List<Question> questions;
java spring hibernate hibernate-search
1个回答
0
投票

这里有两个问题:

  1. 不支持在多值字段上的投影。
  2. 您正在尝试在“对象”字段上进行投影:“标签”本身并不具有值,它仅具有子字段(“ tags.name”,“ tags.description”)。目前不支持“对象”字段上的投影。

如果使用的是Elasticsearch后端,则可以利用_source投影(org.hibernate.search.elasticsearch.ElasticsearchProjectionConstants#SOURCE),它将返回Elasticsearch文档的字符串表示形式,格式为JSON。然后,您可以解析它(例如,使用Gson)以提取所需的任何信息。

当然,您始终可以选择完全不使用投影,然后从数据库加载的实体中提取信息。

[请注意,在Hibernate Search 6(当前为Beta)中,我们将添加对projections on multi-valued fields的内置支持,但不太可能将其添加到处于维护模式的Hibernate Search 5中(没有新功能或改进,仅修正错误)。

在更遥远的将来,我们可能会添加more direct support for DTOs

© www.soinside.com 2019 - 2024. All rights reserved.