programing

저장 후 Mongoose 입력

testmans 2023. 4. 5. 21:24
반응형

저장 후 Mongoose 입력

새로 저장된 개체의 생성자 필드를 수동으로 또는 자동으로 채울 수 없습니다.내가 찾을 수 있는 유일한 방법은 내가 이미 가지고 있는 내가 하고 싶지 않은 것들을 다시 쿼리하는 것이다.

설정은 다음과 같습니다.

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?
    });
});

편집: 최신 mongoose에서 이 문제를 수정하고 입력 기능을 추가했습니다.새로운 답변이 받아들여졌습니다.

모델 입력 기능을 사용하여 다음 작업을 수행할 수 있습니다. http://mongoosejs.com/docs/api.html#model_Model.populate 을 위한 저장 핸들러에서 다음을 수행할 수 있습니다.

book._creator = user;

다음과 같은 행동을 할 수 있습니다.

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

당신을 돕기엔 너무 늦은 답변일 수도 있지만, 최근에 이 일에 매달려서 다른 사람들에게 도움이 될 수도 있어요.

제가 해결한 방법은execPopulate 것 같아

const t = new MyModel(value)
return t.save().then(t => t.populate('my-path').execPopulate())

이걸 찾는 사람이 아직 있을지도 모르니까

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;

약속을 반환하는 솔루션(콜백 없음):

Document #를 사용합니다.

book.populate('creator').execPopulate();

// summary
doc.populate(options);               // not executed
doc.populate(options).execPopulate() // executed, returns promise

구현 가능성

var populatedDoc = doc.populate(options).execPopulate();
populatedDoc.then(doc => {
   ... 
});

문서 작성에 대한 자세한 내용은 여기를 참조하십시오.

나처럼 완벽한 노브스를 위해 이걸 좀 더 설명해야겠어

주의하지 않으면 매우 혼란스러운 것은 세 가지 매우 다른 입력 방법이 있다는 것입니다.이들은 다른 객체의 메서드입니다(모델과)입니다.문서), 다른 입력 및 다른 출력(문서 vs.약속).

다음은 당황한 분들을 위한 것입니다.

Document.protype.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.protype.populate()는 문서를 반환하기 때문에 이는 말도 안 됩니다.약속을 원한다면, 당신은...

Document.protype.exec Populate()

자세한 내용은 문서를 참조하십시오.

이것은 문서에서 작동하지만 문서에 대한 확약을 반환합니다.즉, 다음과 같이 사용할 수 있습니다.

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

그게 더 낫네.드디어...

Model.populate()

자세한 내용은 문서를 참조하십시오.

이건 모델 작업도 하고 약속도 돌려주죠따라서 조금 다르게 사용됩니다.

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

그게 다른 신입사원들에게 도움이 됐으면 좋겠네요.

제가 도움이 됐기 때문에 다른 예를 들어 설명하겠습니다.저장 후 부분적으로 채워진 개체를 검색하려는 사용자에게 도움이 될 수 있습니다.방법도 조금 다릅니다.한 두 시간 넘게 올바른 방법을 찾아다녔어

  post.save(function(err) {
    if (err) {
      return res.json(500, {
        error: 'Cannot save the post'
      });
    }
    post.populate('group', 'name').populate({
      path: 'wallUser',
      select: 'name picture'
    }, function(err, doc) {
      res.json(doc);
    });
  });

나는 효과가 있다

    let post = await PostModel.create({
        ...req.body, author: userId
    })

    post = await post.populate('author', 'name')

    res.status(200).json({
        status: 'success',
        data: { post }
    })

불행히도 이것은 몽구스에 관한 오래된 문제이며, 저는 아직 해결되지 않았다고 생각합니다.

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

커스텀 getter/setter(및 리얼 설정)를 작성할 수 있습니다. _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순수한 아이디를 설정할 때.

몽구스 5.2.7

이것으로 충분합니다(두통이 심합니다!).

exports.create = (req, res, next) => {
  const author = req.userData;
  const postInfo = new Post({
    author,
    content: req.body.content,
    isDraft: req.body.isDraft,
    status: req.body.status,
    title: req.body.title
  });
  postInfo.populate('author', '_id email role display_name').execPopulate();
  postInfo.save()
    .then(post => {
      res.status(200).json(post);
    }).catch(error => {
      res.status(500).json(error);
    });
};

아마 뭔가.맘에 들다

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

이 작업을 수행할 수 있는 가장 좋은 방법(Bluebird 사용 약속)이 될 것입니다.

스키마, query_adapter, data_adapter 함수를 선언하고 문자열을 미리 입력하는 커리 가능한 Promise 함수를 작성하게 되었습니다.보다 단시간에, 보다 간단하게 실장할 수 있습니다.

아마 매우 효율적이진 않겠지만, 나는 그 실행이 꽤 우아하다고 생각했다.

github 파일: curry_Promise.js

분리

const update_or_insert_Item = mDB.update_or_insert({
    schema : model.Item,
    fn_query_adapter : ({ no })=>{return { no }},
    fn_update_adapter : SQL_to_MDB.item,
    populate : "headgroup"
    // fn_err : (e)=>{return e},
    // fn_res : (o)=>{return o}
})

실행

Promise.all( items.map( update_or_insert_Item ) )
.catch( console.error )
.then( console.log )

문서를 모델에 저장한 후 채우기

   chatRoom = await chatRoom.save();
   const data = await chatRoom
  .populate("customer", "email dp")
  .populate({
    path: "admin",
    select: "name logo",
  })
  .execPopulate();

Mongoose 6.x에서는 다음 작업을 간단히 수행할 수 있습니다.

const t = await MyModel.create(value).then((t) =>
  t.populate('my-path')
);

execPopulate()메서드는 삭제되었습니다.

아무것도 효과가 없었기 때문에 저장 후 findById를 사용하여 데이터를 다시 불러왔습니다.

const data: any = await Model.findById(id)
  .populate("name")
  

비동기/대기 기능을 사용하여 poople을 실행하는 방법은 다음과 같습니다.

const updatedBook = await book.save()
const populatedBook = await updatedBook.populate('field', { name: 1, author: 1, field3: 1})

어디에fieldName: 1는 '필드'에서 입력할 필드를 나타냅니다.

약속이라면 아마 다음과 같을 것입니다.

book.save()
  .then(savedBook => savedBook.populate())
  .then(populatedBook => populatedBook)

나는 여기에 새로운 것을 추가하지 않을 것이다.

비동기/대기 기능을 사용하여 보다 깔끔하게 작성할 수 있습니다.

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();

언급URL : https://stackoverflow.com/questions/13525480/mongoose-populate-after-save

반응형