Mongoose 聚合匹配 objectIds 数组
Posted
技术标签:
【中文标题】Mongoose 聚合匹配 objectIds 数组【英文标题】:Mongoose Aggregation match an array of objectIds 【发布时间】:2016-10-14 00:45:18 【问题描述】:我有一个看起来像这样的架构
var Post = new mongoose.Schema(
author:
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
,
created:
type: Date,
Default: Date.now
)
我也有一个用户表。我有一组用户 ID,我正在尝试根据一组用户 ID 搜索帖子表
举例
var userIds = ["575e96652473d2ab0ac51c1e","575e96652473d2ab0ac51c1d"] .... and so on
我想返回这些用户创建的所有帖子。帖子应按创建日期排序。有没有办法根据提供的用户 ID 对帖子进行分组,基本上匹配单个用户的帖子?
我想要达到的结果是这样的:
[
userAId : "56656.....",
post : [postA, postB],
,
userBId :"12345...",
post : [postA, postB]
]
如何编写此查询?
这是我目前所拥有的
Post.aggregate([
// "$unwind" : "",
// "$group":
// _id: "$author",
// "created" : "$sum" : 1
//
"$match" : author : id
]).exec(function(error, data)
if(error)
return console.log(error);
else
return console.log(data)
)
"_id" : ObjectId("575e95bc2473d2ab0ac51c1b"),
"lastMod" : ISODate("2016-06-13T11:15:08.950Z"),
"author" : ObjectId("575dac62ec13010678fe41cd"),
"created" : ISODate("2016-06-13T11:15:08.947Z"),
"type" : "photo",
"end" : null,
"commentCount" : 0,
"viewCount" : 0,
"likes" : 0,
"tags" : [],
"title" : "Today is a good day",
"__v" : 0
【问题讨论】:
你能从 mongo 发布完整的帖子文档吗? 你的意思是发布整个帖子文档的架构吗?? db.post.findOne() 没问题 - 请删除敏感信息 "_id" : ObjectId("575e95bc2473d2ab0ac51c1b"), "lastMod" : ISODate("2016-06-13T11:15:08.950Z"), "author" : ObjectId("575dac62ec13010678fe41cd"), “创建”:ISODate(“2016-06-13T11:15:08.947Z”),“类型”:“照片”,“结束”:null,“commentCount”:0,“viewCount”:0,“喜欢”: 0, "tags" : [ ], "title" : "今天是个好日子", "__v" : 0 【参考方案1】:要返回由 id 列表中描述的用户创建的所有帖子,请在查询中使用 $in
运算符,然后将 sort()
方法链接到按创建日期字段对结果进行排序的查询:
Post.find( "author": "$in": userIds )
.sort("-created") // or .sort( field: 'asc', created: -1 );
.exec(function (err, data)
if(err)
return console.log(err);
else
return console.log(data);
);
要获得每个用户对帖子 ID 进行分组的结果,您需要运行以下聚合操作:
Post.aggregate([
"$match" : "author": "$in": userIds ,
"$sort": "created": -1 ,
"$group" :
"_id" : "$author",
"posts" : "$push": "$_id"
,
"$project":
"_id": 0,
"userId": "$_id",
"posts": 1
]).exec(function (err, result)
if(err)
return console.log(err);
else
return console.log(result);
);
或者使用流畅的 API:
Post.aggregate()
.match( "author": "$in": userIds )
.sort("-created")
.group(
"_id" : "$author",
"posts" : "$push": "$_id"
)
.project(
"_id" : 0,
"userId" : "$_id",
"posts": 1
)
.exec(function (err, result)
if(err)
return console.log(err);
else
return console.log(result);
);
【讨论】:
有没有办法根据提供的用户 ID 对这篇文章进行分组??基本上匹配这样的个人用户的帖子。 userAId:“56656”,帖子:[postA,postB],userBId:“xys”,帖子:[postA,postB] 从数据库中获取帖子并在代码中进行连接会更好吗? @user3412942 你能否更新你的问题,因为原来的问题我想返回这些用户创建的所有帖子。帖子应按创建日期排序。我该如何编写这个查询? 解决了,不是吗?请记住,当已有答案时,在 SO 上更改您的问题被认为是不好的做法 - chameleon questions。 抱歉,我已经更新了问题,非常感谢您的支持。 您先生是钻石,这正是我所需要的。对于所有的支持和耐心来说,这已经足够了。【参考方案2】:这在没有聚合的情况下应该是可能的。
Post
.find( author: $in: userIds )
.sort( created: -1 )
如果您收到 CastError: Cast to ObjectId failed,请确保将您的 userIds 数组从字符串数组映射到 mongoose id 数组。
userIds = userIds.map(userId => new mongoose.Types.ObjectId(userId))
【讨论】:
有没有办法根据提供的用户 ID 对这篇文章进行分组??基本上匹配这样的个人用户的帖子。 userAId:“56656”,帖子:[postA,postB],userBId:“xys”,帖子:[postA,postB]以上是关于Mongoose 聚合匹配 objectIds 数组的主要内容,如果未能解决你的问题,请参考以下文章
Mongodb - 解决 ( aggregate聚合管道 ) $match 根据 id 匹配 返回 [ ] 的问题
与 mongoDb 和 mongoose 聚合后填充单个 ObjectId 引用