对 Spring Data Mongo 存储库提供限制

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

使用最新的Spring Data Mongo(撰写本文时为2.1.1),如何指定获取“自定义”查询方法的第一条记录?这是一个例子:

@Query(value="{name: ?0, approval: {'$ne': null}}",
        sort="{'approval.approvedDate': -1}",
        fields = "{ _id: 1 }")
List<Item> getLatestApprovedIdByName(String name, Pageable pageable);

/**
 * Finds the id of the most recently approved document with the given name.
 */
default Item getLatestApprovedIdByName(String name) {
    return getLatestApprovedIdByName(name, PageRequest.of(0, 1)).stream()
                                                                .findFirst()
                                                                .orElse(null);
}

理想情况下,我可以仅使用

String
参数来注释 getLatestApprvedIdByName。

org.springframework.data.mongodb.repository.Query
注释上似乎没有限制字段。

这看起来很奇怪,因为我可以模拟命名方法所做的一切,除了

findFirst

没有

Pageable
,我得到
IncorrectResultSizeDataAccessException
,并且返回
List
是不可接受的,因为我不想浪费时间返回任意大的结果,加上需要处理 0 或 0 的可能性的复杂代码1 件。

java mongodb mongodb-query spring-data spring-data-mongodb
2个回答
11
投票

因为您的查询返回多个文档,所以无法使其直接返回单个

Item

使用
Stream

// Repository
@Query(value="{name: ?0, approval: {'$ne': null}}",
        sort="{'approval.approvedDate': -1}",
        fields = "{ _id: 1 }")
Stream<Item> getLatestApprovedIdByName(String name);

// Service
default Item getLatestApprovedIdByName(String name) {
    return getLatestApprovedIdByName(name).stream().findFirst().orElse(null);
}

由于

Stream
的工作方式,您将仅获取第一个查询结果而不是整个结果集。有关更多信息,请参阅文档

使用
Page
Pageable

// Repository
@Query(value = "{name: ?0, approval: {'$ne': null}}", fields = "{ _id: 1 }")
Page<Item> getLatestApprovedIdByName(String name, Pageable pageable);

// Service
default Item getLatestApprovedIdByName(String name) {
    PageRequest request = new PageRequest(0, 1, new Sort(Sort.Direction.DESC, "approval.approvedDate"));
    return getLatestApprovedIdByName(name, request).getContent().get(0);
}

通过使用

PageRequest
,您可以指定想要的结果数量以及排序顺序。基于这个答案


0
投票

因为我也有同样的问题;我确实发现 @Aggregation 是一个更有用、更干净的解决方案 你可以这样做:

@Aggregation({
    "{$match: { name: ?0, approval: {$ne: null} }",
    "{$sort: { _id: 1 } }",
    "{$limit: 1 }"
})
Optional<Item> getLatestApprovedIdByName(String name);
© www.soinside.com 2019 - 2024. All rights reserved.