Как мне правильно использовать populate с мангустом?

Я изучаю какой-то узел и пытаюсь использовать мангуста. В настоящее время моя цель — научиться использовать заполнение.

У меня есть определение projects и milestone требуют:

projectSchema = new mongoose.Schema({
    id: String,
    title: String,
    description: String,
    owner: String,
    site: String,
    creation_date: Date,
    milestone_ids: Array,
    milestones: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: "Milestone"
    }]
})

Project = mongoose.model("Project", projectSchema)
milestones = require(__dirname + "/milestones.js")();

Затем я делаю это в какой-то момент в projects.js:

Project.find(query, {}, {sort: {_id: -1}},
    function (error, results) {
        callback(results);
    }
).populate("milestones");

Как заполнить вехи?


Вот данные project из монго:

{
    "title": "sitename",
    "description": "online thing",
    "creation_date": {
        "$date": "2013-07-11T19:45:42.139Z"
    },
    "_id": {
        "$oid": "51df0b66dbdd7c4f14000001"
    },
    "milestones": [],
    "milestone_ids": [],
    "__v": 0
}

И это milestone, который в основном связан с проектом:

{
    "title": "Proof of concept",
    "description": "Make it work.",
    "due_date": {
        "$date": "2013-07-11T19:46:38.535Z"
    },
    "project_id": "51df0b66dbdd7c4f14000001",
    "_id": {
        "$oid": "51df0b9edbdd7c4f14000002"
    },
    "__v": 0
}

Кроме того, это схема вехи:

milestoneschema = new mongoose.Schema({
    id: String,
    title: String,
    description: String,
    owner: String,
    site: String,
    due_date: Date,
    project_id: {
        type: String,
        ref: "Project"
    }
})

Milestone = mongoose.model("Milestone", milestoneschema);

person Eduárd Moldován    schedule 11.07.2013    source источник


Ответы (1)


Вам нужно правильно определить параметры запроса, а затем выполнить их, а API-интерфейсы с возможностью цепочки, такие как mongoose Query, не могут знать, какие дополнительные методы вы можете вызвать ПОСЛЕ запуска запроса. Поэтому, когда вы передаете обратный вызов .find, mongoose сразу же отправляет запрос.

Передайте обратный вызов find

  • запрос определяется аргументами find
  • поскольку обратный вызов есть, запрос немедленно выполняется и выдает команду в БД
  • затем происходит .populate, но это не имеет никакого эффекта, так как запрос уже отправлен в монго

Вот что вам нужно сделать:

Project.find(query, {}, {
    sort: {
        _id: -1
    }
}).populate("milestones").exec(function (error, results) {
    callback(results);
});

Или немного более читабельно:

Project
    .find(query)
    .sort('-_id')
    .populate('milestones')
    .exec(function(error, results) {                  
        callback(results);
    });

Пропустить обратный вызов и использовать .exec

  • запрос, переданный в .find, создает объект запроса с параметрами
  • дополнительные связанные вызовы для .sort, .populate и т. д. дальнейшая настройка запроса
  • .exec сообщает mongoose, что вы закончили настройку запроса, и mongoose выдает команду DB
person Peter Lyons    schedule 11.07.2013
comment
Хорошо, все, что вы написали, имеет смысл. Плохо то, что вехи до сих пор не заполнены. Я получаю пустой массив точно так же, как и раньше. - person Eduárd Moldován; 11.07.2013
comment
Также, если вы опубликуете больше кода, мы можем найти простые опечатки и еще много чего. Дьявол здесь кроется в деталях, поскольку мангуст связывает все это вместе на основе имен строк со сбивающими с толку вещами, такими как автоматическое множественное число. Одна вещь в нижнем регистре или единственном числе неправильно, и вы получите неправильное поведение и никаких ошибок. Однако из вашего фрагмента, на первый взгляд, все выглядит хорошо. - person Peter Lyons; 12.07.2013
comment
У вас также есть milestone_ids, что, вероятно, сбивает вас с толку и похоже на дубликат. Я бы удалил это из схемы и перенес его из ваших данных, как только вы правильно заполните milestones. - person Peter Lyons; 12.07.2013
comment
Я проверил данные, мне кажется, все в порядке. Я вставил в пост. Вы видите там что-то неправильное? - person Eduárd Moldován; 12.07.2013
comment
Да "milestones": [], ваш массив вех пуст. Populate смотрит на это (ссылки в коллекции, которую вы запрашиваете), стиль «один ко многим», а не наоборот. - person Peter Lyons; 12.07.2013
comment
Я немного потерялся. Что должно быть установлено при сохранении? Разве это не похоже на соединение sql, которое объединяет данные из другой таблицы? - person Eduárd Moldován; 12.07.2013
comment
давайте продолжим обсуждение в чате - person Peter Lyons; 12.07.2013
comment
Я собираюсь отметить это как правильный ответ, потому что вы дали мне руководство и правильный способ сделать это в чате. Благодарю вас! - person Eduárd Moldován; 13.07.2013
comment
ссылка на чат не работает. Я хотел бы знать, как это было решено. Спасибо - person ibolton336; 10.12.2015