Как я могу получить количество документов и эффективно их отфильтровать? (Пн goose) - PullRequest
1 голос
/ 20 марта 2020

Я реализую функцию поиска, которая просто находит документ в mongoDB. Я хочу использовать .skip(x) и .limit(x) для результата для имитации результата подкачки, но могу ли я получить общее количество документов (до пропуска и ограничения) и получить фильтрованный результат сразу?

Код, который дает ожидаемый результат:

db.Datas.find({ type: "Unknown" })
  .then((result) => {
    let count = result.length;
    db.Datas.find({ type: "Unknown" })
      .sort({ createdAt: -1 })
      .skip((req.query.page - 1) * 10)
      .limit(10)
      .then((res) => {
        res.json({ count: count, result: res });
      });
  })
  .catch((err) => {});

Но запрос в два раза несколько раздражает, и это может быть медленным в большой базе данных. Я пробовал что-то вроде find({}).then(x => { ... }).sort(...) ..., но не работает, потому что он возвращает только Promise.

Как я могу сделать это эффективно? или только получение целых документов и пропуск, ограничение с помощью JS -way (с использованием .splice или et c ..) будет быстрее и эффективнее?

1 Ответ

2 голосов
/ 20 марта 2020

Для этого можно использовать агрегацию $ facet .

db.Datas.aggregate([
  {
    $match: {
      "type": "Unknown"
    }
  },
  {
    $sort: {
      createdAt: -1
    }
  },
  {
    $facet: {
      totalRecords: [
        {
          $count: "total"
        }
      ],
      data: [
        {
          $skip: 0
        },
        {
          $limit: 5
        }
      ]
    }
  }
])

Детская площадка

Допустим, у вас есть следующие документы:

db={
  "Datas": [
    {
      "_id": "5e390fc33285e463a0799689",
      "type": "Known",
      "createdAt": "2020-02-04T06:31:31.311Z",
      "__v": 0
    },
    {
      "_id": "5e390fd03285e463a079968a",
      "type": "Known",
      "createdAt": "2020-02-04T06:31:44.190Z",
      "__v": 0
    },
    {
      "_id": "5e390fda3285e463a079968b",
      "type": "Unknown",
      "createdAt": "2020-02-04T06:31:54.248Z",
      "__v": 0
    },
    {
      "_id": "5e390fdf3285e463a079968c",
      "type": "Unknown",
      "createdAt": "2020-02-04T06:31:59.993Z",
      "__v": 0
    },
    {
      "_id": "5e390fec3285e463a079968d",
      "type": "Unknown",
      "createdAt": "2020-02-04T06:32:12.336Z",
      "__v": 0
    },
    {
      "_id": "5e390ffd3285e463a079968e",
      "type": "Unknown",
      "createdAt": "2020-02-04T06:32:29.670Z",
      "__v": 0
    },
    {
      "_id": "5e3910163285e463a079968f",
      "type": "Unknown",
      "createdAt": "2020-02-04T06:32:54.131Z",
      "__v": 0
    },
    {
      "_id": "5e3910213285e463a0799690",
      "type": "Unknown",
      "createdAt": "2020-02-04T06:33:05.166Z",
      "__v": 0
    }
  ]
}

Ответ будет таким:

[
  {
    "data": [
      {
        "__v": 0,
        "_id": "5e3910213285e463a0799690",
        "createdAt": "2020-02-04T06:33:05.166Z",
        "type": "Unknown"
      },
      {
        "__v": 0,
        "_id": "5e3910163285e463a079968f",
        "createdAt": "2020-02-04T06:32:54.131Z",
        "type": "Unknown"
      },
      {
        "__v": 0,
        "_id": "5e390ffd3285e463a079968e",
        "createdAt": "2020-02-04T06:32:29.670Z",
        "type": "Unknown"
      },
      {
        "__v": 0,
        "_id": "5e390fec3285e463a079968d",
        "createdAt": "2020-02-04T06:32:12.336Z",
        "type": "Unknown"
      },
      {
        "__v": 0,
        "_id": "5e390fdf3285e463a079968c",
        "createdAt": "2020-02-04T06:31:59.993Z",
        "type": "Unknown"
      }
    ],
    "totalRecords": [
      {
        "total": 6
      }
    ]
  }
]

Как видите, мы получили итоговые записи с отфильтрованными, отсортированными, пропущенными и ограниченными данными.

...