Макс
db.collection.aggregate([
{
$group: {
_id: {
city: "$city",
eventTime: "$eventTime"
},
max: {
$max: "$createdTime"
},
data: {
$push: "$$ROOT"
}
}
},
{
$project: {
max_events: {
$filter: {
input: "$data",
cond: {
$eq: [
"$max",
"$$this.createdTime"
]
}
}
}
}
},
{
$unwind: "$max_events"
},
{
$replaceRoot: {
newRoot: "$max_events"
}
}
])
MongoPlayground
MongoTemplate
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
Aggregation agg = Aggregation.newAggregation(
group("city", "eventTime").max("createdTime").as("max").push("$$ROOT").as("data"),
project().and(new AggregationExpression() {
@Override
public Document toDocument(AggregationOperationContext context) {
return new Document("$filter",
new Document("input", "$data")
.append("cond", new Document("$eq", Arrays.asList("$max", "$$this.createdTime"))));
}
}).as("max_events"),
unwind("max_events"),
replaceRoot("max_events")
);
AggregationResults<Event> events = mongoTemplate.aggregate(agg, mongoTemplate.getCollectionName(Event.class), Event.class);
for(Event ev: events) {
System.out.println(ev);
}
Ближайший
db.collection.aggregate([
{
$group: {
_id: {
city: "$city",
eventTime: "$eventTime"
},
data: {
$push: "$$ROOT"
}
}
},
{
$project: {
closest: {
$reduce: {
input: "$data",
initialValue: {
$arrayElemAt: [
"$data",
0
]
},
in: {
$cond: [
{
$lt: [
{
$abs: {
$subtract: [
"$$this.eventTime",
"$$this.createdTime"
]
}
},
{
$abs: {
$subtract: [
"$$value.eventTime",
"$$value.createdTime"
]
}
}
]
},
"$$this",
"$$value"
]
}
}
}
}
},
{
$unwind: "$closest"
},
{
$replaceRoot: {
newRoot: "$closest"
}
}
])
MongoPlayground
MongoTemplate
Aggregation agg = Aggregation.newAggregation(
group("city", "eventTime").push("$$ROOT").as("data"),
project().and(new AggregationExpression() {
@Override
public Document toDocument(AggregationOperationContext context) {
return new Document("$reduce",
new Document("input", "$data")
.append("initialValue", new Document("$arrayElemAt", Arrays.asList("$data", 0)))
.append("in", new Document("$cond", Arrays.asList(
new Document("$lt", Arrays.asList(
new Document("$abs", new Document("$subtract", Arrays.asList("$$this.eventTime", "$$this.createdTime"))),
new Document("$abs", new Document("$subtract", Arrays.asList("$$value.eventTime", "$$value.createdTime"))))),
"$$this",
"$$value"))));
}
}).as("closest"),
unwind("closest"),
replaceRoot("closest")
);
AggregationResults<Event> events = mongoTemplate.aggregate(agg, mongoTemplate.getCollectionName(Event.class), Event.class);
for(Event ev: events) {
System.out.println(ev);
}