Мангуст — заполнение неправильно фильтрует

#node.js #mongodb #express #mongoose #mongoose-populate

#node.js #mongodb #выразить #мангуст #мангуст-заполнение

Вопрос:

Я хочу возвращать только объекты friend в массиве, статус которых «активен». Тем не менее, когда я выполняю запрос get, я все еще вижу друзей со статусом «ожидание».

Вот мой контроллер индекса:

 index: function(req, res) {
    User.findOne({
      _id: req.params.id
    })
    .populate({path: "roommates", match: {status: {$eq: "active"}}})
    .exec(function(err, user) {
      console.log(user.roommates);
    })
  }
  

Вот результат записи в консоль:

 [ { _id: 57f2e5e02d58f51a8284bc11,
    balance: 0,
    requests: [],
    status: 'pending' } ]
  

Вот моя пользовательская модель для справки:

 var UserSchema = new Schema({
  name: String,
  username: {
    type: String,
    required: [true, "Please enter a username"],
    minlength: [6, "Username must be at least 6 characters"],
    maxlength: [15, "Username cannot exceed 15 characters"],
    unique: true
  },
  password: {
    type: String,
    required: [true, "Please enter a password"],
    minlength: [6, "Password must be at least 6 characters"],
    maxlength: [17, "Password cannot exceed 17 characters"],
  },
  roommates: [{roommate: {type: Schema.Types.ObjectId, ref: "User", unique: true}, status: {type: String, default: "pending"}, requests: [{type: Schema.Types.ObjectId, ref: "Request"}], balance: {type: Number, default: 0}}]
})
  

Я только хочу вернуть друзей со статусом «активный». Любая помощь?
Спасибо!

Комментарии:

1. Где находится «пользовательская» схема или она ссылается на собственную схему в соседях по комнате??

2. Я не понимаю, о чем вы спрашиваете? Где находится схема пользователя? Это выше в нижнем блоке кода.

Ответ №1:

Поскольку ссылка находится в roommate в схеме пользователя, заполнение должно быть:

     .populate({path: "roommates.roommate"})
  

и результат должен выглядеть так:

 [ { roommate: [Object], //populated object
    balance: 0,
    requests: [],
    status: 'pending' } ]
  

Теперь, даже если вы:

 .populate({path: "roommates.roommate", match: {status: {$eq: "active"}}})
  

Он должен возвращать значение null:

 [ { roommate: null,
balance: 0,
requests: [],
status: 'pending' } ]
  

Потому что вы заполняете пользователя в roommate, а схема пользователя не имеет поля статуса или баланса. Статус и баланс являются дополнительными полями в объекте roommate внутри массива roommates.

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

Одним из вариантов является удаление полей статуса и баланса у соседей по комнате и включение их в схему пользователя.

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

     User.findOne({
    _id: req.params.id
     })
    .exec(function(err, user) {
        user.roommates = user.roommates.filter(function (rm) {
            return rm.status == "active"
        });
        console.log(user.roommates)
    })
  

Комментарии:

1. Спасибо, но это не может работать, потому что статус указывает на статус определенных отношений с соседями по комнате. Например, у одного пользователя будет много статусов, по одному для каждого соответствующего соседа по комнате этого пользователя. Поэтому превращение статуса в свойство не будет работать. Мне пришлось фильтровать данные в интерфейсе angular, который работал просто отлично.

2. В вашем случае была бы уместна другая коллекция «сосед по комнате». В нем будут поля status и members. члены будут представлять собой массив, который будет содержать идентификаторы двух пользователей, поэтому он позаботится о многих отношениях со многими с обоих концов. У пользователей A и B будет один документ roommate со статусом.