2013-07-08 23 views
0

您好我有在用户集合的MongoDB的文档新增内容:统计数组的长度并获得MongoDB中+ PHP

{ 
    "_id": ObjectId("51d9534fc469880b338903eb"), 
    "inbox": { 
     "0": {}, 
     "1": {} , 
     "2": {} 
      ... 
    }, 

} 

根据要求,我需要检查收件箱中,每5分钟。所以我在寻找:

  1. 找到收件箱的长度。
  2. 想象一下,我的收件箱长度是4,但有2封新邮件进来,我将如何获得这些新邮件。

经过一番研究后,我发现我可以使用db.collection.find({ tags : { $size: 4 }});来检查我的收件箱中是否有新邮件,但现在我的问题是如何找到这些新增的邮件。如果你能提出一个更好的方法来解决这种情况,这将是非常好的。

谢谢!如果您inbox领域确实是一个阵列,因为你的榜样它是一个文档

db.collection.find({ tags : { $size : 4 } }, { inbox : { $slice : -4 } }) 

检查:

回答

0

您应该使用$slice运营商跳过你的数组中的一些项目。

也许你应该修改查询过,假设你有你的收件箱的长度,取新邮件将是:

var len = current_length; // comes from your app 
var field = 'inbox.' + len; 
// the query will check if the index "len" of inbox array exists 
db.collection.find({ field : { $exists: true }, { inbox : { $slice : -len } }} 

检查这个问题有关索引查询的详细信息:https://stackoverflow.com/a/15224544/1877296

0

首先,设计模式的最佳方式是不使用inbox的对象;你应该使用一个数组。

然而,其次,你是否知道什么是新消息(即4条消息中有2条是新消息)?我要出去的一个肢体,说有一个read字段将是truefalse

那么你实际上很可能会问的是如何获取所有消息,按发送日期排序,其中readfalse;或者,您也可以使用MongoDatehttp://php.net/manual/en/class.mongodate.phplastPullTime来跟踪它记录$_SESSION中的值。

在这个例子中,我们要去read字段。我还会假设您的ISODate()格式的发送日期为sent

为此,我们可以使用聚合框架,像这样:

db.collection.aggregate([ 
    // Let's get our user 
    {$match:{_id:ObjectId()}}, 

    // Now we want to unwind the inbox so we can operate on it 
    {$unwind:'$inbox'}, 

    // Now we want only messages that are not read 
    {$match: {'inbox.read':false}}, 

    // Now lets do our sort by newest 
    {$sort: {'inbox.sent':-1}}, 

    // Now lets group them back up 
    {$group: {_id:'$_id', inbox: {$addToSet:'$inbox'}}} 
]) 

或者你可以用asort上做到这一点在PHP $doc['inbox']