简体   繁体   中英

Return multiple documents which match the latest date with a single MongoDB query in Mongoose

The following is MongoDB query. What is the best possible way to write this query in Mongoose?

db.logs.find({date: db.logs.find({}, {date:1,"_id":0}).sort({date:-1}).limit(1).toArray()[0].date})

There could be multiple documents with the same date and we need to retrieve all the documents that match the latest date.

The aggregation framework makes it possible to write this in a single query. You would require a pipeline that has an initial $lookup operator to do a self-join and within the $lookup execute a pipeline on the joined collection which allows for uncorrelated sub-queries to return the latest date:

db.logs.aggregate([
    {  "$lookup": {
        "from": "logs",
        "pipeline": [
            { "$sort": { "date": -1 } },
            { "$limit": 1 },
            { "$project": { "_id": 0, "date": 1 } }
        ],
        "as": "latest"
    } }
])

A further step is required to reshape the new field latest produced above so that the array is flattened. Use $addFields to reshape and $arrayElemAt to flatten the array or use "$unwind" :

db.logs.aggregate([
    {  "$lookup": {
        "from": "logs",
        "pipeline": [
            { "$sort": { "date": -1 } },
            { "$limit": 1 },
            { "$project": { "_id": 0, "date": 1 } }
        ],
        "as": "latest"
    } },
    { "$addFields": { "latest": { "$arrayElemAt": ["$latest", 0] } } }
])

The final step would be to filter the documents in the resulting pipeline using $expr in a $match stage since you will be comparing fields from the same document:

db.logs.aggregate([
    {  "$lookup": {
        "from": "logs",
        "pipeline": [
            { "$sort": { "date": -1 } },
            { "$limit": 1 },
            { "$project": { "_id": 0, "date": 1 } }
        ],
        "as": "latest"
    } },
    { "$addFields": { "latest": { "$arrayElemAt": ["$latest", 0] } } },
    { "$match": {
        "$expr": {
            "$eq": [ "$date", "$latest.date" ]
        } 
    } }
])

Getting the query into Mongoose becomes a trivial exercise.

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