Fill in the following mongoose users

The lemma needs time to explain what is going on from beginning to end.

Preamble

User a follows 10 other people. When user A registers, X appears the number of messages from each of 10 people.

I do not know if this is the right thing to do, and I will appreciate the best way to do it. However, I want to try and it does not work.

Follow the model :

let mongoose = require('mongoose'); let Schema = mongoose.Schema; let FollowSchema = new Schema({ user: { type: Schema.Types.ObjectId, ref: 'User' }, followers: [{ type: Schema.Types.ObjectId, ref: 'Card' }], following: [{ type: Schema.Types.ObjectId, ref: 'Card' }] }); module.exports = mongoose.model('Follow', FollowSchema); 

Card model

 let mongoose = require('mongoose'); let Schema = mongoose.Schema; let CardSchema = new Schema({ title: String, content: String, createdById: { type: Schema.Types.ObjectId, ref: 'User' }, createdBy: { type: String } }); module.exports = mongoose.model('Card', CardSchema); 

Follow the logic

When user A follows user B, do two things:

  • Press user_id of B on the user. The document in the "Next" field (A corresponds to B).
  • Press user_id from A to user B's document at field subscribers (followed by A)

     router.post('/follow', utils.loginRequired, function(req, res) { const user_id = req.user._id; const follow = req.body.follow_id; let bulk = Follow.collection.initializeUnorderedBulkOp(); bulk.find({ 'user': Types.ObjectId(user_id) }).upsert().updateOne({ $addToSet: { following: Types.ObjectId(follow) } }); bulk.find({ 'user': Types.ObjectId(follow) }).upsert().updateOne({ $addToSet: { followers: Types.ObjectId(user_id) } }) bulk.execute(function(err, doc) { if (err) { return res.json({ 'state': false, 'msg': err }) } res.json({ 'state': true, 'msg': 'Followed' }) }) 

    })

Actual DB Values

 > db.follows.find().pretty() { "_id" : ObjectId("59e3e27dace1f14e0a70862d"), "user" : ObjectId("59e2194177cae833894c9956"), "following" : [ ObjectId("59e3e618ace1f14e0a708713") ] } { "_id" : ObjectId("59e3e27dace1f14e0a70862e"), "user" : ObjectId("59e13b2dca5652efc4ca2cf5"), "followers" : [ ObjectId("59e2194177cae833894c9956"), ObjectId("59e13b2d27cfed535928c0e7"), ObjectId("59e3e617149f0a3f1281e849") ] } { "_id" : ObjectId("59e3e71face1f14e0a708770"), "user" : ObjectId("59e13b2d27cfed535928c0e7"), "following" : [ ObjectId("59e3e618ace1f14e0a708713"), ObjectId("59e13b2dca5652efc4ca2cf5"), ObjectId("59e21942ca5652efc4ca30ab") ] } { "_id" : ObjectId("59e3e71face1f14e0a708771"), "user" : ObjectId("59e3e618ace1f14e0a708713"), "followers" : [ ObjectId("59e13b2d27cfed535928c0e7"), ObjectId("59e2194177cae833894c9956") ] } { "_id" : ObjectId("59e3e72bace1f14e0a708779"), "user" : ObjectId("59e21942ca5652efc4ca30ab"), "followers" : [ ObjectId("59e13b2d27cfed535928c0e7"), ObjectId("59e2194177cae833894c9956"), ObjectId("59e3e617149f0a3f1281e849") ] } { "_id" : ObjectId("59f0eef155ee5a5897e1a66d"), "user" : ObjectId("59e3e617149f0a3f1281e849"), "following" : [ ObjectId("59e21942ca5652efc4ca30ab"), ObjectId("59e13b2dca5652efc4ca2cf5") ] } > 

With the database results above, this is my query:

Query

 router.get('/follow/list', utils.loginRequired, function(req, res) { const user_id = req.user._id; Follow.findOne({ 'user': Types.ObjectId(user_id) }) .populate('following') .exec(function(err, doc) { if (err) { return res.json({ 'state': false, 'msg': err }) }; console.log(doc.username); res.json({ 'state': true, 'msg': 'Follow list', 'doc': doc }) }) }); 

With the above request, from my little understanding of the Mongoose population, I expect to receive maps from each of the Users in the following array.

