【问题标题】:NodeJS aggregate on 2 specific filtersNodeJS 在 2 个特定的过滤器上聚合
【发布时间】:2017-02-13 03:14:57
【问题描述】:

我有 2 个模型,一个称为关注者,一个称为时间线。我想要做的是获取关注者时间线,并根据关注者包含的键过滤该时间线内的帖子。

这是我的模型:

var followerSchema = new Schema({
    followee: { type: Schema.ObjectId, ref: 'User' },
    follower: { type: Schema.ObjectId, ref: 'User' },
    accepted: Boolean,
    branches: [],
    date: { type: Date, default: Date.now }
});

var timelineSchema = new Schema({
    user: { type: Schema.ObjectId, ref: 'User' },
    posts: [],
});

这是填充模型的样子:

[{ 
    _id: 58a086dc3884d9ddfb65bad8,
    accepted: true,
    follower: 58a086293884d9ddfb65bad2,
    followee: 58a086923884d9ddfb65bad5,
    __v: 0,
    date: Sun Feb 12 2017 11:01:32 GMT-0500 (EST),
    branches: [ 2, 5 ]
 }, ...]

{ 
  _id: '58a086293884d9ddfb65bad3',
  user: '58a086293884d9ddfb65bad2',
  __v: 0,
  posts: [ 
     { date: 1486915113883,
       branch: '-1',
       txt: 'hello 0'},
     { date: 1486915142820,
       branch: '1',
       txt: 'hello 1' },
     { date: 1486915265607,
       branch: '2',
       txt: 'hello 2' } 
  ]
}

目前我正在使用此代码来汇总时间线。

Follower.find({
    followee: req.params.user_id, 
    accepted: true
}, function(err, followees) {
    if (err)
        res.json(err);

    // Create a date 3 days past current date
    var d = new Date();
    d.setDate(d.getDate() - 3);

    // Gets all timelines of the followees and their newest posts
    Timeline.aggregate([
        { $match: { user: {$in : followees.map(function(x) {return x.follower;}) } }},
        { $unwind: '$posts'},
        { $match: {'posts.date': {$gte: d.getTime() } } },
        { $match: {'posts.branch': {$in : ['1', '2', '5']} } }, // <--- this array should be that equal to the followers branches
        { $group: {
                '_id':'$_id',
                'user' : {'$first': '$user'},
                'posts': {'$push': '$posts'} 
            } 
        }
    ]).exec(function(err, timeline) {

        console.log(timeline)

        // Populate the user
        User.populate(timeline, {path: 'user'}, function(err, tt) {
            if (err) 
                res.json(err);

            res.json(timeline);
        })
    });
});

此查询为我获取了关注者的所有帖子,但我只想要分支位于关注者分支中的帖子。

不知何故,我认为我必须改变这一行

{ $match: {'posts.branch': {$in : ['1', '2', '5']} } }

但是以某种方式将数组替换为当前追随者的分支。

我正在寻找的预期 JSON 输出如下:

{
    "_id" = 58a086293884d9ddfb65bad3;
    posts = [{
            branch = 1,
            date = 1486915142820,
            txt = "hello 0"
        },
                    {
            branch = 2,
            date = 1486915265607,
            txt = "hello 2",
        }
    ],
    user = {
        "__v" = 0;
        "_id" = 58a086293884d9ddfb65bad2,
        date = "2017-02-12T15:58:33.861Z",
        email = "email@google.com",
        handle = "m",
        password = "m",
    }
}

【问题讨论】:

  • 您能否展示一个预期的 JSON 输出示例?

标签: node.js mongodb mongoose mongodb-query aggregation-framework


【解决方案1】:

您可以使用$lookup 创建与关注者集合的连接,展开直到通过 $lookup 创建的新字段中的分支数组,然后基于分支进行分组。

这样,您将拥有特定于关注者集合中分支的用户、帖子。

// Gets all timelines of the followees and their newest posts
Timeline.aggregate([
    { $match: { user: {$in : followees.map(function(x) {return x.follower;}) } }},
    { $unwind: '$posts'},
    { $match: {'posts.date': {$gte: d.getTime() } } },
    { $lookup: { 
                 from: "followers",
                 localField: "user",
                 foreignField: "follower",
                 as: "fNew"
               }
    },
    { $unwind: "fNew" },
    { $unwind: "fNew.branches" },
    { $unwind: "posts" },
    { $project: {"isBranchSame":{$eq:["$posts.branch","$fNew.branches"]},"otherFieldsToProject":1}},
    { $match: {"isBranchSame":true}},
    { $group: {
            '_id': "$_id",
            'user' : {'$first': '$user'},
            'posts': {'$push': '$posts'} 
        } 
    }
])

【讨论】:

  • 我试图实现这一点,结果我会得到undefined。我将 2 $unwind 的值更改为 $fNew$fNew.branches,然后只返回一个空数组。想法?
  • @RockPaperScissors 我已经编辑了处理相等性的答案,试一试,在项目阶段添加字段以用于分组
猜你喜欢
  • 1970-01-01
  • 2018-06-24
  • 2018-06-16
  • 2014-12-11
  • 1970-01-01
  • 1970-01-01
  • 2017-01-18
  • 2015-09-17
  • 2014-02-02
相关资源
最近更新 更多