【问题标题】:Mongodb retrieve conversation from messagesMongodb 从消息中检索对话
【发布时间】:2016-11-11 20:24:36
【问题描述】:

在我的 mongodb 数据库中,我有一个消息集合,用于在用户之间发送私人消息。我想检索用户的对话。 我有这个数据模型:

更新的 json

{
   "_id" : ObjectId("577f81fde4501ba208b0e470"),
   "text" : "This is a message",
   "sender_profile_id" : ObjectId("577e69b0794f49d962f10e85"),
   "receiver_profile_id" : ObjectId("577e57393db745060b532000"),
},    
{
   "_id" : ObjectId("577f81fde4501ba208b0e470"),
   "text" : "This is a message",
   "sender_profile_id" : ObjectId("577e57393db745060b532000"),
   "receiver_profile_id" : ObjectId("577e69b0794f49d962f10e85"),
},    
{
   "_id" : ObjectId("577f81fde4501ba208b0e470"),
   "text" : "This is a message",
   "sender_profile_id" : ObjectId("577e57393db745060b532000"),
   "receiver_profile_id" : ObjectId("577e69b0794f49d962f10e82"),
},  
{
   "_id" : ObjectId("577f81fde4501ba208b0e470"),
   "text" : "This is a message",
   "sender_profile_id" : ObjectId("577e69b0794f49d962f10e82"),
   "receiver_profile_id" : ObjectId("577e57393db745060b532000"),
},    

理论上,有了这个 json,我有 2 个用户 ObjectId(“577e57393db745060b532000”)的对话。我怎样才能找回它们?

更新的解决方案

我解决了这个问题:

var selector = {};
selector['$or'] = [
  {"sender_profile_id" : ObjectId(decoded.profile._id)},
  {"receiver_profile_id" : ObjectId(decoded.profile._id)}
];

selector['_acl'] = {$exists : true};
selector['_acl.' + decoded.profile._id] = {$exists : true};
selector['_acl.' + decoded.profile._id + '.read'] = true;

var query = {
  $match : selector
};

var group = {
  $group: {
    _id: "$_id",
    text : { $last: '$text' },
    sender_profile_id : { $last: '$sender_profile_id' },
    receiver_profile_id : { $last: '$receiver_profile_id' },
    receiver : {$addToSet : '$receiver_profile_id'},
    sender: {$addToSet : '$sender_profile_id'},
    created_at : { $last: '$created_at' },
    updated_at : { $last: '$updated_at' },
    count: { $sum: 1 }
  }
};

var project = {
  $project: {
    _id: "$_id",
    text: "$text",
    sender_profile_id: '$sender_profile_id',
    receiver_profile_id: '$receiver_profile_id',
    created_at : '$created_at',
    updated_at : '$updated_at',
    participants : {
      $cond: {
        if: {
          $gte: ["$sender", "$receiver"] },
          then: { "$setUnion": ["$receiver", "$sender"] },
          else:  { "$setUnion": ["$sender", "$receiver"] }
        }
      }
    }
  };

  var group2 =   {
    $group: {
      _id: "$participants",
      text : { $first: '$text' },
      sender_profile_id : { $first: '$sender_profile_id' },
      receiver_profile_id : { $first: '$receiver_profile_id' },
      created_at : { $first: '$created_at' },
      updated_at : { $first: '$updated_at' },
      count: { $sum: 1 }
    }
  };

var project2 = {
  $project: {
    _id : 0,
    participants : "$_id",
    text: "$text",
    interlocutor_profile_id: {
      $cond: {
        if: {"$eq": [ "$receiver_profile_id", ObjectId(decoded.profile._id)]},
        then: '$sender_profile_id',
        else: '$receiver_profile_id'
    }
  },
  created_at : 1,
  updated_at : 1,
  count: 1
  }
}

var sort = {
  $sort: {
      "created_at": -1
    }
}

var sort2 = {
  $sort: {
      "created_at": -1
    }
}

