如何强制MongoDB pullAll忽略文档顺序

时间:2015-02-28 00:29:02

标签: mongodb

我有一个mongoDB文档,它具有以下结构:

{
    user:user_name, 
    streams:[
        {user:user_a, name:name_a}, 
        {user:user_b, name:name_b},
        {user:user_c, name:name_c}
    ]
}

我想使用$ pullAll从流数组中删除,传递一个流数组(数组的大小从1到N不等):

var streamsA = [{user:"user_a", name:"name_a"},{user:"user_b", name:"name_b"}]
var streamsB = [{name:"name_a", user:"user_a"},{name:"name_b", user:"user_b"}]

我使用以下mongoDB命令来执行更新操作:

db.streams.update({name:"user_name", {"$pullAll:{streams:streamsA}})
db.streams.update({name:"user_name", {"$pullAll:{streams:streamsB}})

删除streamsA成功,而删除streamsB失败。在深入研究mongoDB手册之后,我看到streamsA和streamsB记录中的字段顺序必须与数据库中字段的顺序相匹配。对于streamsB,订单不匹配,这就是为什么它没有被删除。

在执行更新操作之前,我可以将流重新排序到数据库文档顺序,但是有更简单,更清晰的方法吗?是否有一些标志可以设置为更新和/或pullAll以忽略顺序?

谢谢你, 加里

1 个答案:

答案 0 :(得分:4)

$pullAll运算符实际上是一个“特殊情况”,主要用于单个“标量”数组元素,而不是用于您使用它的子文档。

而是使用$pull来检查每个元素并对文档列表使用$or条件:

db.streams.update(
    { "user": "user_name" },
    { "$pull": { "streams": { "$or": streamsB } }}
)

这样,无论字段在哪个顺序或者确实寻找“完全匹配”并不重要,因为当前$pullAll操作实际上正在进行。