Reputation: 41
I am trying run a mongo aggregation on Spring data here is the sample json
{
"id":*****
"taskResultContent":
[
{
"executionUUID":"uuid_2",
"sequency":"1",
"returnContent":"SUCCESS",
},
{
"executionUUID":"uuid_2",
"sequency":"2",
"returnContent":"SUCCESS",
}
]
}
here is my Mongo query
[
{
"$match" : {
"_id" : ObjectId("54767c7cfda0da01d4843e93")
}
},
{
"$unwind" : "$taskResultContent"
},
{
"$project" : {
"executionUUID" : "$taskResultContent.executionUUID",
"returnContent" : "$taskResultContent.returnContent",
"sequency" : "$taskResultContent.sequency",
"_id" : 0,
"resultID" : "$_id"
}
},
{
"$match" : {
"executionUUID" : "uuid_3"
}
},
{
"$sort" : {
"sequency" : -1
}
}
]
here is my java implementation:
Aggregation agg = newAggregation(
match(Criteria.where("_id").is(objId)),
unwind("taskResultContent"),
project("taskResultContent.executionUUID","taskResultContent.returnContent","taskResultContent.sequency").and("resultID").previousOperation(),
match(Criteria.where("executionUUID").is(executionUUID)),
sort(DESC,"sequency")
);
Then I found a problem, the SORT doesn't work. I print out the aggregation query from java. it looks like:
{
"$sort": {
"taskResultContent.sequency": -1
}
}
it should be "sequerycy":-1 but not "taskResultContent.sequency": -1 Does anyone meet the same issue ?
Upvotes: 2
Views: 2165
Reputation: 21
You would new class
class SortOperationEx implements AggregationOperation {
private final Sort sort;
/**
* Creates a new {@link org.springframework.data.mongodb.core.aggregation.SortOperation} for the given {@link Sort} instance.
*
* @param sort must not be {@literal null}.
*/
public SortOperationEx(Sort sort) {
Assert.notNull(sort, "Sort must not be null!");
this.sort = sort;
}
public SortOperationEx (Sort.Direction direction, String... fields) {
this(new Sort(direction, fields));
}
public SortOperationEx and(Sort.Direction direction, String... fields) {
return and(new Sort(direction, fields));
}
public SortOperationEx and(Sort sort) {
return new SortOperationEx(this.sort.and(sort));
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDBObject(AggregationOperationContext context) {
BasicDBObject object = new BasicDBObject();
for (Sort.Order order : sort) {
// Check reference
String prop = order.getProperty();
object.put(prop, order.isAscending() ? 1 : -1);
}
return new BasicDBObject("$sort", object);
}
}
and modify code From:
Aggregation agg = newAggregation(
match(Criteria.where("_id").is(objId)),
unwind("taskResultContent"),
project("taskResultContent.executionUUID","taskResultContent.returnContent","taskResultContent.sequency").and("resultID").previousOperation(),
match(Criteria.where("executionUUID").is(executionUUID)),
sort(DESC,"sequency")
);
To:
Aggregation agg = newAggregation(
match(Criteria.where("_id").is(objId)),
unwind("taskResultContent"), project("taskResultContent.executionUUID","taskResultContent.returnContent","taskResultContent.sequency").and("resultID").previousOperation(),
match(Criteria.where("executionUUID").is(executionUUID)),
new SortOperationEx(DESC,"sequency")
);
Upvotes: 2
Reputation: 19700
Modify your project stage operation to use as()
to project
a field by some other name and then apply the sort.
..
project("taskResultContent.executionUUID").as("executionUUID").
and("taskResultContent.returnContent").as("returnContent")
...
Upvotes: 0