Разбиение на стороне сервера с полем массива строк одного документа - PullRequest
5 голосов
/ 18 апреля 2020

Я пытаюсь выяснить, как выполнить разбиение на страницы на стороне сервера для одного документа, содержащего поле blacklistGroup: [String]

  "blacklistGroup": [
    "5e99fd3aa506cf570056898d",
    "5e99fde5a506cf5700568991",
    "5e99fd64a506cf570056898e",
    "5e98c950f4fb3f63b4634e30",
    "5e99fd15a506cf570056898c",
    "5e99fda5a506cf570056898f",
    "5e99fdc7a506cf5700568990",
    "5e99fcf3a506cf570056898b",
    "5e98e90d85e69146f841d23a",
    "5e9867ff5e72550988820dd3",
    "5e98e8e785e69146f841d239"
  ]

. Я хочу, чтобы оно ограничивало 10 одновременно. Я в основном ищу эквивалент

     User.findById({ _id: req.params.id })
              .select("blacklistGroup")
              .populate("blacklistGroup", "username")
              .skip(10 * (req.query.currentPage - 1))
              .limit(10)
              .then(documents => {

, но, очевидно, не для нескольких документов, а для одного запрашиваемого документа. В настоящее время я передаю текущую страницу бэкэнду, чтобы получить список указанной страницы c из 10. Также важно вернуть имя пользователя, следовательно, .populate в примере. Я ценю любую помощь с этим!

Ответы [ 3 ]

2 голосов
/ 21 апреля 2020

Вы можете использовать срез по запросу с последующим заполнением.

User.findById({ _id: req.params.id })
           .slice('blacklistGroup', [10 * (req.query.currentPage - 1), 10])
           .populate("blacklistGroup", "username");

Вы также можете использовать агрегат с $ slice и $ lookup.

User.aggregate([
 {"$match":{"_id":req.params.id}},
 {"$project":{"blacklistGroup":{"$slice":["$blacklistGroup", 10 * (req.query.currentPage - 1), 10]}}},
 {"$lookup":{
   "from": usercollection,
   "localField": "blacklistGroup",
   "foreignField": "_id",
   "as": "blacklistGroup"
 }},
 {"$project":{"usernames":"$blacklistGroup.username"}}])

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

User.aggregate([
 {"$match":{"_id":req.params.id}},
 {"$lookup":{
  "from":usercollection,
  "let":{"blacklistGroup":{"$slice":["$blacklistGroup", 10 * (req.query.currentPage - 1), 10]}},
  "pipeline":[
    {"$match":{"$expr":{"$eq":["$_id","$$blacklistGroup"]}}},
    {"$project":{"username":1,"_id":0}}
  ],
  "as":"blacklistGroup"
}}]);

Ради полноты добавлен целый пример

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test', {useNewUrlParser: true});
var db = mongoose.connection;
mongoose.set('debug', true);
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
  // we're connected!
});
const UserSchema = new mongoose.Schema({
    blacklistGroup: [{
      type: String,
      ref: 'Group'
    }]
  })
const GroupSchema = new mongoose.Schema({
    _id: String,
    content: String,
    username: String
  })
const User  = mongoose.model('User', UserSchema, 'users');
const Group = mongoose.model('Group', GroupSchema, 'groups');
module.exports = {
    User, Group
  }

 User.findOne().slice("blacklistGroup", 3).populate("blacklistGroup", "username").exec((err, blacklistGroup) => {
      console.log("Populated blacklistGroup " + blacklistGroups);
    })        

Также добавлен пн go Детская площадка likn например 2

https://mongoplayground.net/p/YP5l5Kz3sp8

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

Насколько я знаю, это невозможно сделать с помощью функции populate, вместо этого вам придется использовать агрегацию:

User.aggregate([
  {$match: {
    _id: req.params.id
  }},
  {$unwind: '$blacklistGroup'},
  {$addFields:{
    blacklistGroupId: {$toObjectId: "$blacklistGroup"}
  }},
  {$lookup:{
    from: '<name of your blacklist collection>',
    localField: 'blacklistGroupId',
    foreignField: '_id',
    as: 'blacklistGroup'
  }},
  {$skip: 10 * (req.query.currentPage - 1)},
  {$limit: 10},
  {$group:{
    _id: '$_id',
    blacklistGroup: {$push: '$blacklistGroup.username'}
  }}
]).exec().then(documents => {
  //...
})

Это даст вам один документ, содержащий blacklistGroup свойство, которое является массивом username с. Вы можете удалить $group -этап, чтобы сохранить их как 10 отдельных документов.

Обратите внимание, что для этого требуется версия 4.0 mon go.

0 голосов
/ 22 апреля 2020

Попробуйте использовать функцию агрегирования и выполните шаги,

$lookup:{
   "from": <usercollection>,
   "localField": "blacklistGroup",
   "foreignField": "_id",
   "as": "blacklistGroup"
 }

, затем

$unwind: {
             path : <usercollection>,
         }

, затем

$match: {
        ...
        }

желаемое условие. после этого используйте свою функцию предела, следуя шаблону совокупности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...