对数组进行计数';s长度,并在mongodb+php中获取新添加的元素


count the array's length and get newly added elements in mongodb+php

嗨,我在用户集合中有一个MongoDB文档:

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

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

  1. 查找收件箱的长度
  2. 想象一下,我的收件箱长度是4,但有2条新邮件进来,我怎么会只收到这些新邮件呢

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

谢谢!

您应该使用$slice运算符跳过数组中的一些项:

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

检查您的inbox字段是否真的是一个数组,因为在您的示例中它是一个文档。

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

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

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

然而,第二,你知道什么是新消息吗(即4条消息中有2条是新消息)?我要指出的是,有一个read场,它将是truefalse

所以,实际上,你最可能要问的是如何获得所有消息,按发送日期排序,其中readfalse;或者,您也可以使用MongoDate(http://php.net/manual/en/class.mongodate.php)CCD_ 11以跟踪它并将该值存储在CCD_。

在本例中,我们将使用read字段。我还假设您有一个名为sentISODate()格式的发送日期。

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

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'}}}
])

或者您可以在$doc['inbox'] 上使用asort在PHP中执行此操作