$ group无法使用Spring聚合类后的$ sort管道

时间:2017-12-15 14:26:44

标签: spring mongodb aggregation-framework

我有一个User集合,如下所示:

User :{
    "_id" : ObjectId("59f6dc660a975a3e3290ea01"),
    "basicInfo" : {
        "name" : "xxxx",
        "age"  : 27,
        "gender" : "Male"
    }
    "otherInfo" {
        "projects" : [
            {
                "_id" : ObjectId("59f6f9230a975a67cc7d7638"),
                "name" : "Test Project",
                "projectImage" : "images/project/59f6f9230a975a67cc7d7638.jpg",
                "desc" : "This is a testing project",
                "status" : "Active",
                "verifyDet" : {
                    "method" : "Admin",
                    "status" : "PENDING",
                    "isVerified" : false
                }
            },
            {
                "_id" : ObjectId("59f6f9230a975a67cc7d5556"),
                "name" : "Test Project Two",
                "projectImage" : "images/project/59f6f9230a975a67cc7d5556.jpg",
                "desc" : "This is a testing project",
                "status" : "Closed",
                "verifyDet" : {
                    "method" : "Admin",
                    "status" : "APPROVED",
                    "isVerified" : true
                }
            }           
        ]
    }
 }

注意:一个用户可以成为多个项目的一部分。但他需要得到Admin的批准才能参与项目活动。验证由verifyDet管理,项目由项目数组管理。

实际要求是以这样的方式显示成员列表:具有待验证成员的成员按字母顺序排在最前面,然后按字母顺序向管理员批准/验证成员。

当我在mongo shell上运行以下查询时,我得到了一个只有一个项目详细信息的用户列表(_id = 59f6f9230a975a67cc7d7638),我想要搜索并按验证待定用户和用户名排序结果。结果恰如其分。

db.User.aggregate(
    {$unwind:"$otherInfo.projects"}, 
    {
        $match:{
            "otherInfo.projects._id":ObjectId("59f6f9230a975a67cc7d7638"), 
            "otherInfo.projects.status":"Active"
            }
    },
    {$group: {_id: {"_id":"$_id", "basicInfo":"$basicInfo"}, "projects": {$push: "$otherInfo.projects"}}},
    {$project:{"_id":"$_id._id", "basicInfo":"$_id.basicInfo", "otherInfo.projects":"$projects"}},
    {$sort:{"otherInfo.projects.verifyDet.isVerified":1, "basicInfo.name":1}}
)

但是当我在Spring中创建相同的聚合时,如下所述,我得到例外:

public List<Map> fetchUsersList(String projectId, Pageable pageable) {

    //unwind operation
    AggregationOperation unwindOp = Aggregation.unwind("$otherInfo.projects");

    Criteria criteria = Criteria.where("otherInfo.projects._id").is(new ObjectId(projectId));
             criteria.and("otherInfo.projects.status").is("Active");
    AggregationOperation matchOp =  Aggregation.match(criteria);

    AggregationOperation groupOp = Aggregation.group(
                                    Fields.from(Fields.field("_id", "$_id")).and(Fields.field("basicInfo","$basicInfo"))).push("$otherInfo.projects").as("projects");
    AggregationOperation projectOp = Aggregation.project(
            Fields.from(Fields.field("_id","$_id._id"),
            Fields.field("basicInfo","$_id.basicInfo"),
            Fields.field("otherInfo.projects","$projects")));

    AggregationOperation sortOp = Aggregation.sort(Direction.DESC, "otherInfo.projects.verifyDet.isVerified").and(Direction.DESC, "basicInfo.name");

    Aggregation agg = Aggregation.newAggregation(unwindOp, matchOp, groupOp, projectOp, sortOp);

    AggregationResults<User> results = mongoTemplate.aggregate(agg,
            "User", User.class);
    return results.getMappedResults();
}

例外:

2017-12-15 19:24:31,852 ERROR GlobalExceptionHandler:75 - Exception Stack Trace : 
java.lang.IllegalArgumentException: Invalid reference 'otherInfo.projects.verifyDet.isVerified'!
at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:99)
at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:80)
at org.springframework.data.mongodb.core.aggregation.SortOperation.toDBObject(SortOperation.java:73)
at org.springframework.data.mongodb.core.aggregation.AggregationOperationRenderer.toDBObject(AggregationOperationRenderer.java:56)
at org.springframework.data.mongodb.core.aggregation.Aggregation.toDbObject(Aggregation.java:580)
at org.springframework.data.mongodb.core.aggregation.Aggregation.toString(Aggregation.java:596)
at com.grpbk.gp.repository.impl.UserRepositoryCustomImpl.fetchUsersList(UserRepositoryCustomImpl.java:1128)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)

请让我知道我做错了什么。

1 个答案:

答案 0 :(得分:0)

&#34; otherInfo.projects.verifyDet.isVerified&#34;字段需要出现在Project Oepration或group操作中,以便sort可以获得该参考。