嗨,我在用户集合中有一个MongoDB文档:
{
"_id": ObjectId("51d9534fc469880b338903eb"),
"inbox": {
"0": {},
"1": {} ,
"2": {}
...
},
}
根据要求,我需要每5分钟检查一次收件箱。所以我在寻找:
- 查找收件箱的长度
- 想象一下,我的收件箱长度是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
场,它将是true
或false
。
所以,实际上,你最可能要问的是如何获得所有消息,按发送日期排序,其中read
是false
;或者,您也可以使用MongoDate
(http://php.net/manual/en/class.mongodate.php)CCD_ 11以跟踪它并将该值存储在CCD_。
在本例中,我们将使用read
字段。我还假设您有一个名为sent
的ISODate()
格式的发送日期。
为此,我们可以使用这样的聚合框架:
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中执行此操作