মঙ্গুজ সংরক্ষণের পরে পপুলেশন করুন


99

আমি নতুনভাবে সংরক্ষিত অবজেক্টে আমি ম্যানুয়ালি বা স্বয়ংক্রিয়ভাবে স্রষ্টার ক্ষেত্রকে পপুলেট করতে পারি না ... আমি খুঁজে পাবার একমাত্র উপায় হ'ল আমার কাছে ইতিমধ্যে থাকা অবজেক্টগুলির পুনরায় জিজ্ঞাসা করা যা আমি করতে ঘৃণা করি।

এটি সেটআপ:

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

সম্পাদনা: সর্বশেষতম মঙ্গুজ এই সমস্যাটিকে সংশোধন করেছে এবং জনসাধারণের কার্যকারিতা যুক্ত করেছে, নতুন গৃহীত উত্তর দেখুন।

উত্তর:


140

এটি করার জন্য আপনার মডেলের পপুলেট ফাংশনটি ব্যবহার করতে সক্ষম হওয়া উচিত: http://mongoosejs.com/docs/api.html#model_Model.populate বইয়ের জন্য সংরক্ষণের হ্যান্ডলারের পরিবর্তে:

book._creator = user;

আপনি যেমন কিছু করতে চাই:

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

আপনাকে সাহায্য করার জন্য সম্ভবত খুব দেরি করা উত্তর, তবে আমি সম্প্রতি এটিতে আটকে গিয়েছিলাম এবং এটি অন্যের পক্ষে কার্যকর হতে পারে।


এটি ভার্চুয়াল বৈশিষ্ট্যগুলির সাথে কাজ করলে ভাল হবে be পছন্দcreator.profile
চবি

যদি ব্যবহারকারীর কিছু ভার্চুয়াল বৈশিষ্ট্য থাকে তবে সেগুলি অন্তর্ভুক্ত নয়।
chovy

এটি আমার পক্ষে কাজ করেছে যদিও আমি সংরক্ষণ করার ঠিক আগে রেফারেন্সটি বাতিল করার চেষ্টা করার সময় আমার কিছু সমস্যা হয়েছিল। সেভের পরে, Book.populate কল করার পরে পূর্ববর্তী রেফারেন্স মানটি ফিল্ডকে ভুলভাবে জনবহুল করেছে এবং কেন আমি তা কার্যকর করতে পারছি না। ডিবি সফলভাবে নালটি ধারণ করে।
ড্যানিয়েল ফ্লিপ্যান্স

4
এবং এটি ডাটাবেস পুনরায় জিজ্ঞাসা করবে না ?!
নেপক্সক্স

9
এটি ডাটাবেসটি পুনরায় জিজ্ঞাসা করছে
বুবকাজোবা

37

যে কেউ যদি এখনও এটি খুঁজছেন।

মঙ্গুজ ৩.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- অনুগ্রহ করে- দ্রষ্টব্য # জনসংখ্যা

তবে এইভাবে আপনি আবার ব্যবহারকারীর জন্য জিজ্ঞাসা করবেন।

অতিরিক্ত প্রশ্ন ছাড়াই এটি সম্পাদন করার জন্য একটি ছোট কৌশলটি হ'ল:

book = book.toObject();
book._creator = user;

করছেন book._creator = user;পরে save()সমস্ত বর্তমান উত্তর মধ্যে শুধুমাত্র সঠিক উত্তর, সব অন্যান্য উত্তর একটি অতিরিক্ত ক্যোয়ারী প্রয়োজন।
Mr5o1

25

আমার জন্য সমাধানটি ব্যবহার করা ছিল execPopulate, তেমন

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

4
ফ্র্যাঙ্কোইসকে অনেক ধন্যবাদ, আপনি আমার জীবন বাঁচিয়েছিলেন, আমি এর সমাধান খুঁজতে চেষ্টা করছিলাম। পেলাম।
রূপেশ

22

সমাধান যা প্রতিশ্রুতি দেয় (কোনও কলব্যাক নেই):

নথি # পপুলেট ব্যবহার করুন

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

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

সম্ভাব্য বাস্তবায়ন

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

এখানে নথির জনসংখ্যা সম্পর্কে পড়ুন ।


ভাল জিনিস. ধন্যবাদ
জোয়েল এইচ

11

