【问题标题】:Mongoose how can I get a list of conversations, a sepcific user has chatted with?Mongoose 如何获取对话列表,特定用户与之聊天?
【发布时间】:2014-10-22 01:36:11
【问题描述】:

好的,我的数据模型基本上是这样的:

var messageSchema = new Schema({
    to: { type: String, required: true},
    from: { type: String, required: true},
    message: { type: String, required: true}
});

我想做的是有一个功能,我可以传入当前登录用户的用户名:例如 billy。

数据库可能包含 100 条这样的消息:

[{"_id":"2394290384","from":"billy","to":"dan","message":"some message"},
 {"_id":"2394290384","from":"dan","to":"billy","message":"some message"},
 {"_id":"2394290389","from":"john","to":"billy","message":"some message"},
 {"_id":"2394290389","from":"billy","to":"john","message":"some message"}] 

它应该只给我这样的输出:

 [{"_id":"2394290384","from":"billy","to":"dan","message":"some message"},   
  {"_id":"2394290389","from":"john","to":"billy","message":"some message"}] 

我怎样才能为每条消息提取最新的 1。

因此,无论是我向他们发送消息还是他们向我发送消息,它基本上都会显示我与之聊天的每个对话/每个人的 1 个结果。

每个对话应该只提取 1 个结果,其中包含与其最新消息相关的所有数据。

所以最新的消息,该消息的 id,它的来往用户。

这样我就可以在一侧创建一个对话列表,在用户名下方显示用户及其消息。用户点击它,它会显示聊天。

我已经问过这个问题的多种变体,试图弄清楚,但到目前为止我还没有成功地找到解决方案。

我来自 php mysql 背景,所以我是 node 和 mongoose 的新手。

提前感谢您的所有帮助,我真的很感激。

我已经提到了为什么示例中的 2 个项目是不同的。根据当前登录的用户名,每次对话都会提取 1 个结果。

所以需要有这样的函数:

getconversations(username){
Message.find(Where messages are to this username or from this from username).exec(function(error,results){
this would probably output all messages like so:
[{"_id":"2394290384","from":"billy","to":"dan","message":"some message"},
 {"_id":"2394290384","from":"dan","to":"billy","message":"some message"},
 {"_id":"2394290389","from":"john","to":"billy","message":"some message"},
 {"_id":"2394290389","from":"billy","to":"john","message":"some message"}] 


})
}

if the current username was billy.

    But I only want 1 of the latest.

    So i can have a list on the left:
    messages:
    username:
    lastmessage
    username:
    last message

    a user clicks on it and it opens up the full chat. For example like you see on skype on ios or android: it shows you a list of users and their message below. you tap on it and it shows you the chat. it is basically pulling that list based on people you have had a conversation with.

我最终是如何让它工作的:

var user="billy";
Message.aggregate(
    {
           $match: {
              $or: [{
                to: user
              }, 
              {
                from: user
              }]
            }
        },
    { $project: { "from" : {
      $cond: {'if': {$eq: ['$to',user]},'then': '$from', 'else': '$to'}
                            },
                            "to":{
      $cond: {'if': {$eq: ['$to',user]},'then': '$to', 'else': '$from'}
                            },
                            "message":"$message"



                } },
    { $sort: { _id: -1 } },
    { $group: { "id": { "$first" : "$_id" },"_id" : { "from" : "$from" }, "from": { "$first" : "$from" },"to": { "$first" : "$to" }, "message": { "$first" : "$message" }  } }
, function(err, docs) {
  res.send(docs);

});

它按特定的用户名搜索并删除所有重复项,只为每个用户输出 1 条记录,并输出他们的消息、ID、来往和来自

【问题讨论】:

  • 为了澄清为什么你还没有在我给你的一个问题和其他 cmets 上被投票,你真正需要在这里解释的是为什么?意思是从你给出的样本中,为什么你指出的两个项目出来是“不同的”?如果您不接受,人们将不会回答您的问题。鉴于前者和对您的结果缺乏合理解释,人们不会浪费时间。由你自己解释。记住。忙碌的著名同事。清楚地解释自己,然后你就会学习。

标签: node.js mongodb mongoose mongodb-query


【解决方案1】:

我假设问题是您如何在 Mongoose 的 Mongodb 中执行 or 查询?

var Message = mongoose.model('message');
Message.find({ $or: [ { from: 'billy' }, { to: 'billy' } ] }, function(err, docs) {
    // docs will now be an array of Message models
});

更新: 您可以根据插入时间按_id 排序,然后将结果限制为一条记录:

var Message = mongoose.model('message');
Message.find({ $or: [ { from: 'billy' }, { to: 'billy' } ] })
    .sort({ _id : -1 })
    .limit(1)
    .exec(function(err, docs) {
    // docs will now be an array containing 1 Message model
});

更新 2:
尝试使用聚合框架:

var Message = mongoose.model('message');
Message.aggregate(
    { $project: { "from" : "$from", "message" : "$message" } },
    { $sort: { _id: -1 } },
    { $group: { "_id" : { "from" : "$from" }, "from": { "$first" : "$from" }, "message": { "$first" : "$message" } } }
, function(err, docs) {
    /* i.e. docs = array
    [ 
        { "_id" : { "from" : "alex" }, "from" : "alex", "message" : "Some message" },
        { "_id" : { "from" : "billy" }, "from" : "billy", "message" : "Some message" },
    ...

    */
});

【讨论】:

  • 有效,输出如下: [{"_id":{"from":"dan"},"from":"dan","message":"hello"},{ "_id":{"from":"nasser"},"from":"nasser","message":"wow"},{"_id":{"from":"billy"},"from": "billy","message":"bye"}] 任何更好的格式化方式我都不确定 {from:"billly"} 周围有什么奇怪的大括号并且没有 id
  • 谢谢,你能接受答案吗?) _id 是它的唯一索引。如果您需要每个文档的索引,只需将"id": { "$first" : "$_id" } 添加到$group 对象
  • 在哪里可以传入当前用户的用户名?所以它只从他那里拉记录?而且我似乎无法获得 to 的价值。当我添加 "to": { "$first" : "$to" } 它只返回 null
  • 我得到了工作,对不起我的坏事。我怎样才能为 1 个特定用户返回所有内容,这样它不只是输出整个数据库。
  • 还有什么方法可以在 mysql 查询等聚合上执行相当于跳过和限制的分页操作?
猜你喜欢
  • 2021-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多