My understanding and expectations may be erroneous, however, with such an endgoal, is this approach with the population good? Or am I trying to solve the problem of population aggregation?

UPDATE:

Thanks for the answer. Close enough, but still the followingCards array does not contain a result. Here is the contents of my current Follow model:

 > db.follows.find().pretty() { "_id" : ObjectId("59f24c0555ee5a5897e1b23d"), "user" : ObjectId("59f24bda1d048d1edad4bda8"), "following" : [ ObjectId("59f24b3a55ee5a5897e1b1ec"), ObjectId("59f24bda55ee5a5897e1b22c") ] } { "_id" : ObjectId("59f24c0555ee5a5897e1b23e"), "user" : ObjectId("59f24b3a55ee5a5897e1b1ec"), "followers" : [ ObjectId("59f24bda1d048d1edad4bda8") ] } { "_id" : ObjectId("59f24c8855ee5a5897e1b292"), "user" : ObjectId("59f24bda55ee5a5897e1b22c"), "followers" : [ ObjectId("59f24bda1d048d1edad4bda8") ] } > 

Here is all the current content that I received from the Card Model:

 > db.cards.find().pretty() { "_id" : ObjectId("59f24bc01d048d1edad4bda6"), "title" : "A day or two with Hubtel HTTP API", "content" : "a day or two", "external" : "", "slug" : "a-day-or-two-with-hubtels-http-api-df77056d", "createdBy" : "seanmavley", "createdById" : ObjectId("59f24b391d048d1edad4bda5"), "createdAt" : ISODate("2017-10-26T20:55:28.293Z"), "__v" : 0 } { "_id" : ObjectId("59f24c5f1d048d1edad4bda9"), "title" : "US couple stole goods worth $1.2m from Amazon", "content" : "for what", "external" : "https://bbc.com", "slug" : "us-couple-stole-goods-worth-dollar12m-from-amazon-49b0a524", "createdBy" : "nkansahrexford", "createdById" : ObjectId("59f24bda1d048d1edad4bda8"), "createdAt" : ISODate("2017-10-26T20:58:07.793Z"), "__v" : 0 } 

With the Population Virtual example from your (@Veeram), here is the answer I get:

 {"state":true,"msg":"Follow list","doc":{"_id":"59f24c0555ee5a5897e1b23d","user":"59f24bda1d048d1edad4bda8","following":["59f24b3a55ee5a5897e1b1ec","59f24bda55ee5a5897e1b22c"],"followers":[],"id":"59f24c0555ee5a5897e1b23d","followingCards":[]}} 

The followingCards array is empty.

Using the $lookup query, on the other hand, just returns []

Most likely something is missing?

+5
source share
2 answers

You can use the virtual fill operator or $lookup in the aggregation pipeline.

Using virtual padding

 FollowSchema.virtual('followingCards', { ref: 'Card', localField: 'following', foreignField: 'createdById' }); Follow.findOne({ 'user': Types.ObjectId(user_id) }) .populate('followingCards') .exec(function(err, doc) { console.log(JSON.stringify(doc)); }); 

Using $lookup aggregation

 Follow.aggregate([ { "$match": { "user": Types.ObjectId(user_id) } }, { "$lookup": { "from": "cards", "localField": "following", "foreignField": "createdById", "as": "followingCards" } } ]).exec(function (err, doc) { console.log(JSON.stringify(doc)); }) 
+2
source
 var mongoose = require('mongoose'), Schema = mongoose.Schema var eventSchema = Schema({ title : String, location : String, startDate : Date, endDate : Date }); var personSchema = Schema({ firstname: String, lastname: String, email: String, dob: Date, city: String, eventsAttended: [{ type: Schema.Types.ObjectId, ref: 'Event' }] }); var Event = mongoose.model('Event', eventSchema); var Person = mongoose.model('Person', personSchema); 

To show how padding is used, first create a person object,

  aaron = new Person({firstname: 'Aaron'}) and an event object, event1 = new Event({title: 'Hackathon', location: 'foo'}): aaron.eventsAttended.push(event1); aaron.save(callback); 

Then, when you make your request, you can fill out the following links:

  Person .findOne({ firstname: 'Aaron' }) .populate('eventsAttended') .exec(function(err, person) { if (err) return handleError(err); console.log(person); }); 

// only works if we click refs on person.eventsAttended

0
source

Source: https://habr.com/ru/post/1272648/


All Articles