Node.js MongoDB:查询模型,检查单据是否包含对象,然后标记/分组结果
我有一个名为Post的模型,它包含一个属性数组,其中包含了喜欢这篇文章的用户ID 现在,我需要查询post模型,并将返回的结果标记为likedBySelf true/false,以供客户端使用-这可能吗 我不必将likedBySelf属性存储在数据库中,只需修改结果以获得该属性 我找到的一个临时解决方案是执行两个查询,一个查询查找用户x喜欢的帖子,另一个查询查找用户x不喜欢的帖子,然后使用en-map设置likedBySelf true/false组合这两个数组并返回组合的数组。但这给其他查询函数(如limit和skip)带来了一些限制 现在我的查询如下所示: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组合这两个数组并返回组合的数组。但这给其他查询函
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检查,这也可以工作,但我希望您可以在一个查询中完成所有操作。检查我的答案,我已经发布了一个聚合函数,可以满足我的需要。