Mongo 查询和响应 'GroupBy' 使用 Mongoose and/or underscore.js 实现
Mongo query and response 'GroupBy' implementation using Mongoose and/or underscore.js
我们有一个 mongo 集合 messages
,格式如下...
/* 0 */
{
"text" : "A message to John",
"created" : ISODate("2015-01-29T23:50:10.488Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
},
}
/* 1 */
{
"text" : "Another message to John",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin fowler"
},
}
/* 2 */
{
"text" : "Just another message to Jerry",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Jerry Jones"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
},
}
/* 2 */
{
"text" : "Message to Martin Fowler",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Martin Fowler"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Jerry Jones"
},
}
我们需要以对话格式显示上面的数据,我们将每个对话组合在一起。一段对话意味着它可以是 to
或 from
。
我们需要此数据的示例如下格式:
{
"result":[
{
"id":"54bf1dc6c65b030c00faec0d",
"name":"Jerry Jones",
"messages":[
{
"text" : "A message to John",
"created" : ISODate("2015-01-29T23:50:10.488Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
},
}
{
"text" : "Another message to John",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin fowler"
},
}
]
},
{
"id":"54bf1e80eb5bf8800b0f5a8d",
"name":"John Smith",
"messages":[
{
"text" : "Just another message to Jerry",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Jerry Jones"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
},
}
{
"text" : "Message to Martin Fowler",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Martin Fowler"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Jerry Jones"
},
}
]
}
]
}
注意 此查询始终在 current user
的上下文中进行,这就是为什么在每个对话中,我们都有一个 _id
和一个name
代表对话中的其他用户。对于上面的示例,current user
将是 Martin Fowler
我们已经尝试了几种不同的方法来实现这一点,但是 运行 仍然存在问题。我宁愿求助于 Mongo/Node 社区,以了解如何正确完成。如果有帮助,我们将 mongoose
与 Node 一起使用...
我们目前的初始查询实现如下:
Message.find().or([{'from.id':req.user.id},{'to.id':req.user.id}]).exec(function(err,messages){
//NEED TO IMPLEMENT THIS HERE CORRECTLY
});
注意 req.user.id
是 current user
的 ID
我试图为您创建一个 mongo 请求,但我不确定它是否相关...
我可以在一个请求中生成几乎与您需要的格式完全相同的格式:
db.messages.aggregate([{$match:{$or:[{"from.id":ObjectId("54bf1dc6c65b030c00faec0d")},{"to.id":ObjectId("54bf1dc6c65b030c00faec0d")}]}},{$group:{_id: ObjectId("54bf1dc6c65b030c00faec0d"), messages:{$push: "$$ROOT"}}}]);
问题是,你还需要指定id,我不确定这是你需要的。
使用这个我得到以下结果:
{
"_id": ObjectId("54bf1dc6c65b030c00faec0d"),
"messages": [
{
"_id": ObjectId("54d1b9f02cd45cae7e453633"),
"text": "A message to John",
"created": ISODate("2015-01-29T23:50:10.488Z"),
"to": {
"id": ObjectId("54bf1dc6c65b030c00faec0d"),
"name": "John Smith"
},
"from": {
"id": ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name": "Martin Fowler"
}
},
{
"_id": ObjectId("54d1ba052cd45cae7e453634"),
"text": "Another message to John",
"created": ISODate("2015-01-30T00:37:38.106Z"),
"to": {
"id": ObjectId("54bf1dc6c65b030c00faec0d"),
"name": "John Smith"
},
"from": {
"id": ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name": "Martin fowler"
}
}
]
}
我没有使用 mongoose 所以这部分我帮不了你,但是有了 "mongodb" 模块,这个查询可以直接使用,所以应该可以用 mongo也是。
这个解决方案是对我之前对类似问题的解决方案的轻微修改 here。
有问题的文档中的成员名称大小写不一致。 Martin Folwer
在整个 app/database 中应该是 Martin Fowler
,而不是 Martin fowler
。 (注意小 f
)。您需要对您的文档进行此更改。
$group
消息,基于 to
和 from
字段。
构造一个组键 - "message_between",值为 a
$concat to
和 from
字段中值的结果。
从 Martin Fowler
到 Jerry Jones
和 Jerry Jones
到
Martin Fowler
应该是下单group.To实现
那,我们让结果包含最后一个名字
按字母顺序,第一。因此,我们从 Martin
Fowler
到 Jerry Jones
和 Jerry Jones
到 Martin Fowler
的所有消息的密钥将是
Martin Fowler and Jerry Jones
.
代码:
Model.aggregate(
//match all those records which involve the user.
{$match:{$or:[{"to.name":req.user.id},
{"from.name":req.user.id}]}},
{$group:{"_id":{
"message_between":{
$cond:[
{
$gt:[
{$substr:["$to.name",0,1]},
{$substr:["$from.name",0,1]}]
},
{$concat:["$to.name"," and ","$from.name"]},
{$concat:["$from.name"," and ","$to.name"]}
]
},"name":{$cond:[{$eq:["$to.name",
req.user.id]},
"$from.name",
"$to.name"]}
},"messages":{$push:"$$ROOT"}
}
},
{$project:{"_id":0,"name":"$_id.name","messages":1}}
,function(err,resp){
// handle response.
})
o/p:
{
"messages" : [
{
"_id" : ObjectId("54d1d819b62f332e93fbb906"),
"text" : "Just another message to Jerry",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Jerry Jones"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
}
},
{
"_id" : ObjectId("54d1d819b62f332e93fbb907"),
"text" : "Message to Martin Fowler",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Martin Fowler"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Jerry Jones"
}
}
],
"name" : "Jerry Jones"
}
{
"messages" : [
{
"_id" : ObjectId("54d1d819b62f332e93fbb904"),
"text" : "A message to John",
"created" : ISODate("2015-01-29T23:50:10.488Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
}
},
{
"_id" : ObjectId("54d1d819b62f332e93fbb905"),
"text" : "Another message to John",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
}
}
],
"name" : "John Smith"
}
我们有一个 mongo 集合 messages
,格式如下...
/* 0 */
{
"text" : "A message to John",
"created" : ISODate("2015-01-29T23:50:10.488Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
},
}
/* 1 */
{
"text" : "Another message to John",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin fowler"
},
}
/* 2 */
{
"text" : "Just another message to Jerry",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Jerry Jones"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
},
}
/* 2 */
{
"text" : "Message to Martin Fowler",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Martin Fowler"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Jerry Jones"
},
}
我们需要以对话格式显示上面的数据,我们将每个对话组合在一起。一段对话意味着它可以是 to
或 from
。
我们需要此数据的示例如下格式:
{
"result":[
{
"id":"54bf1dc6c65b030c00faec0d",
"name":"Jerry Jones",
"messages":[
{
"text" : "A message to John",
"created" : ISODate("2015-01-29T23:50:10.488Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
},
}
{
"text" : "Another message to John",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin fowler"
},
}
]
},
{
"id":"54bf1e80eb5bf8800b0f5a8d",
"name":"John Smith",
"messages":[
{
"text" : "Just another message to Jerry",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Jerry Jones"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
},
}
{
"text" : "Message to Martin Fowler",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Martin Fowler"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Jerry Jones"
},
}
]
}
]
}
注意 此查询始终在 current user
的上下文中进行,这就是为什么在每个对话中,我们都有一个 _id
和一个name
代表对话中的其他用户。对于上面的示例,current user
将是 Martin Fowler
我们已经尝试了几种不同的方法来实现这一点,但是 运行 仍然存在问题。我宁愿求助于 Mongo/Node 社区,以了解如何正确完成。如果有帮助,我们将 mongoose
与 Node 一起使用...
我们目前的初始查询实现如下:
Message.find().or([{'from.id':req.user.id},{'to.id':req.user.id}]).exec(function(err,messages){
//NEED TO IMPLEMENT THIS HERE CORRECTLY
});
注意 req.user.id
是 current user
我试图为您创建一个 mongo 请求,但我不确定它是否相关... 我可以在一个请求中生成几乎与您需要的格式完全相同的格式:
db.messages.aggregate([{$match:{$or:[{"from.id":ObjectId("54bf1dc6c65b030c00faec0d")},{"to.id":ObjectId("54bf1dc6c65b030c00faec0d")}]}},{$group:{_id: ObjectId("54bf1dc6c65b030c00faec0d"), messages:{$push: "$$ROOT"}}}]);
问题是,你还需要指定id,我不确定这是你需要的。
使用这个我得到以下结果:
{
"_id": ObjectId("54bf1dc6c65b030c00faec0d"),
"messages": [
{
"_id": ObjectId("54d1b9f02cd45cae7e453633"),
"text": "A message to John",
"created": ISODate("2015-01-29T23:50:10.488Z"),
"to": {
"id": ObjectId("54bf1dc6c65b030c00faec0d"),
"name": "John Smith"
},
"from": {
"id": ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name": "Martin Fowler"
}
},
{
"_id": ObjectId("54d1ba052cd45cae7e453634"),
"text": "Another message to John",
"created": ISODate("2015-01-30T00:37:38.106Z"),
"to": {
"id": ObjectId("54bf1dc6c65b030c00faec0d"),
"name": "John Smith"
},
"from": {
"id": ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name": "Martin fowler"
}
}
]
}
我没有使用 mongoose 所以这部分我帮不了你,但是有了 "mongodb" 模块,这个查询可以直接使用,所以应该可以用 mongo也是。
这个解决方案是对我之前对类似问题的解决方案的轻微修改 here。
有问题的文档中的成员名称大小写不一致。 Martin Folwer
在整个 app/database 中应该是 Martin Fowler
,而不是 Martin fowler
。 (注意小 f
)。您需要对您的文档进行此更改。
$group
消息,基于to
和from
字段。 构造一个组键 - "message_between",值为 a $concatto
和from
字段中值的结果。从
Martin Fowler
到Jerry Jones
和Jerry Jones
到Martin Fowler
应该是下单group.To实现 那,我们让结果包含最后一个名字 按字母顺序,第一。因此,我们从Martin Fowler
到Jerry Jones
和Jerry Jones
到Martin Fowler
的所有消息的密钥将是Martin Fowler and Jerry Jones
.
代码:
Model.aggregate(
//match all those records which involve the user.
{$match:{$or:[{"to.name":req.user.id},
{"from.name":req.user.id}]}},
{$group:{"_id":{
"message_between":{
$cond:[
{
$gt:[
{$substr:["$to.name",0,1]},
{$substr:["$from.name",0,1]}]
},
{$concat:["$to.name"," and ","$from.name"]},
{$concat:["$from.name"," and ","$to.name"]}
]
},"name":{$cond:[{$eq:["$to.name",
req.user.id]},
"$from.name",
"$to.name"]}
},"messages":{$push:"$$ROOT"}
}
},
{$project:{"_id":0,"name":"$_id.name","messages":1}}
,function(err,resp){
// handle response.
})
o/p:
{
"messages" : [
{
"_id" : ObjectId("54d1d819b62f332e93fbb906"),
"text" : "Just another message to Jerry",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Jerry Jones"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
}
},
{
"_id" : ObjectId("54d1d819b62f332e93fbb907"),
"text" : "Message to Martin Fowler",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1e80eb5bf8800b0f5a8d"),
"name" : "Martin Fowler"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Jerry Jones"
}
}
],
"name" : "Jerry Jones"
}
{
"messages" : [
{
"_id" : ObjectId("54d1d819b62f332e93fbb904"),
"text" : "A message to John",
"created" : ISODate("2015-01-29T23:50:10.488Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
}
},
{
"_id" : ObjectId("54d1d819b62f332e93fbb905"),
"text" : "Another message to John",
"created" : ISODate("2015-01-30T00:37:38.106Z"),
"to" : {
"id" : ObjectId("54bf1dc6c65b030c00faec0d"),
"name" : "John Smith"
},
"from" : {
"id" : ObjectId("54bf1e1ceb5bf8800b0f5a8c"),
"name" : "Martin Fowler"
}
}
],
"name" : "John Smith"
}