Mongoose / MongoDB: $ elemMatch для нескольких полей с массивом объектов - PullRequest
0 голосов
/ 17 марта 2020

У меня есть коллекция MongoDB, которую я пытаюсь запросить, но у меня возникают проблемы при запросе нескольких полей. Я видел много статей по SO, в документах и ​​в других местах, но не нашел ни одной, которая бы соответствовала моей проблеме.

Я думаю, что это легче увидеть из запроса в приведенном ниже коде, но я ' Я пытаюсь добиться следующего:

Вернуть все документы, которые

ЛИБО

  • доступны для публики c

    ИЛИ

  • имеют ограниченный доступ

    И ИЛИ

    • этот пользователь назван в массиве индивидуумов
    • этот пользователь имеет разрешение на просмотр статьи

      ИЛИ

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

Я сделал и проверил запрос для лиц , но ничего не пробовал для учреждений сработало.

Упрощенная версия user schema. NB. Пользователь может иметь более одного role.

const userSchema = new mongoose.Schema({
  institutions: [{
    institution: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Institution'
    },
    role: [{
      type: String,
      enum: ['Owner', 'Admin', 'User', 'Guest']
    }]
  }]
})

Сокращенная версия paper schema:

const paperSchema = new mongoose.Schema({
  accessLevel: {
    type: String,
    enum: ['Public', 'Restricted', 'Owner']
  },
  individualAccess: [{
    individual: {
      type: mongoose.Schema.Types.ObjectId,
      ref: Individual
    }
    permissions: {
      viewPaper: Boolean
    }
  }],
  institutionAccess: [{
    institution: {
      type: mongoose.Schema.Types.ObjectId,
      ref: Institution
    },
    permissions: {
      viewPaper: [{
        type: String,
        enum: ['Owner', 'Admin', 'User', 'Guest']
      }]
    }
  }]
  }
})

Запрос:

// req.user._id: userId from the jwt.
// userMapped = req.user.map() to return something like:
[{
  institution: objectIdOfInstitution1
  role: [ 'Admin', 'Guest' ]
},
{
  institution: objectIdOfInstitution2
  role: [ 'Admin', 'Owner' ]
}]

const papers = await Paper.find({
  $or: [
    { 'accessLevel': 'Public' },
    {
      'accessLevel': 'Restricted',
      $or: [
        { 'individualAccess': { $elemMatch: {
          'user': req.user._id,
          'permissions.viewPaper': true
        }}},

//Start of the part that is causing problems
        { 'institutionAccess': { $elemMatch: {
          'institution': userMapped.institution,
          'permissions.viewPaper': userMapped.role
        }}}
//End of the part that is causing problems

      ]
    }
  ]
})

Я пробовал сопоставить req.user с userMapped различными способами, но ни один из них не сработал. (Я попытался разделить массив и объединить institutionId с role, но понял, что, вероятно, не смог объединить значения документа MongoDB до тех пор, пока он не будет возвращен.

Я пытался использовать подстановочные знаки, но думаю, они предназначены для обновления вместо получения .

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

Я на правильном пути? Или есть другая функция MongoDB, которую мне нужно исследовать?

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