根据两个数组中的元素总数更新MongoDB文档

根据两个数组中的元素总数更新MongoDB文档,mongodb,mongodb-query,Mongodb,Mongodb Query,我有一个名为groups的集合,其中包含两个数组:members和invested。数组中的每个元素都是用户对象,例如{u id:''.''.',name:'.'.''.'.'.'.'.} 该文档还包含一个名为maxMembers的字段,该字段是一个整数,表示该组总共可以有多少成员。我想在更新文档时强制执行一条规则,以确保成员数组中的元素数+邀请数组中的元素数永远不会超过maxMembers计数 maxMembers永远不会改变,所以如果必要的话,我可以提前阅读(尽管以原子方式阅读会非常棒) 如

我有一个名为
groups
的集合,其中包含两个数组:
members
invested
。数组中的每个元素都是用户对象,例如
{u id:''.''.',name:'.'.''.'.'.'.'.}

该文档还包含一个名为
maxMembers
的字段,该字段是一个整数,表示该组总共可以有多少成员。我想在更新文档时强制执行一条规则,以确保
成员
数组中的元素数+
邀请
数组中的元素数永远不会超过
maxMembers
计数

maxMembers
永远不会改变,所以如果必要的话,我可以提前阅读(尽管以原子方式阅读会非常棒)

如果这只是一个
成员
数组,我会这样做:

var id = ... // the id of the document
var users = {...} // a user's object
var max = ... // the max amount of users read from `maxMembers` previously

var query = { _id: id, 'members._id': { $ne: user._id } }
query['members.' + max] = { $exists: false }

db.groups.update(query, { $push: { members: user } })
但是,如果我必须同时考虑
invested
数组中的元素数量,那么这当然不起作用

有没有一种方法可以以原子方式执行此操作?

没有任何“好”的方法可以以原子方式处理此操作,因为更新操作符实际上无法“读取”文档属性在其当前状态下的值。例外情况是这样的,根据赋值中的正值还是负值,用“递增/递减”原子地修改当前值

您“可以”将更新中的查询条件与逻辑结合起来,但这本身有一些限制

例如:

db.things.insert({“a”:[1,2,3],“maxA”:4})
定义一个文档,其中一个数组包含三个成员,另一个字段“maxA”是数组最大长度的预期“控制器”

db.things.update(

{“$where”:“返回此项。a.length+1的效果与charm类似-谢谢:)只是为了确保没有误解:我不希望数组成为一种滑动窗口,只保留最后的
maxA
元素。我只希望update语句在达到最大值的情况下不做任何事情,所以您最初使用
$where
的想法很好。现在是我的实现:
$where:'return(this.members | |[]).length+(this.invested | |[])).length
哦,是的,你完全正确,我不应该依赖
$where
子句作为唯一的查询元素。在我的情况下,我知道我要更新的文档的ID,我将使用它作为我的主要查找键,如果你愿意,只需添加
$where
部分作为一种保护确保最大值是kept@ThomasWatson就是这样。有趣的是,刚才回答了另一个问题,关于
$where
,以及
\u id
字段上的“精确匹配”。所以听起来你的想法是对的。你真的考虑过“一”数组而只是输入一个“类型”吗在子文档信息上?或者您需要在列表之间移动“成员”吗?在这种情况下,两个数组形式是有意义的。这里的响应实际上只是一个“指南”,因为您的实际(两个数组的长度)似乎对您需要做的事情持开放态度。非常通用,非常有用。@BlakeStevens是的,我考虑过一个数组,但它太好了,我不必担心在我的代码的其他部分将实际成员与受邀请的用户相关联-所以我想看看是否有办法将它们分开-而且似乎是的,我在列表之间移动成员:)@ThomasWatson仅供其他人参考,正是“在列表之间移动”使这绝对是正确的做法。一般情况下,存在
$push/$pull
操作,而您不能“两者都”执行在同一路径上的同一更新操作中。这就是为什么单独的列表是此类处理的设计要求。