db.collection('message').aggregate(query, group, project, sort, group2, project2, sort2, function(error, result)

【问题讨论】:

  • 试试这个:db..find({$or: [{'sender._id': 'ObjectId("577e57393db745060b532000")'}, {'receiver._id': 'ObjectId ("577e57393db745060b532000")'}]}).pretty();
  • 如果存在问题或我遗漏了什么,请告诉我
  • 这可以给你一个想法。 stackoverflow.com/questions/35549200/…
  • 给我 5 分钟,我正在为此创建查询。
  • 您应该考虑在答案部分发布您的解决方案。

标签: mongodb mongoose aggregation-framework nosql


【解决方案1】:

为我的问题找到了解决方案:

var selector = {};
selector['$or'] = [
 {"sender_profile_id" : ObjectId(decoded.profile._id)},
 {"receiver_profile_id" : ObjectId(decoded.profile._id)}
];

selector['_acl'] = {$exists : true};
selector['_acl.' + decoded.profile._id] = {$exists : true};
selector['_acl.' + decoded.profile._id + '.read'] = true;

var query = {
 $match : selector
};

var group = {
 $group: {
  _id: "$_id",
  text : { $last: '$text' },
  sender_profile_id : { $last: '$sender_profile_id' },
  receiver_profile_id : { $last: '$receiver_profile_id' },
  receiver : {$addToSet : '$receiver_profile_id'},
  sender: {$addToSet : '$sender_profile_id'},
  created_at : { $last: '$created_at' },
  updated_at : { $last: '$updated_at' },
  count: { $sum: 1 }
 }
};

var project = {
  $project: {
    _id: "$_id",
    text: "$text",
    sender_profile_id: '$sender_profile_id',
    receiver_profile_id: '$receiver_profile_id',
    created_at : '$created_at',
    updated_at : '$updated_at',
    participants : {
     $cond: {
       if: {
         $gte: ["$sender", "$receiver"] },
         then: { "$setUnion": ["$receiver", "$sender"] },
         else:  { "$setUnion": ["$sender", "$receiver"] }
       }
     }
   }
 };

var group2 =   {
 $group: {
  _id: "$participants",
  text : { $first: '$text' },
  sender_profile_id : { $first: '$sender_profile_id' },
  receiver_profile_id : { $first: '$receiver_profile_id' },
  created_at : { $first: '$created_at' },
  updated_at : { $first: '$updated_at' },
  count: { $sum: 1 }
 }
};

var project2 = {
 $project: {
  _id : 0,
  participants : "$_id",
  text: "$text",
  interlocutor_profile_id: {
   $cond: {
    if: {"$eq": [ "$receiver_profile_id", ObjectId(decoded.profile._id)]},
    then: '$sender_profile_id',
    else: '$receiver_profile_id'
  }
 },
 created_at : 1,
 updated_at : 1,
 count: 1
 }
}

var sort = {
 $sort: {
  "created_at": -1
 }
}

var sort2 = {
  $sort: {
   "created_at": -1
  }
}

db.collection('message').aggregate(query, group, project, sort, group2, project2, sort2, function(error, result)

【讨论】:

    【解决方案2】:

    试试下面的

    db.messages.aggregate([{$project: {correspondents: {$cond: { if: {$gte: ["$sender", "$receiver"]}, then: ["$sender", "$receiver"], else: ["$receiver", "$sender"]}}}}, {$group: {_id: "$correspondents", messages: {$addToSet: "$_id"}}}, {$match: {"_id": ObjectId("577e57393db745060b532000")}}])

    查询按对话参与者(通讯员)对分组,并返回组成对话的消息数组。此外,您可以获取属于特定用户的对话。

    【讨论】:

    • 我试过了,但它返回一个空数组。就像他们没有对话一样。
    • 这很奇怪,因为我在您在问题中发布的部分数据上启动了它,并且恰好收到了两个对话。您是在控制台中启动它的吗?
    • 不,我将它与 nodejs 一起使用并通过后端调用运行
    • 你可以看到这个截图dropbox.com/s/mml88u0e4axa47q/…
    • 那么,问题可能出在您的电话中。首先在控制台中尝试查询,如果它适用于您的数据,您可能需要查看 nodejs 代码。
    【解决方案3】:

    您还可以检查 $lookup 选项。请参阅下面的插图 http://dbversity.com/joins-in-mongodb-lookup/

    【讨论】:

      【解决方案4】:

      试试这个:

      db.aggregate([ {$match: {$or: [{'sender._id': 'ObjectId("577e57393db745060b532000")','receiver._id': 'ObjectId("577e69b0794f49d962f10e85")'},{'sender._id': 'ObjectId("577e69b0794f49d962f10e85")','receiver._id': 'ObjectId("577e57393db745060b532000")'}]}}, {$group: { _id: '$sender._id', vals: { '$push': '$receiver._id' } }} ])
      

      【讨论】:

      • 我试过了,但我改变了一些部分并简化了 json,只使用 objectid 作为发送者和接收者的值,在 $or 中:[{“sender”:ObjectId('577e57393db745060b532000')},{ "receiver" : ObjectId('577e57393db745060b532000')}], because i want to know the conversation from a user (the logged in user). Than with $group : { _id: '$sender', vals: { '$push': '$receiver' } }` 我只得到 1 个结果,但它应该是 2...
      猜你喜欢
      • 1970-01-01
      • 2015-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-25
      • 1970-01-01
      相关资源
      最近更新 更多