我在我的项目中使用 Java spring 和 MongoDB 存储库。
这是 DTO 定义:
@Document(collection = "Info")
public class Info {
String id,
Integer count,
String type
…
}
我需要从查询中返回 ID 列表,其中计数字段不为零且类型字段具有“二进制”文本。
这是我尝试实现它的方法:
@Query(value="{ 'count' : 0, 'type' : 'binary' }", fields="{ 'id' : 1 }")
List<String> getInfo();
我从上面的查询得到这个结果:
0={"_id": {"$oid": "5eb97a8139d4c62be4d90e4c"}}
1={"_id": {"$oid": "3ec97a8127d4c60cb4d90e9e"}}
我期待这个结果:
{"5eb97a8139d4c62be4d90e4c", "3ec97a8127d4c60cb4d90e9e"}
正如你所看到的,我希望从上面的查询中获得 id 字符串列表。
知道我应该在上面的查询中更改什么才能获得预期的 ids 结果列表吗?
不,那是不可能的。
原因:MongoDB只能返回JSON文档。您可以包含您想要的字段。
您可以遵循此建议:
DTO定义:
@Document(collection = "Info")
public class Info {
@Id
private String id;
private Integer count;
private String type;
// other fields and getters and setters
}
示例存储库:
public interface InfoRepository extends MongoRepository<Info, String> {
@Query(value="{ 'count' : 0, 'type' : 'binary' }", fields="{ 'id' : 1 }")
List<Info> getInfo();
}
服务类别示例:
@Service
public class InfoService {
@Autowired
private InfoRepository infoRepository;
public List<String> getIds() {
return infoRepository.getInfo()
.stream()
.map(Info::getId)
.collect(Collectors.toList());
}
}
返回的
{"$oid": "5eb97a8139d4c62be4d90e4c"}
是 ObjectID 的 MongoDB 扩展 JSON 表示形式。
它不返回字符串,因为数据库中存储的字段是
ObjectID
类型,而不是 String
类型。
如果您希望它返回一个字符串,您应该使用带有 $toString 运算符的聚合来转换它。
你能得到的最好结果是一个带有数组字段的文档,其中包含找到的 ID,如下所示:
{
"ids" : [
"606018909fb6351e4c34f964",
"606018909fb6351e4c34f965"
]
}
这可以通过像这样的聚合查询来实现:
db.Info.aggregate([
{
$match: {
count: 0,
type: "binary"
}
},
{
$project: { _id: { $toString: "$_id" } }
},
{
$group: {
_id: null,
ids: { $push: "$_id" }
}
},
{
$project: { _id: 0 }
}
])
我有2条建议。
1。您可以使用 JPA 查询代替命名查询
public interface InfoRepository extends MongoRepository<Info, String> {
List<Info> findByCountAndType(final Integer count, final String type);
}
2。在业务逻辑中使用 java Stream api 从上面的结果中收集所有 id 作为 List。
public class InfoServiceImpl {
@Autowired
private InfoRepository repository;
public String getIds(final String type, final Integer count) {
return repository.findByCountAndType(count, type)
.stream()
.map(Info::getId)
.collect(Collectors.toList());
}
有可能
@Aggregation(pipeline = {"{$match: {}} " +
"{$project: { _id: { $toString: $_id } }} " +
"{$group: {_id: null, ids: { $push: $_id }}} " +
"{$project: { _id: 1 }}"})
List<String> getInfo();