#java #mongodb
#java #mongodb
Вопрос:
Я пытаюсь загрузить из mongodb последние документы — документы, если они имеют одинаковую временную метку в MongoDB. Есть ли какой-нибудь способ найти последний документ или документы?
Итак, в этом примере возвращаемый документ должен быть первым и вторым.
/* 1 */
{
"_id" : ObjectId("5fbf852902fe571c41d07c9f"),
"insertionTime" : ISODate("2020-11-26T10:36:25.600Z")
}
/* 2 */
{
"_id" : ObjectId("5fbf852902fe571c41d07ca0"),
"insertionTime" : ISODate("2020-11-26T10:36:25.600Z")
}
/* 3 */
{
"_id" : ObjectId("5fbf852902fe571c41d07ca1"),
"insertionTime" : ISODate("2020-11-24T10:36:25.600Z")
}
/* 4 */
{
"_id" : ObjectId("5fbf854702fe571c41d07ca9"),
"insertionTime" : ISODate("2020-11-23T10:36:55.582Z")
}
Я смог найти только последний документ, но только на пределе.
private List<Bson> prepareFilter() {
Bson sortByTimeFilter = sort(Sorts.descending(INSERTION_TIME));
Bson latestFilter = limit(1);
return Arrays.asList(sortByTimeFilter, latestFilter);
}
После попытки агрегировать коллекцию я получил только один документ. Конечно, благодаря пределу (1) есть только один документ. Есть ли какой-либо способ объединить N последних документов, если они имеют одинаковую временную метку?
Заранее спасибо. С наилучшими пожеланиями
Комментарии:
1. Поможет ли вам ответ?
2. @varman Прошу прощения, что не ответил раньше, я только что увидел ваш комментарий. Нет. Мне это не помогло, потому что я не мог использовать MongoTemplate :(.
Ответ №1:
Я использую MongoTemplate для агрегирования. Я рассказываю способ здесь. Автоматическое подключение MongoTemplate
@Autowired private MongoTemplate MongoTemplate;
$sort
помогает сортировать по времени вставки$group
помогает найти последний объектlatestDoc
и одновременно поместить весь документ в массивallDocs
- Поскольку у нас есть последний документ и весь массив документов, мы можем отфильтровать весь массив документов, используя последнюю временную метку документа,
$unwind
для деконструкции массива (теперьallDocs
массив становится объектом)$replaceRoot
для замены объекта на ROOT
Метод
public List<Object> test(List<String> companies,List<String> professions ) {
Aggregation aggregation = Aggregation.newAggregation(
sort(Sort.Direction.DESC, "insertionTime"),
group()
.first("$$ROOT").as("latestDoc")
.push("$$ROOT").as("allDocs")
p-> new Document("$project",
new Document("allDocs",
new Document("$filter"
new Document()
.append("input","$allDocs")
.append("cond",
new Document("$eq",Arrays.asList("$$this.insertionTime","$latestDoc.insertionTime"))
)
)
)
),
unwind("allDocs"),
replaceRoot("allDocs")
).withOptions(AggregationOptions.builder().allowDiskUse(Boolean.TRUE).build());
return mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(YOUR_COLLECTION.class), Object.class).getMappedResults();
}
Рабочая игровая площадка Mongo
Если вы не используете шаблон Mongo, вы можете использовать, как вы уже пробовали, или ТРЮК ДЛЯ ПРЕОБРАЗОВАНИЯ ОБОЛОЧКИ MONGO
Примечание: этот код не тестируется. Но это было написано при работе над сценарием mongo