mongo中$push的$slice子操作符的理解

在读mongoDB权威指南的过程中,看到push这里时,书上明确写着slice必须为负整数

一般设计函数时,都是会用正整数,负整数真的是强制要求么。怀揣着这样的疑问,就有了以下的实验


首先构造一个数组1234

> db.person.update({"name":"123"}, {"$push":{"text":{ "$each":["1","2","3","4"], "$slice":-4}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.person.findOne({"name":"123"});
{
        "_id" : ObjectId("55d1c05ac2ca814480da4237"),
        "name" : "123",
        "text" : [
                "1",
                "2",
                "3",
                "4"
        ]
}



先按常规的方法使用slice

> db.person.update({"name":"123"}, {"$push":{"text":{ "$each":["5","6","7"], "$slice":-4}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.person.findOne({"name":"123"});
{
        "_id" : ObjectId("55d1c05ac2ca814480da4237"),
        "name" : "123",
        "text" : [
                "4",
                "5",
                "6",
                "7"
        ]
}

可以看到得到数据是4567,即“最新”的四个数


我们重置数据

> db.person.update({"name":"123"}, {"$push":{"text":{ "$each":["1","2","3","4"], "$slice":-4}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.person.findOne({"name":"123"});
{
        "_id" : ObjectId("55d1c05ac2ca814480da4237"),
        "name" : "123",
        "text" : [
                "1",
                "2",
                "3",
                "4"
        ]
}

这次使用一个正整数的slice
> db.person.update({"name":"123"}, {"$push":{"text":{ "$each":["5","6","7"], "$slice":4}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.person.findOne({"name":"123"});
{
        "_id" : ObjectId("55d1c05ac2ca814480da4237"),
        "name" : "123",
        "text" : [
                "1",
                "2",
                "3",
                "4"
        ]
}

没有报错,数据也没有发生变化,但是这是真的没有发生变化么?


我们换一个slice的值
> db.person.update({"name":"123"}, {"$push":{"text":{ "$each":["5","6","7"], "$slice":5}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.person.findOne({"name":"123"});
{
        "_id" : ObjectId("55d1c05ac2ca814480da4237"),
        "name" : "123",
        "text" : [
                "1",
                "2",
                "3",
                "4",
                "5"
        ]
}

正整数的slice是用的!但是用正整数的slice操作的数组得到的不是“最新”的5个数,而是“最老”的五个数

slice这个词是切割的意思,按切割的意思就很好理解这个操作符了:首先整个数组尾部加上新添加的数组,然后进行切割,正整数即为从头端开始切割,负整数就是从尾部开始切割。

这样在负整数的情况下,就能达到保存“最新”数据的效果。我们在这里用一个稍大的slice值做一下验证


> db.person.findOne({"name":"123"});
{
        "_id" : ObjectId("55d1c05ac2ca814480da4237"),
        "name" : "123",
        "text" : [
                "1",
                "2",
                "3",
                "4",
                "5"
        ]
}
先展示下现在数组的情况是12345

我们继续插入567三个数,但是这次切割的长度是10,即为前10个都保留
> db.person.update({"name":"123"}, {"$push":{"text":{ "$each":["5","6","7"], "$slice":10}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.person.findOne({"name":"123"});
{
        "_id" : ObjectId("55d1c05ac2ca814480da4237"),
        "name" : "123",
        "text" : [
                "1",
                "2",
                "3",
                "4",
                "5",
                "5",
                "6",
                "7"
        ]
}

可见之前的5个元素+3个新插入的元素都得到了保留

再进行一次插入567

> db.person.update({"name":"123"}, {"$push":{"text":{ "$each":["5","6","7"], "$slice":10}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.person.findOne({"name":"123"});
{
        "_id" : ObjectId("55d1c05ac2ca814480da4237"),
        "name" : "123",
        "text" : [
                "1",
                "2",
                "3",
                "4",
                "5",
                "5",
                "6",
                "7",
                "5",
                "6"
        ]
}

之前的数组12345567,插入后是12345567567,然后截取前10个,就是这次的结果1234556756

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值