Mongodb Пагинация после совокупности - PullRequest
1 голос
/ 12 апреля 2020
  • Я хочу объединить метаданные и метаданные для правильного отображения результата, как вы можете видеть, я использовал $match несколько раз, чтобы получить правильный результат после агрегирования.
  • Мне также нужно total_pages в метаданных, Как реализовать эту формулу Math.ceil(total_items/limit).

Примечание: Код работает правильно, но нужно оптимизировать лог c.

db.collection('cms_brands').aggregate([
  {
    $facet: {
      data: [{ $match: {title:"clue brand"} }, { $skip: 0 }, { $limit: 10 }],
      metadatax: [ { $count: "total" }, { $addFields: { page: 0 } }],
      metadata: [ { $match: {title:"clue brand"} }, { $skip: 0 }, { $limit: 10 }, {$group: { _id: "$title", count: { $sum: 1 } }} ],

    }
  }
]).toArray()
    .then((items) => { return { statusCode: 200, body: items }; })
    .catch(err => {
      console.log('=> an error occurred: ', err);
      return { statusCode: 500, body: 'error' };
    });

Фактический ответ:

[
    {
      "data": [
        {
          "_id": "5e91d2c4a3fda138bcdbfd82",
          "title": "clue brand"
        },
        {
          "_id": "5e91d2dea3fda138bcdbfd83",
          "title": "clue brand"
        }
      ],
      "metadatax": [
        {
          "total": 3,
          "page": 0
        }
      ],
      "metadata": [
        {
          "_id": "clue brand",
          "count": 2
        }
      ]
    }
  ]

Ожидаемый ответ:

[
    {
      "data": [
        {
          "_id": "5e91d2c4a3fda138bcdbfd82",
          "title": "clue brand"
        },
        {
          "_id": "5e91d2dea3fda138bcdbfd83",
          "title": "clue brand"
        }
      ],
      "metadata": [
        {
          "total": 3,
          "page": 0,
          "_id": "clue brand",
          "count": 2
        }
      ]
    }
  ]

1 Ответ

1 голос
/ 12 апреля 2020

Вы можете изменить несколько вещей, попробуйте следующий запрос:

db.collection.aggregate([
  {
    $facet: {
      metadatax: [{ $count: "total" }, { $addFields: { page: 0 } }],
      metadata: [
        { $match: { title: "clue brand" } },
        { $skip: 0 },
        { $limit: 10 },
        {
          $group: {
            _id: "$title",
            count: { $sum: 1 },
            data: { $push: "$$ROOT" }
          }
        }
      ]
    }
  },
  { $unwind: "$metadata" },
  {
    $project: {
      data: "$metadata.data",
      metadata: {
        $mergeObjects: [
          { _id: "$metadata._id", count: "$metadata.count",total_pages: { $ceil: { $divide: [ { $arrayElemAt: [ "$metadatax.total",  0 ] } , 8 ] } } },
          { $arrayElemAt: ["$metadatax", 0] }
        ]
      }
    }
  }
]);

Тест: MongoDB-Playground

Обновления:

  1. Вам не нужен этот data: [{ $match: {title:"clue brand"} }, { $skip: 0 }, { $limit: 10 }] дополнительный шаг в $facet, его можно заменить на data: { $push: "$$ROOT" } в $group из metadata.
  2. Также, поскольку metadata всегда будет массивом одного объекта - вместо того, чтобы быть массивом, я бы предложил, чтобы это был объект для легкого доступа в коде. На всякий случай, если вам нужен массив, все, что вам нужно, это обернуть $mergeObjects в массив в $project.

Примерно так:

  metadata: [{
    $mergeObjects: [
      { _id: "$metadata._id", count: "$metadata.count" },
      { $arrayElemAt: ["$metadatax", 0] }
    ]
  }]
...