Home > Software design >  Mongoose sort by array of dates (today future)
Mongoose sort by array of dates (today future)

Time:12-30

I need help with a bit more complex version of sorting than usual. So I have times: [Date] field in scheme. Let's say my DB has 2 items with these fields:

  • a) time: [ "2022-12-28T18:00:00.000 00:00", "2023-01-04T18:00:00.000 00:00" ].
  • b) time: [ "2022-12-30T18:00:00.000 00:00" ].

My query:

const today = new Date().toISOString().split("T")[0];
...
.find({ times: { $gte: today } }).sort("times")

Because today is 2022-12-29, .sort("times") or .sort({ times: 1 }) will sort events in a way, that item "a)" will be sorted first, because from "now" Dec 28 is closer than 30, so it works correctly.

What I want is to ignore dates that are 1 days old. It should consider dates that are today and all in the future, but not yesterday or later in the past.

I thought about querying all items once per day to and removing all past dates, but I kind of want to keep them. Is there a solution with aggregation for this problem?

EDIT: added algorithm for sorting array of dates

export const sortDateByClosest = datesArray => {
    if (datesArray.length === 1) return datesArray;

    const today = new Date();
    const yesterday = new Date(new Date().setDate(new Date().getDate() - 1));

    const sorted = datesArray.sort((a, b) => {
        const distanceA = Math.abs(today - a);
        const distanceB = Math.abs(today - b);
        return distanceA - distanceB;
    });

    // remove times that were before yesterday
    return sorted.filter(d => d - yesterday > 0);
};

CodePudding user response:

I think it works You want to ignore 1 days older dates then you need to use aggregation like this:

db.collectionName.aggregate([ 
  {
    "$match": {
      'times': {
        '$gte': today, 
       }
     }
  }, { $unwind: '$times' }, {
    $sort : {
      times: 1
    }
  }
])

CodePudding user response:

Aggregation be like:

    { $unwind: "$times" },
    {
        $match: {
            times: { "$gte": today }
        },
    },
    {
        $sort: {
            times: 1,
        },
    },
    {
        $group: {
            _id: "$_id",
            times: { $push: "$times" },
            otherStuff: { $first: "$otherStuff" },
            ...
        }
    },

But it doesn't show very good results in terms of scalability

  • Related