首页  >  文章  >  数据库  >  $push到排序数组

$push到排序数组

WBOY
WBOY原创
2016-06-07 16:32:18929浏览

作者:MongoDB 解决方案架构师 Sam Weaver 和 MongoDB 内核负责人 Alberto Lerner MongoDB 2.4 引入了许多人长期以来一直要求的功能 - 创建上限数组的能力。上限数组非常适合任何应用

作者:Sam Weaver,MongoDB 解决方案架构师和 Alberto Lerner,MongoDB 内核负责人

MongoDB 2.4 引入了许多人长期以来一直要求的功能 - 创建上限数组的能力。

上限数组非常适合任何需要固定大小列表的应用程序。例如,如果您正在使用 MongoDB 设计一个电子商务应用程序,并且想要包含最近查看的 5 个产品的列表,那么您之前必须为查看的每个新项目发出 $push 请求,然后发出 $pop 来踢出最旧的产品数组中的项目。虽然这种方法很有效,但不一定有效。让我们举一个旧方法的例子:

首先,我们需要创建一个文档来代表用户,其中包含一个数组来保存最后查看的产品:

db.products.insert({last_viewed:["bike","cd","game","bike","book"]})
db.products.findOne()
{
    "_id" : ObjectId("51ff97d233c4f2089347cab6"),
    "last_viewed" : [
        "bike",
        "cd",
        "game",
        "bike",
        "book"
    ]
}

我们可以看到用户查看了自行车、CD、游戏、自行车和书籍。现在,如果他们查看一双滑雪板,我们需要将滑雪板推入数组中:

db.products.update({},{$push: {last_viewed: "skis"}})
db.products.findOne()
{
    "_id" : ObjectId("51ff97d233c4f2089347cab6"),
    "last_viewed" : [
        "bike",
        "cd",
        "game",
        "bike",
        "book",
        "skis"
    ]
}

你可以看到此时数组中有 6 个值。现在我们需要一个单独的操作来弹出“自行车”:

db.products.update({},{$pop: {last_viewed: -1}})
db.products.findOne()
{
    "_id" : ObjectId("51ff97d233c4f2089347cab6"),
    "last_viewed" : [
        "cd",
        "game",
        "bike",
        "book",
        "skis"
    ]
}

在 MongoDB 2.4 中,我们结合了这两个操作来维护按特定字段排序的数组的限制。

使用上面相同的示例文档,现在可以使用 $slice 在单个更新操作中执行固定大小的数组:

db.products.update({},{$push:{last_viewed:{$each:["skis"],$slice:-5}}})

将值ski推入last_viewed数组,然后将其切片为5个元素。这给了我们:

db.products.findOne()
{
    "_id" : ObjectId("51ff9a2d33c4f2089347cab7"),
    "last_viewed" : [
        "cd",
        "game",
        "bike",
        "book",
        "skis"
    ]
}

Mongo 按自然顺序维护数组并将数组修剪为 5 个元素。可以通过使用 $slice 的正整数或负整数来指定从数组的开头或数组的结尾进行切片。也可以通过传递 $sort 来升序或降序排序。这有助于避免无限制的文档增长,并允许事件系统保证按顺序交付。

此功能还有很多其他应用程序:

  • 跟踪消息系统中的最新消息
  • 管理网站上的最近点击上次访问/查看的产品
  • 前 X 位用户/评论/帖子

这样的例子还在继续。

此功能在 MongoDB 2.4 中可用,但需要许多扩展,例如 $push 中的完整 $sort 和 $slice 语义 (SERVER-8069),并使 $slice 操作可选 (SERVER-8746)。这两个都计划在 2.5 开发系列中使用。

特别感谢 eBay 的尤里·芬克尔斯坦 (Yuri Finkelstein),他对这一功能非常热心,并为这篇博文提供了灵感。

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn