gpt4 book ai didi

node.js - 如何在 mongoose/mongodb 查询子文档中使用 mapreduce?

转载 作者:可可西里 更新时间:2023-11-01 09:17:39 24 4
gpt4 key购买 nike

我在mongoose/mongodb中实现了一个简单的消息系统,架构如下

var schema = new mongoose.Schema({
user: {type:String, required:true},
updated: {type:Date, default:new Date()},
msgs: [ {m:String, // message itself
d:Date, // date of message
s: String, // message sender
r:Boolean // read or not
} ],
});

所有消息都存储在 msg 嵌套数组中,现在我想查询来自某个发件人的消息,例如,

{
"_id" : ObjectId("52c7cbe6d72ecb07f9bbc148"),
'user':'abc'
"msgs" : [{
"m" : "I want to meet you",
"d" : new Date("4/1/2014 08:52:54"),
"s" : "user1",
"r" : false,
"_id" : ObjectId("52c7cbe69d09f89025000005")
}, {
"m" : "I want to meet you",
"d" : new Date("4/1/2014 08:52:56"),
"s" : "user1",
"r" : false,
"_id" : ObjectId("52c7cbe89d09f89025000006")
}, {
"m" : "I want to meet you",
"d" : new Date("4/1/2014 08:52:58"),
"s" : "user2",
"r" : false,
"_id" : ObjectId("52c7cbea9d09f89025000007")
}
}

这里我有一个用户 'aa' 的文档,该文档包含三条消息,两条消息来自 'user1',一条消息来自 'user2'。我想查询来自“user1”的消息

基本上有两种方法可以做到,map-reduce 或 aggregate。我尝试了 map-reduce 解决方案。

var o = {}; 
o.map = function() {
this.msgs.forEach(function(msg){
if(msg.s == person){ emit( msg.s, {m:msg.m,d:msg.d,r:msg.r}); }
})
}
o.reduce = function(key, values) {
var msgs = [];
for(var i=0;i<values.length;i++)
msgs.push(values[i]);
return JSON.stringify(msgs);
}
o.query = {user:'username'};
o.scope = {person:'user1'};
model.mapReduce(o,function (err, data, stats) {
console.log('map reduce took %d ms', stats.processtime)
if(err) callback(err);
else callback(null,data);
})

最终,它的结果如下

 [ 
{ _id: 'helxsz',
value: '[
{"m":"I want to meet you","d":"2014-01-04T08:52:54.112Z","r":false}, ....
]
]

结果是我想要的,只是格式有点复杂。我怎样才能改变输出这样的格式

    { sender: 'helxsz',
messages: '[
{"m":"I want to meet you","d":"2014-01-04T08:52:54.112Z","r":false}, ...
]
}

以及我如何对结果进行排序和限制,所以我必须手动执行 reduce 函数?

最后一个 map reduce 方法需要 28 毫秒来查询结果,为了模拟,我的集合有三个文档,每个文档都有一个包含 4 个子文档的 msg 数组。对我来说,28 毫秒对于查询来说有点太多了,是吗,现在我也在“用户”字段上建立了索引。

最佳答案

我不确定它对你有多有效,但为了格式化,它会像下面这样工作,我制作了自定义键名 titleclassNamestart 不在集合中。所以将 mapReduce 的结果存储在一个新的集合中并检索它。 (如果您不打算对每个请求都运行 mapReduce)

  db.events.aggregate([{
$project: {
title: "$value",
className: "$_id.method",
start: "$_id.time",
_id:0 }
}]
)

关于node.js - 如何在 mongoose/mongodb 查询子文档中使用 mapreduce?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20919149/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com