$ addToSet更新后,mongodb中的切片数组

los*_*rce 8 mongodb mongodb-query

我有一个类似于此结构的文档

{
    "brand": "BMW",
    "models": ["320","545"]
}
Run Code Online (Sandbox Code Playgroud)

模型必须是唯一的,我在添加新项目时使用以下查询,

db.cars.update(
    {brand:'BMW'},
    {
        $addToSet: {
            models: '750'
        }
    },
    {upsert:true}
);
Run Code Online (Sandbox Code Playgroud)

这会给

{
    "brand": "BMW",
    "models": ["320","545","750"]
}
Run Code Online (Sandbox Code Playgroud)

题:

如何限制"模特"可以拥有的商品总数?假设我只想保留最后3个添加的模型.因此,如果我插入一个新模型'135',我最终会得到

{
    "brand": "BMW",
    "models": ["545","750","135"]
}
Run Code Online (Sandbox Code Playgroud)

我读到了$slice修饰符,但它似乎只在使用时才可用,$push而不是$addToSet

Nei*_*unn 6

有趣的问题,因为这实际上是一个错误的主题,已经提出了一个实际的添加请求.至于请求,我不会屏住呼吸来添加这种行为.

该错误在于您实际上可以发出以下内容:

db.cars.update(
    {brand:'BMW'},
    { $addToSet: { models: { $each: ['200'], $slice: 3 } } },
    {upsert: true}
)
Run Code Online (Sandbox Code Playgroud)

并且addToSet只会在忽略修饰符或警告的情况下工作.但是当然你现在在阵列中有四个元素.

来自CTO的评论同样指出了冲突.

因此,我唯一能想到的是首先在find中使用$ elemMatch测试数组中的元素,如果文档都存在且$ elemMatch find不为true,则使用常规$ push和slice进行更新.否则插入新文档或不管它

db.cars.update(
   {brand:'BMW'},
   {$push: { models: { $each: ['750'], $slice: -3 } }}
)
Run Code Online (Sandbox Code Playgroud)

这将导致两个以上的操作通过电线.交替下拉文档并自己操作数组,这将是另一个操作.无论哪种方式,你都会失去upsert魔法并且必须手动完成.

  • 你提到的[SERVER-8512:支持$ slice/sort $ $ addToSet](https://jira.mongodb.org/browse/SERVER-8512)"请求"已经关闭,因为"无法修复"所以绝对不要不要屏住呼吸;-).集合目前实现为数组,但将`$ addToSet`修饰符与数组`$ slice`机制混合起来没有意义.集合应视为无序. (2认同)