简体   繁体   中英

How to find latest documents from mongoDB if they have the equals time

I am trying to download from mongodb latest documents - documents if they have the same timestamp in mongoDB. Is there any way to found the latest document or documents?

So in this example, the returned document should be the first one and the second one.

/* 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")
}

I was able to found out only the latest document but only by the limit.

private List<Bson> prepareFilter() {
    Bson sortByTimeFilter = sort(Sorts.descending(INSERTION_TIME));
    Bson latestFilter = limit(1);
    return Arrays.asList(sortByTimeFilter, latestFilter);
}

After trying to aggregate collection I have received the only one document. Of course, thanks to the limit(1) are only one document. Is there any way to aggregate N latest document if they have the same timestamp?

Thanks in advance. Best Regards

I use MongoTemplate to do the aggregation. I tell a way here. Autowire the MongoTemplate

@Autowired private MongoTemplate mongoTemplate;

  • $sort helps to sort by insertionTime
  • $group helps to find the latest object latestDoc and meanwhile push all document to array allDocs
  • Since we have the latest document and all document array, we can filter the all document array using latest document timestamp,
  • $unwind to deconstruct the array (now allDocs array becomes object)
  • $replaceRoot to replace the object to ROOT

The method is

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();

}

Working Mongo playground

If you dont use Mongo template, you can use as you already tried or TRICK TO CONVERT MONGO SHELL

Note: This code is not tested. But it was written on working above mongo script

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM