Mongodb, пн goose - сортировка по _id и дате с использованием агрегата и группы - PullRequest
1 голос
/ 21 марта 2020

Я пытаюсь отсортировать по task._id & date в порядке c. Я могу отсортировать по task._id, но сортировка по date не работает, я попытался изменить порядок в совокупности, но все же не повезло. Я получаю ответ, но в коллекцию добавлен только порядок по пользовательским задачам, а не usertask.date

  1. Пользователь (имя, адрес и т. Д. c)
  2. Задача (имя , значок, правопреемник)
  3. UserTask (User.ObjectId, Task.ObjectId, дата)

Коллекция пользователей:

{
    "users": [
        {
            "name": "Bill",
            "phone": "345"
        },
        {
            "name": "Steve",
            "phone": "123"
        },
        {
            "name": "Elon",
            "phone": "567"
        }
    ]
}

Коллекция задач:

{
    "tasks": [
        {
            "name": "Run 100m",
            "icon": "run",
            "assignee": "Elon"
        },
        {
            "name": "Walk 1 hour",
            "icon": "walk",
            "assignee": "Bill"
        },
        {
            "name": "Jog 30 minutes",
            "icon": "jog",
            "assignee": "Steve"
        }
    ]
}

UserTasks:

    {
        "_id": "5e72fec..",
        "user": "5e72fa4..",
        "task": "5e72fbac..",
        "date": "2020-03-03T05:10:10.000Z",
        "createdAt": "2020-03-19T05:10:37.027Z",
        "updatedAt": "2020-03-19T05:10:37.027Z",
        "__v": 0
    },
    {
        "_id": "5e72fed3..",
        "user": "5e72fa4e..",
        "task": "5e72fbac..",
        "date": "2020-03-12T05:10:10.000Z",
        "createdAt": "2020-03-19T05:10:43.296Z",
        "updatedAt": "2020-03-19T05:10:43.296Z",
        "__v": 0
    },
    {
        "_id": "5e72fed6..",
        "user": "5e72fa..",
        "task": "5e72fb..",
        "date": "2020-03-15T05:10:10.000Z",
        "createdAt": "2020-03-19T05:10:46.057Z",
        "updatedAt": "2020-03-19T05:10:46.057Z",
        "__v": 0
    },
    {
        "_id": "5e72feda...",
        "user": "5e72fa4..",
        "task": "5e72fb..",
        "date": "2020-03-07T05:10:10.000Z",
        "createdAt": "2020-03-19T05:10:50.785Z",
        "updatedAt": "2020-03-19T05:10:50.785Z",
        "__v": 0
    }

Это агрегат, который необходимо изменить

    UserTask.aggregate([
    {
        $lookup: {
            from: "tasks",
            localField: "task",
            foreignField: "_id",
            as: "matchedTask"
        }
    },
    {
        $unwind: "$matchedTask"
    },
    {
        $lookup: {
            from: "users",
            localField: "user",
            foreignField: "_id",
            as: "matchedUser"
        }
    },
    {
        $unwind: "$matchedUser"
    },
    {
        $group: {
            _id: "$matchedTask._id",
            name: {$first: "$matchedTask.name"},
            icon: {$first: "$matchedTask.icon"},
            assignee: { $first: "$matchedTask.assignee" },
            userdata: {
                $push: {
                    name: "$matchedUser.name",
                    date: "$date"
                }
            }

        }
    },
    {
      $sort: { _id: 1, "userdata.date": -1 }
    }
  ])

.exec()
.then(doc => res.status(200).json(doc))
.catch(err => res.status(400).json("Error: " + err));

Ответ показан ниже, обратите внимание на usertask.date. он НЕ сортируется

{
        "_id": "5e...",
        "name": "Run 100m",
        "icon": "run",
        "assignee": "Elon",
        "userdata": [
               {
                "name": "Elon",
                "date": "2020-03-21T20:02:38.143Z"
            },
            {
                "name": "Bill",
                "date": "2020-03-11T20:02:38.000Z"
            },
            {
                "name": "Steve",
                "date": "2020-03-19T20:02:38.000Z"
            }
        ]
    }

Как вы можете видеть, он не отсортирован по дате - по порядку c. Результат должен быть таким, как показано ниже

"userdata": [
               {
                "name": "Elon",
                "date": "2020-03-21T20:02:38.143Z"
            },
            {
                "name": "Steve",
                "date": "2020-03-19T20:02:38.000Z"
            },
            {
                "name": "Bill",
                "date": "2020-03-11T20:02:38.000Z"
            }
        ] 

Ответы [ 2 ]

0 голосов
/ 22 марта 2020

Я исправил это, пришлось использовать сортировку два раза , теперь я могу получить желаемый результат

Решение, представленное ниже

UserTask.aggregate([
        {
          $lookup: {
            from: "tasks",
            localField: "task",
            foreignField: "_id",
            as: "matchedTask"
          }
        },
        {
          $unwind: "$matchedTask"
        },
        {
          $lookup: {
            from: "users",
            localField: "user",
            foreignField: "_id",
            as: "matchedUser"
          }
        },
        {
          $unwind: "$matchedUser"
        },
        {
          $sort: { date: -1 }
        },
        {
          $group: {
            _id: "$matchedTask._id",
            name: { $first: "$matchedTask.name" },
            icon: { $first: "$matchedTask.icon" },
            assignee: { $first: "$matchedTask.assignee" },
            userdata: {
              $push: {
                name: "$matchedUser.name",
                execDate: "$date"
              }
            }
          }
        },
        {
          $sort: { _id: 1 }
        }
      ])
        .exec()
        .then(doc => res.status(200).json(doc))
        .catch(err => res.status(400).json("Error: " + err));
0 голосов
/ 21 марта 2020

$ sort будет использовать последний объект, который выходит из агрегатного канала, и в этом объекте нет поля «дата»:

 {
        $group: {
            _id: "$matchedTask._id",
            name: {$first: "$matchedTask.name"},
            icon: {$first: "$matchedTask.icon"},
            assignee: { $first: "$matchedTask.assignee" },
            userdata: {
                $push: {
                    name: "$matchedUser.name",
                    execDate: "$date"
                }
            }

        }
    },

ваша группа должна вернуть поле с именем date, чтобы возможность его сортировки

{
   $group: {
      _id: "$matchedTask._id",
      name: ....,
      date: ....
   }
}
{ $sort: {date: -1}}

, если значение, которое вы хотите отсортировать, не относится к другому объекту, вы должны указать его для сортировки:

{$sort: {"userdata.date": -1}}
...