node.js - Mongoose : associate a . 项目(聚合)与 .find().limit().sort() 等

标签 node.js mongodb mongoose

我有一个看起来像这样的 Mongoose 模式:

var AnswerSchema = new Schema({
  author: {type: Schema.Types.ObjectId, ref: 'User'},
  likes: [{type: Schema.Types.ObjectId, ref: 'User'}],
  date: {type: Date, default: Date.now},
  text: String,
  ....
});

截至目前,我通过执行以下操作查询此集合:

Answer.find({
    author: profileId,
    date: {$lt: fromDate}
  }).sort({date: -1})
    .limit(25)
    .populate('question.sender', 'username username_display name')
    .exec(function (err, answers) {
        *code here*
    });

但由于聚合管道,我需要在此查询中添加一个计算字段以了解访问者是否已经喜欢作者的答案(请参阅 this question)。它看起来像这样:

Answer.aggregate()
    .project({
        "author": 1,            
        "matched": {
            "$eq": [ 
                { 
                    "$size": { 
                        "$ifNull": [
                            { "$setIntersection": [ "$likes", [userId] ] }, 
                            []
                        ] 
                    } 
                },
                1
            ]
        }
    })
    .exec(function (err, docs){
        console.log(docs);
    })

问题是:我只需要在第一个查询过滤的文档上运行这个投影。换句话说,我需要将查找/限制/排序与项目结合起来。

我该怎么做?我试过在第一个查询之后(在 .exec() 之前)链接 .project(),但它不起作用。也许我需要通过 mongodb 的聚合链来完成我在第一个查询中所做的所有事情?

编辑: 这是一个数据集的例子来尝试这个:

{
    "_id" : ObjectId("56334295e45552c018fc475d"),
    "author" : ObjectId("561f9c319cdd94401ae160ef"),
    "likeCount" : 1,
    "likes" : [ 
        ObjectId("561f9c319cdd94401ae160ef")
    ],
    "text" : "This is the answer content",
    "question" : {
        "questionId" : ObjectId("56334031e45552c018fc4757"),
        "sender" : ObjectId("561f9c319cdd94401ae160ef"),
        "date" : ISODate("2015-10-30T10:02:25.323Z")
    },
    "date" : ISODate("2015-10-30T10:12:37.894Z")
},
{
    "_id" : ObjectId("563246cfa04c1b281b6d97bf"),
    "author" : ObjectId("561f9c319cdd94401ae160ef"),
    "likeCount" : 0,
    "likes" : [],
    "text" : "Bla bla bla",
    "question" : {
        "questionId" : ObjectId("562f9a74a16d6fb418752b37"),
        "sender" : ObjectId("561f9c319cdd94401ae160ef"),
        "date" : ISODate("2015-10-27T15:38:28.337Z")
    },
    "date" : ISODate("2015-10-29T16:18:23.020Z")
}

最佳答案

使用聚合流式 API 的链接方法 match() , sort() + limit() project() 之前方法:

Answer.aggregate()
    .match({
        "author": profileId,
        "date": { "$lt": fromDate }
    })
    .sort("-date")
    .limit(25)
    .project({
        "author": 1, "question.sender": 1,          
        "matched": {
            "$eq": [ 
                { 
                    "$size": { 
                        "$ifNull": [
                            { "$setIntersection": [ "$likes", [userId] ] }, 
                            []
                        ] 
                    } 
                },
                1
            ]
        }
    })
    .exec(function (err, docs){
        if (err) throw err;
        console.log(docs);
        var answers = docs.map(function(doc) { return new Answer(doc); });
        Answer.populate(answers, { 
                "path": "question.sender",
                "select": "username username_display name"
            }, function(err, results) {
            if (err) throw err;
            console.log(JSON.stringify(results, undefined, 4 ));
            res.json(results);
        });         
    });

关于node.js - Mongoose : associate a . 项目(聚合)与 .find().limit().sort() 等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33919755/

相关文章:

node.js - 如何通过具有不同状态代码的 Nock 对同一 url 进行后续调用

node.js - 204 错误代码然后 500 错误代码响应

javascript - 未捕获错误 : EPERM: operation not permitted, 写入

node.js - 无法理解 package.json 的命令行脚本

c# - MongoDB 的 C# 驱动程序中的 BSON 序列化

node.js - 如何在 mongoose hook 中保存 userId?

node.js - 按价格对 Mongodb 数据排序

node.js - 如何让 node.js 使用 mongoose 连接到 mongolab

mongodb - 从 fs.files 中投影一列

mongodb - 在 mongodb 中对推送的数组进行排序