Node.js MongoDB:查询模型,检查单据是否包含对象,然后标记/分组结果

Node.js MongoDB:查询模型,检查单据是否包含对象,然后标记/分组结果,node.js,mongodb,mongoose,Node.js,Mongodb,Mongoose,我有一个名为Post的模型,它包含一个属性数组,其中包含了喜欢这篇文章的用户ID 现在,我需要查询post模型,并将返回的结果标记为likedBySelf true/false,以供客户端使用-这可能吗 我不必将likedBySelf属性存储在数据库中,只需修改结果以获得该属性 我找到的一个临时解决方案是执行两个查询,一个查询查找用户x喜欢的帖子,另一个查询查找用户x不喜欢的帖子,然后使用en-map设置likedBySelf true/false组合这两个数组并返回组合的数组。但这给其他查询函

我有一个名为Post的模型,它包含一个属性数组,其中包含了喜欢这篇文章的用户ID

现在,我需要查询post模型,并将返回的结果标记为likedBySelf true/false,以供客户端使用-这可能吗

我不必将likedBySelf属性存储在数据库中,只需修改结果以获得该属性

我找到的一个临时解决方案是执行两个查询,一个查询查找用户x喜欢的帖子,另一个查询查找用户x不喜欢的帖子,然后使用en-map设置likedBySelf true/false组合这两个数组并返回组合的数组。但这给其他查询函数(如limit和skip)带来了一些限制

现在我的查询如下所示:

var notLikedByQuery = Post.find({likedBy: {$ne: req.body.user._id}})
var likedByQuery = Post.find({likedBy: req.body.user._id})
我用的是猫鼬库

PS.一篇典型的帖子可以像这样:

{
    "_id": {
        "$oid": "55fc463c83b2d2501f563544"
    },
    "__t": "Post",
    "groupId": {
        "$oid": "55fc463c83b2d2501f563545"
    },
    "inactiveAfter": {
        "$date": "2015-09-25T17:13:32.426Z"
    },
    "imageUrl": "https://hootappprodstorage.blob.core.windows.net/devphotos/55fc463b83b2d2501f563543.jpeg",
    "createdBy": {
        "$oid": "55c49e2d40b3b5b80cbe9a03"
    },
    "inactive": false,
    "recentComments": [],
    "likes": 8,
    "likedBy": [
        {
            "$oid": "558b2ce70553f7e807f636c7"
        },
        {
            "$oid": "559e8573ed7c830c0a677c36"
        },
        {
            "$oid": "559e85bced7c830c0a677c43"
        },
        {
            "$oid": "559e854bed7c830c0a677c32"
        },
        {
            "$oid": "559e85abed7c830c0a677c40"
        },
        {
            "$oid": "55911104be2f86e81d0fb573"
        },
        {
            "$oid": "559e858fed7c830c0a677c3b"
        },
        {
            "$oid": "559e8586ed7c830c0a677c3a"
        }
    ],
    "location": {
        "type": "Point",
        "coordinates": [
            10.01941398718396,
            60.96738099591897
        ]
    },
    "updatedAt": {
        "$date": "2015-09-22T08:45:41.480Z"
    },
    "createdAt": {
        "$date": "2015-09-18T17:13:32.426Z"
    },
    "__v": 8
}

@tskippe您可以使用如下方法来处理用户是否喜欢帖子,并在您想要的任何地方调用函数

var processIsLiked = function(postId, userId, doc, next){
  var q = Post.find({post_id: postId});
  q.lean().exec(function(err,res){
    if(err) return utils.handleErr(err, res);
    else {
       if(_.find(doc.post.likedBy,userId)){ //if LikedBy array contains the user
          doc.post.isLiked = true;
        } else {
          doc.post.isLiked = false;
        }
      });
      next(doc);
    }
  });
}

因为您使用的是q.lean,所以不需要实际持久化数据。您只需处理它,在帖子中添加isLiked字段并发送回响应**请注意,我们是直接生产的。您还可以将其转换为接受包含帖子数组的文档,并对其进行迭代,然后将一个islike字段附加到每个帖子

我发现MongoDB与$project tequnique的聚合是我最好的选择。所以我写了一个这样的聚合

说明: 由于我希望保留整个文档,但$project的目的是修改文档,因此您必须指定要保留的属性。保存所有属性的一种简单方法是使用$$ROOT

因此,我定义了一个$project,将所有原始属性设置为doc:$$ROOT,然后创建一个新属性likedBySelf,如果指定的USERID在$likedBy集中,则该属性被标记为true/false

我认为这比在查询后查询每个模型以设置likedBySelf标志更干净、更简单。它可能不会更快,但会更干净

Model.aggregate([
        { $project: {
            doc: "$$ROOT",
            likedBySelf: {
                $cond: {
                    "if": { "$setIsSubset": [
                        [USERID],
                        "$likedBy"
                    ]},
                    "then": true,
                    "else": false
                }
            }
        }}
    ]);

你能为你的收藏提供json吗?@HarshPatel我现在在问题中包含了一个json示例。如果我的情况是每次只需要标记一篇文章,这将非常有用。但是我想做一个查询,得到几个文档,并同时标记它们。如果是这样的话,正如我在回答中所说的,你可以稍微看一下。获取所有你需要的文档,我猜你会有一系列的帖子。然后将此postid数组作为参数传递给process函数,您将返回相同的post数组,其中包含一个isLiked为true或false的附加字段。如果这是需要的话。var q=Post.find{Post:{$in:postIds};然后执行查询,您可以对结果运行forEach循环,并对每个objectsye应用islike检查,这也可以工作,但我希望您可以在一个查询中完成所有操作。检查我的答案,我已经发布了一个聚合函数,可以满足我的需要。