Запрос для получения последних трех пользователей, сортировка по дате - Пн goose Node.js - PullRequest
0 голосов
/ 24 февраля 2020

Это данные из Mongodb (Задача. json)

    {
        "username": "john",
        "taskId": "001",
        "date": "2020-02-18T20:14:19.000Z",
    },
    {
        "username": "david",
        "taskId": "001",
        "date": "2020-02-18T21:48:19.000Z",
    },
    {
        "username": "john",
        "taskId": "002",
        "date": "2020-02-15T20:20:32.000Z",
    }
    ... many more

Что я пытаюсь получить

  • Я пытаюсь написать запрос, который возвращает taskId со списком последних users, выполнивших задачу (отсортировано по date - по убыванию).
  • Я хочу только трех последних пользователей который выполнил задачу, чтобы показать ее в списке, таким образом, массив user не должен содержать больше 3 пользователей на задачу

Вот пример, который я создал, о том, как я хочу получить ответ быть:

{
  "tasks": [
    {
      "taskid": "001",
      "users": [
        {
          "username": "david",
          "date": "2020-02-18T21:48:19.000Z"
        },
        {
          "username": "john",
          "date": "2020-02-18T20:14:19.000Z"
        }
      ]
    },
    {
      "taskid": "002",
      "users": [
        {
          "username": "john",
          "date": "2020-02-15T20:20:32.000Z"
        }
      ]
    }
  ]
}

Мой прогресс на данный момент:

router.route("/latest-tasks").get((req, res) => {
    Task.find()
        .sort({ date: "desc" })
        .then(doc =>
            res.status(200).json({
                taskId: doc.taskId,
                list: doc.map(doc => {
                    return {
                        username: doc.username,
                        date: doc.date
                    };
                })
            })
        )
        .catch(err => res.status(400).json("Error: " + err));
});

Ответы [ 2 ]

1 голос
/ 25 февраля 2020

Здесь немного сценария с несколькими запросами, я предлагаю вам использовать агрегацию MongoDB для этого. Этот запрос должен работать:

Todo.aggregate([
  {
    $sort: { taskId: 1, date: 1 }
  },
  {
    $group: {
      _id: "$taskId",
      users: {
        $push: { username: "$username", date: "$date" }
      }
    }
  },
  {
    $project: {
      _id: 0,
      taskid: "$_id",
      users: {
          $filter: {
            input: [
              { $arrayElemAt: ["$users", 0] },
              { $arrayElemAt: ["$users", 1] },
              { $arrayElemAt: ["$users", 2] }
            ],
            as: "user",
            cond: { $ne: ["$$user", null] }
          }
        },
    }
  }
]).exec()
.then(doc => { console.log(doc); })
.catch(err => { console.log(err); });

Трубопровод агрегации Объяснение:

  • $sort: сортировка задач с использованием поля taskId и даты в порядке возрастания
  • $group: эта группа задач по идентификатору задачи. Вот как мы получаем всех пользователей, связанных с задачей
  • $project: это помогает извлечь только первых 3 пользователей, связанных с задачей. Оператор $filter, используемый на этом этапе конвейера, помогает удалить нулевые значения в случае, если с задачей не связано до трех пользователей.

Ссылки: Агрегационный конвейер , Этапы трубопровода , Операторы трубопровода

0 голосов
/ 25 февраля 2020

Вам необходимо использовать .aggregate:

Пн goose код не проверен

Task.aggregate([
  {
    $sort: {
      taskId: 1,
      date: -1
    }
  },
  {
    $group: {
      _id: "$taskId",
      users: {
        $push: {
          username: "$username",
          date: "$date"
        }
      }
    }
  },
  {
    $facet: {
      tasks: [
        {
          $sort: {
            _id: 1
          }
        },
        {
          $project: {
            _id: 0,
            taskid: "$_id",
            users: 1
          }
        }
      ]
    }
  }
]).exec()
.then( doc => res.status(200).json(doc))
.catch(err => res.status(400).json("Error: " + err));

MongoPlayground

...