вернуть последние встроенные данные в коллекцию

В приложении mongodb с весенней загрузкой я хотел бы вернуть последний элемент встроенной коллекции.

Мой документ:

@Document
public class ConnectedObject {
  @Id
  private String uuid;
  private List<Measure> measures = new ArrayList<>();
}

public class Measure {
  private LocalDateTime timestamp;
  private long stepsCount;
}

Пример данных в mongoDb:

{
 "_id":"aaaa",
 "measures":[
   {"timestamp":"2018-04-05T08:20:33.561Z","stepsCount":"0"},
   {"timestamp":"2018-04-05T08:21:35.561Z","stepsCount":"10"},
   {"timestamp":"2018-04-05T08:20:35.561Z","stepsCount":"0"}
  ]
 }

Я хотел бы получить последнюю меру (фильтр по полю метки времени) подключенного объекта (фильтр по uuid). Я не знаю, как написать запрос с помощью MongoTemplate.

У меня уже есть собственный репозиторий в проекте.


person BokC    schedule 03.04.2018    source источник


Ответы (2)


Что-то вроде запроса ниже должно дать то, что вам нужно

db.collection.aggregate([
 {$match: {'$uuid':'12345'}},
 {$sort:{'$measure.timestamp':1}},
 {$project:{
     uuid: 1,
     last: { $arrayElemAt: [ "$measures", -1 ] }
  }
 }
])
person Graciano    schedule 04.04.2018
comment
Это не хорошо. $sort не действует в списке мер. Можно ли отсортировать элементы $measures в $arrayElemAt? - person BokC; 05.04.2018

После долгих попыток работает:

public Measure getLastMeasureOf(String uuid) {
    final Aggregation agg = newAggregation(
            match(Criteria.where("uuid").is(uuid)),
            unwind("measures"),
            sort(Sort.Direction.DESC, "measures.timestamp"),
            group("uuid").first("$$ROOT").as("result"),
            project("result.uuid").and("result.measures").as("last")
    );

    final AggregationResults<ObjectWithLastMeasure> results
            = template.aggregate(agg, ConnectedObject.class, ObjectWithLastMeasure.class);

    final ObjectWithLastMeasure owlm = results.getUniqueMappedResult();
    return owlm == null ? null : owlm.getLast();
}
person BokC    schedule 27.04.2018