Я часами боролся с функцией mongoose.model.populate. Я даже попытался напрямую скопировать и вставить несколько решений, но безуспешно.
У меня есть модель пользователя, которая должна содержать массив «Дилемм», который он / она создал, но я не смог его заполнить.
Вот модели, а также реализация populate().
User.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// Create Schema
const UserSchema = new Schema({
username: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
dilemmas: [
{
type: Schema.Types.ObjectId,
ref: "Dilemma"
}
]
});
module.exports = User = mongoose.model("User", UserSchema, "users");
Dilemma.js
const mongoose = require("mongoose");
const slug = require("mongoose-slug-generator");
const Schema = mongoose.Schema;
mongoose.plugin(slug);
// Create Schema
const DilemmaSchema = new Schema({
creator: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
title: {
type: String
},
slug: {
type: String,
slug: "title"
},
red: {
type: String,
required: true
},
blue: {
type: String,
required: true
},
red_votes: {
type: Number,
default: 0,
required: true
},
blue_votes: {
type: Number,
default: 0,
required: true
},
likes: [
{
user: {
type: Schema.Types.ObjectId,
ref: "User"
}
}
],
comments: [
{
user: {
type: Schema.Types.ObjectId,
ref: "User"
},
text: {
type: String,
required: true
},
author: {
type: String
},
avatar: {
type: String
},
date: {
type: Date,
default: Date.now
}
}
],
date: {
type: Date,
default: Date.now
}
});
module.exports = Dilemma = mongoose.model("Dilemma", DilemmaSchema, "dilemmas");
Routes.js
// @route GET api/users/profile
// @desc Gets logged in user's profile
// @access Private
router.get(
"/profile",
passport.authenticate("jwt", { session: false }),
(req, res) => {
User.find({ username: req.user.username })
.populate("dilemmas")
.then(user => {
if (!user) {
errors.nouser = "There is no user";
return res.status(404).json(errors);
}
res.json(user);
})
.catch(err => res.status(400).json(err));
}
);
Ответ JSON
[
{
"_id": "5b807beef770e7c7e6bf7ce0",
"dilemmas": [],
"username": "Jonas",
"email": "[email protected]",
"password": "$2a$10$QaqljS9x08YQ9N9EuCBTpO114ZJUFuVxAV80xMzImNi8eW2frPg0C",
"date": "2018-08-24T21:43:10.411Z",
"__v": 0
}
]
Ответ JSON Dilemmas
[
{
"red_votes": 0,
"blue_votes": 0,
"_id": "5b80975f6e47fecba621f295",
"user": "5b807beef770e7c7e6bf7ce0",
"title": "Am i the real author asdsdasd?",
"red": "This is the red dilemma",
"blue": "This is the blue dilemma",
"likes": [],
"comments": [],
"date": "2018-08-24T23:40:15.381Z",
"slug": "am-i-the-real-author-asdsdasd",
"__v": 0
},
{
"red_votes": 0,
"blue_votes": 0,
"_id": "5b808e789bc36bcae8c6c3ad",
"creator": "5b807beef770e7c7e6bf7ce0",
"title": "Am i the real author?",
"red": "This is the red dilemma",
"blue": "This is the blue dilemma",
"likes": [],
"comments": [],
"date": "2018-08-24T23:02:16.565Z",
"slug": "am-i-the-real-author",
"__v": 0
}
]
Ответ пользователей JSON
{
"_id": {
"$oid": "5b807beef770e7c7e6bf7ce0"
},
"dilemmas": [],
"username": "Jonas",
"email": "[email protected]",
"password": "$2a$10$QaqljS9x08YQ9N9EuCBTpO114ZJUFuVxAV80xMzImNi8eW2frPg0C",
"date": {
"$date": "2018-08-24T21:43:10.411Z"
},
"__v": 0
}
заполнить ({путь: "путь", модель: "модель"})
@AnthonyWinzlet, я обновил коллекции.
Можете ли вы попробовать отобразить дилеммы в своем представлении? Я считаю, что существует известная проблема с populate (), когда данные не отображаются в JSON, хотя вы можете отображать их в представлении.
@ Майкл, я могу попробовать. Я еще не создал представление, но сообщу вам, как только закончу.
У вас нет идентификаторов объектов dilemmas в коллекции пользователей ... "dilemmas": [],
@AnthonyWinzlet, у меня возникла идея, что заполнить массив дилемм идентификаторами объектов, поскольку они ссылаются друг на друга, потому что у дилемм есть «создатель» с целью пользователя, который их создал.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы пробовали это?
User.find({ username: req.user.username })
.populate("dilemmas")
.exec() // <-- add exec() to perform the search
.then(user => {
...
})
Вы уверены, что у вас есть дилеммы в базе данных для пользователя Jonas?
Да, я действительно опубликовал ответ json, показывающий, что это могло быть отредактировано.
Я спрашиваю об этом, потому что ответ JSON имеет пустой массив dilemmas без какого-либо objectId в нем
Да, в этом вся проблема. JSON в сообщении - это ответ от маршрута профиля, который должен содержать все dilemmas, созданные пользователем. Я подтвердил, что в базе данных существует dilemmas с таким же идентификатором автора, как и у user.
Вы проверяли здесь документацию?
https://mongoosejs.com/docs/populate.html#refs-to-children
Он показывает аналогичную установку (с авторами и рассказами). Он упоминает «подталкивание» историй, чтобы иметь возможность использовать комбинацию find / populate.
Да, я читал это раньше и пытался воспроизвести то, что они показали, для моего проекта. Но вроде ничего не работает ...
Я сам столкнулся с подобной проблемой. Заполнение ссылки сработало, но заполнение массива ссылок - нет. Мне удалось заставить заполнить массив для работы, явно указав имя модели в вызове заполнения, например:
User.find({ ... }).populate({
path: 'dilemmas',
model: 'Dilemma',
});
Я не знаю, почему это имеет значение, если имя модели, на которую указывает ссылка, уже указано в схеме.
не могли бы вы опубликовать свои образцы коллекций для обоих документов