112

新しく保存されたオブジェクトの作成者フィールドを手動または自動で入力することはできません...私が見つけることができる唯一の方法は、私がやりたくない既に持っているオブジェクトを再クエリすることです.

これはセットアップです:

var userSchema = new mongoose.Schema({   
  name: String,
});
var User = db.model('User', userSchema);

var bookSchema = new mongoose.Schema({
  _creator: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
  description: String,
});
var Book = db.model('Book', bookSchema);

髪を引っ張っているところです

var user = new User();
user.save(function(err) {
    var book = new Book({
        _creator: user,
    });
    book.save(function(err){
        console.log(book._creator); // is just an object id
        book._creator = user; // still only attaches the object id due to Mongoose magic
        console.log(book._creator); // Again: is just an object id
        // I really want book._creator to be a user without having to go back to the db ... any suggestions?
    });
});

編集:最新のマングースはこの問題を修正し、移入機能を追加しました。新しい受け入れられた回答を参照してください。

4

13 に答える 13

150

これを行うには、モデルのpopulate関数を使用できるはずです: http://mongoosejs.com/docs/api.html#model_Model.populate

book._creator = user;

あなたは次のようなことをします:

Book.populate(book, {path:"_creator"}, function(err, book) { ... });

おそらくあなたを助けるには遅すぎる答えですが、私は最近これに行き詰まっており、他の人にとっては役立つかもしれません.

于 2013-07-06T17:57:02.193 に答える
37

誰かがまだこれを探している場合に備えて。

Mongoose 3.6 では、実装するための多くの優れた機能が導入されました。

book.populate('_creator', function(err) {
 console.log(book._creator);
});

また:

Book.populate(book, '_creator', function(err) {
 console.log(book._creator);
});

詳細については、https ://github.com/LearnBoost/mongoose/wiki/3.6-Release-Notes#population をご覧ください。

ただし、この方法では、ユーザーを再度照会します。

追加のクエリなしでそれを達成するためのちょっとしたトリックは次のようになります。

book = book.toObject();
book._creator = user;
于 2015-01-02T13:25:37.453 に答える
12

私のような完全な初心者のために物事を明確にするために、これに追加すると思いました。

注意しないと非常に混乱するのは、3 つのまったく異なる populate メソッドがあることです。それらは異なるオブジェクト (Model と Document) のメソッドであり、異なる入力を受け取り、異なる出力 (Document と Promise) を提供します。

ここに困惑している人のためのものがあります:

Document.prototype.populate()

完全なドキュメントを参照してください。

これはドキュメントに対して機能し、ドキュメントを返します。元の例では、次のようになります。

book.save(function(err, book) {
    book.populate('_creator', function(err, book) {
        // Do something
    })
});

ドキュメントに対して機能し、ドキュメントを返すため、次のようにチェーンすることができます。

book.save(function(err, book) {
    book
    .populate('_creator')
    .populate('/* Some other ObjectID field */', function(err, book) {
        // Do something
    })
});

しかし、私のようにばかげてはいけません。

book.save(function(err, book) {
    book
    .populate('_creator')
    .populate('/* Some other ObjectID field */')
    .then(function(book) {
        // Do something
    })
});

覚えておいてください: Document.prototype.populate() はドキュメントを返すので、これはナンセンスです。約束が欲しいなら...

Document.prototype.execPopulate()

完全なドキュメントを参照してください。

これはドキュメントで機能しますが、ドキュメントに解決される約束を返します。つまり、次のように使用できます。

book.save(function(err, book) {
    book
    .populate('_creator')
    .populate('/* Some other ObjectID field */')
    .execPopulate()
    .then(function(book) {
        // Do something
    })
});

その方がいいです。最後に、ある...

Model.populate()

完全なドキュメントを参照してください。

これはモデルで動作し、promise を返します。したがって、使用方法が少し異なります。

book.save(function(err, book) {
    Book // Book not book
    .populate(book, { path: '_creator'})
    .then(function(book) {
        // Do something
    })
});

それが他の新人の助けになったことを願っています。

于 2018-07-19T21:09:42.543 に答える
1

残念ながら、これはマングースの長年の問題であり、まだ解決されていないと思います。

https://github.com/LearnBoost/mongoose/issues/570

あなたができることは、これのためにあなた自身のカスタムゲッター/セッターを書くことです(そして、別のプロパティで実数を設定します)。 _customer例えば:

var get_creator = function(val) {
    if (this.hasOwnProperty( "__creator" )) {
        return this.__creator;
    }
    return val;
};
var set_creator = function(val) {
    this.__creator = val;
    return val;
};
var bookSchema = new mongoose.Schema({
  _creator: {
     type: mongoose.Schema.Types.ObjectId,
     ref: 'User',
     get: get_creator,
     set: set_creator
  },
  description: String,
});

注:私はそれをテストしていません.populate.純粋なIDを設定すると、奇妙に動作する可能性があります.

于 2012-11-23T10:10:30.383 に答える
0

おそらくsth。お気に入り

Book.createAsync(bookToSave).then((savedBook) => savedBook.populateAsync("creator"));

これを機能させるには、最も適切で問題の少ない方法です (Bluebird の約束を使用する)。

于 2017-01-05T16:33:52.907 に答える
-1

ここに新しいものを追加するつもりはありません。

これは、async/await を使用してこれを記述する単純な方法です。

const newCourse = new Course(new_course_data);
const populate_options = [
  // Here write your populate options
];
const created_course = await newCourse.save();
await created_course.populate(populate_options).execPopulate();
于 2021-06-13T10:52:29.413 に答える