mongodb - 在 Spring Data MongoDB 中按内部数组进行聚合和排序
问题描述
我对 mongoDB 很陌生。请多多包涵。
我有一个名为 Users 的集合,其中包含角色列表。一个用户可以有多个角色,因此角色被列在一个数组中。我想按用户的角色名称对用户进行排序。
用户结构如下所示,
{
"_id": ObjectId("5bc910a39e53b62c7d4c4e62"),
"_class": "User",
"userName": "John",
"fullName": "Doe",
"roles": [
DBRef("roles",
ObjectId("5d5cf8ceb3773255b54d18c6")),
DBRef("roles",
ObjectId("5d5cf8ceb3773255b54d18c7"))
]
}
课程
@Document(collection = "users")
public class User {
@Id
private String id;
private String username;
private String fullName;
private boolean active;
@DBRef
private List<Role> roles;
//constructor, getter, setter
}
@Document(collection = "roles")
public class Role {
@Id
private String id;
private String name;
//constructor, getter, setter
}
我尝试了以下方法,
Criteria criteria = new Criteria();
setCriteriaReadOnlyIsNullOrReadOnlyIsFalse(criteria);
criteria.andOperator(Criteria.where("<condition>").is(<"condition_data">));
AggregationOperation userMatch = Aggregation.match(criteria);
LookupOperation lookupOperation = LookupOperation.newLookup()
.from("roles")
.localField("roles.id")
.foreignField("id")
.as("rolesAgg");
AggregationOperation sort = Aggregation.sort(Sort.Direction.DESC, "rolesAgg.name");
AggregationOperation project = Aggregation.project("id", "userName", "fullName","roles");
TypedAggregation<User> aggregation = newAggregation(User.class, userMatch, lookupOperation, sort, project);
return mongoOperations.aggregate(aggregation, User.class).getMappedResults();
这会产生结果,但无法排序,因为rolesAgg是一个对象数组。这就是每个用户的rolesAgg 显示方式。
"rolesAgg": [
{
"_id": ObjectId("5d5cf8ceb3773255b54d18c3"),
"name": "Super Admin"
},
{
"_id": ObjectId("5d5cf8ceb3773255b54d18c5"),
"name": "Customer Service"
},
{
"_id": ObjectId("5d5cf8ceb3773255b54d18c4"),
"name": "Admin"
}
]
有没有办法将rolesAgg.name提取到一个数组中并使用它进行排序?我被困住了。提前感谢您帮助我。
解决方案
当对象在数组内时,您无法排序。
[
{
"$unwind": "$rolesAgg"
},
{
"$sort": {
"rolesAgg.name": -1
}
},
{
$group: {
_id: "$_id",
username: {
"$first": "$username"
},
"fullname": {
"$first": "$fullname"
},
rolesAgg: {
$push: "$rolesAgg"
}
}
}
]
所以你需要做
展平阵列
Aggregation.unwind("$rolesAgg")
按名称排序
Aggregation.sort(Sort.Direction.DESC, "rolesAgg.name")
全部归组
Aggregation.group("_id)
.first("username").as("username")
.first("fullname").as("fullname")
.push("rolesAgg").as("rolesAgg")
分别。
注意:如果分组时有更多字段,也可以考虑
工作Mongo游乐场
推荐阅读
- html - 通过 Bootstrap Nav Pill 实现 CSS3 按钮擦除效果
- javascript - 使用 javascript 切换 CSS 隐藏表格行
- ruby-on-rails - Ruby on Rails RSpec 测试模型以仅允许数据库中的一条记录
- amazon-web-services - 1亿个文件的跨账户S3副本
- python - 如何将输出文件保存在新文件夹中?现在这些存储在根目录中。指导我保存在特定位置,我想给出文件名
- mysql - 查询动态列表时 GROUP_CONCAT 中的 COUNT 不起作用
- python - 为什么我的功能部分做它应该做的事情?
- javascript - 如何减慢滚动到最高速度?
- emeditor - 如何让用户编辑器等到用户输入窗口关闭
- odoo - 基于用户组的单个按钮上的不同方法?奥多 12