Lemme花时间解释从开始到结束发生的事情。
序言:
用户a跟随其他10个人。当用户A登录时,来自10个人中的每个人的X个帖子被拉入视野。
我不知道这是否是正确的做法,并会欣赏更好的方法。但是,我想尝试一下,它无法正常工作。
关注模式:
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);
卡片型号
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);
遵循逻辑
当用户A跟随用户B时,请执行以下两项操作:
将A的user_id推送到字段'关注者'上的用户B文档。 (B后跟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'
})
})
})
实际数据库值
> 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")
]
}
>
使用上面的数据库结果,这是我的查询:
查询
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
})
})
});
通过上述查询,从我对Mongoose populate的一点了解,我希望从following
数组中的每个用户获取卡片。
我的理解和期望可能是错误的,但是有了这样一个结局,这种填充方法是否可以?或者我是否尝试用人口来解决聚合任务?
更新
感谢您的回答。尽管如此,followingCards
数组仍然没有结果。这是我当前Follow
模型的内容:
> 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")
]
}
>
以下是Card
模型中的所有当前内容:
> db.cards.find().pretty()
{
"_id" : ObjectId("59f24bc01d048d1edad4bda6"),
"title" : "A day or two with Hubtel's 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
}
使用您的Populate Virtual示例(@Veeram),我得到的回复是:
{"state":true,"msg":"Follow list","doc":{"_id":"59f24c0555ee5a5897e1b23d","user":"59f24bda1d048d1edad4bda8","following":["59f24b3a55ee5a5897e1b1ec","59f24bda55ee5a5897e1b22c"],"followers":[],"id":"59f24c0555ee5a5897e1b23d","followingCards":[]}}
followingCards
数组为空。
另一方面,使用$lookup
查询只会返回[]
我可能错过了什么?
答案 0 :(得分:2)
您可以在聚合管道中使用虚拟填充或executable=
运算符。
使用Virtual Populate
$lookup
使用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));
});
聚合
$lookup
答案 1 :(得分:0)
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);
要显示如何使用填充,请先创建一个人物对象
aaron = new Person({firstname: 'Aaron'}) and an event object,
event1 = new Event({title: 'Hackathon', location: 'foo'}):
aaron.eventsAttended.push(event1);
aaron.save(callback);
然后,当您进行查询时,可以填充这样的引用:
Person
.findOne({ firstname: 'Aaron' })
.populate('eventsAttended') .exec(function(err, person) {
if (err) return handleError(err);
console.log(person);
});
//只有在我们将refs推送到person.eventsAttended
时才有效答案 2 :(得分:0)
注意:将Activity.find更改为Card.find
const { ObjectID } = require("mongodb");
// import Follow and Activity(Card) schema
const userId = req.tokenData.userId; // edit this too...
Follow.aggregate([
{
$match: {
user: ObjectID(userId)
}
}
])
.then(data => {
// console.log(data)
var dataUsers = data[0].following.map(function(item) {
return item._id;
});
// console.log(dataUsers)
Activity.find(
{ createdById: { $in: dataUsers } },
{
_id: 1,
title: 1,
content: 1,
createdBy: 1,
creatorAvatar: 1,
activityType: 1,
createdAt: 1
}
)
// .sort({createdAt:-1)
.then(posts => res.send({ posts }));
});