এটি কেবল আমাকে ব্যাখ্যা করতে এবং আরও একটি উদাহরণ দেওয়ার জন্য। এটি সংরক্ষণের পরে আংশিক জনবহুল বস্তু পুনরুদ্ধার করতে তাদের সহায়তা করতে পারে। পদ্ধতিটিও কিছুটা আলাদা। এটি করার সঠিক উপায়টি অনুসন্ধান করতে এক বা দুই ঘন্টা বেশি সময় ব্যয় করেছেন।

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

9

আমি ভেবেছিলাম আমি নিজের মতো সম্পূর্ণ noobs এর জন্য বিষয়গুলি পরিষ্কার করতে এটি যুক্ত করব।

আপনি যদি সাবধান না হন তবে বৃহত্তর বিভ্রান্তিকর বিষয়টি হ'ল তিনটি পৃথক জনবস্তু পদ্ধতি রয়েছে। এগুলি হ'ল বিভিন্ন অবজেক্টের (মডেল বনাম ডকুমেন্ট) পদ্ধতি, বিভিন্ন ইনপুট নেয় এবং বিভিন্ন আউটপুট দেয় (নথি বনাম প্রতিশ্রুতি)।

বিস্মিত তাদের জন্য এখানে:

ডকুমেন্ট.প্রোটোটাইপ.পপুলেট ()

সম্পূর্ণ ডক্স দেখুন।

এটি একটি নথিতে কাজ করে এবং একটি নথি ফেরত দেয়। মূল উদাহরণে, এটি দেখতে এরকম হবে:

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

মনে রাখবেন: ডকুমেন্ট.প্রোটোটাইপ.পপুলেট () একটি দস্তাবেজ ফেরত দেয়, সুতরাং এটি আজেবাজে কথা। যদি আপনি কোন প্রতিশ্রুতি চান, আপনার প্রয়োজন ...

ডকুমেন্ট.প্রোটোটাইপ.অ্যাকেকপুলেট ()

সম্পূর্ণ ডক্স দেখুন।

এটি নথিতে কাজ করে তবে এটি একটি প্রতিশ্রুতি দেয় যা দস্তাবেজের সমাধান করে। অন্য কথায়, আপনি এটি ব্যবহার করতে পারেন:

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

এটা ভাল. অবশেষে, এখানে ...

মডেল.পপুলেট ()

সম্পূর্ণ ডক্স দেখুন।

এটি মডেলগুলিতে কাজ করে এবং প্রতিশ্রুতি দেয়। সুতরাং এটি কিছুটা আলাদাভাবে ব্যবহৃত হয়:

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

আশা করি এটি কিছু নতুন আগতদের সহায়তা করেছে।


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এবং খাঁটি আইডি সেট করার সময় এটি অদ্ভুতভাবে কাজ করতে পারে ।


দেখে মনে হচ্ছে তারা এই সমস্যাটি সমাধান করতে চাইছেন না।
পাইকলার

4
এই সমস্যাটি 3.6
এমকোরিয়াক

@ পাইক্লারকে আপনার অবশ্যই সত্যিকারের আগে সর্বাধিক রেট দেওয়া উত্তরটির পরিবর্তন করতে হবে, কারণ এই উত্তরটি আর কার্যকর নয়
ম্যাট ফ্লেচার

1

মঙ্গুজ 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);
    });
};

0

সম্ভবত sth। পছন্দ

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

এই কাজটি করার সবচেয়ে দুর্দান্ত এবং সর্বনিম্ন সমস্যাযুক্ত উপায় (ব্লুবার্ড প্রতিশ্রুতি ব্যবহার করে)।


0

কিছু তরকারী-সক্ষম প্রতিশ্রুতি ফাংশনগুলি লিখে শেষ করে যেখানে আপনি আপনার স্কিমা, ক্যোয়ারী_ডাপ্টার, ডেটা_অ্যাডাপ্টার ফাংশন এবং অগ্রিম স্ট্রিং পপুলেটে ঘোষণা করেন। আরও ছোট / সহজ প্রয়োগের জন্য আরও সহজ।

এটি সম্ভবত সুপার দক্ষ নয়, তবে আমি ভেবেছিলাম মৃত্যুদন্ড কার্যকর করাটা বেশ মার্জিত ছিল।

গিথুব ফাইল: কারি_প্রোমস.জে

ঘোষণা

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 )
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.