我有一个lists
集合,其中每个文档都有一个members
数组。 members
数组的每个元素都是一个具有email
属性,创建date
属性和其他元数据的文档。我在members.email
上有一个唯一索引,以阻止同一个电子邮件两次输入同一个列表,但我希望保留原始的date
值。不幸的是,$addToSet
和$push
似乎都不这样做。
使用$ push的示例:
$lists->update(array('_id' => $list['_id'], 'members.email' => array('$ne' => $email)), array('$push' => array('members' => array(
'email' => $email,
'date' => new MongoDate(),
// etc.
))));
使用$ addToSet:
$lists->update(array('_id' => $list['_id']), array('$addToSet' => array('members' => array(
'email' => $email,
'date' => new MongoDate(),
// etc.
))));
由于(我假设)唯一的date
值,两个示例都用新的替换整个嵌入文档。如果$push
尚不存在,或者我需要在两个命令中执行此操作,是否只能members.email
“成员”文档?
或者,将members
放在他们自己的集合中,并使用类似parent_list
的属性,是否可以更好地实现可伸缩性?
答案 0 :(得分:5)
根据我的经验,您不能“$ push”或“$ addToSet”的原因是因为您的目标“成员”可能是一个嵌入对象(或在创建后转换为一个)。你只能在嵌入式阵列上使用$ push,$ pushAll,$ addToSet ......
不幸的是,对于我们php开发人员来说,游标查询总是将数据作为数组返回,检查“member”之类的东西是否是数组或对象的最佳方法是在mongo shell中运行find()并查看对于结果中的花括号/方括号(“{}”或“[]”)。
希望这有帮助。
答案 1 :(得分:1)
为什么没有存储list_id,email,added_date的集合 然后,您将在2个键list_id和电子邮件上创建唯一索引。这会阻止插入 具有相同list_id和电子邮件的记录
不会有嵌入式文件。您仍然可以使用list_id
中的find()答案 2 :(得分:1)
在查询条件中使用$ne
来过滤包含相同电子邮件成员的文档:
$lists->update(array('_id' => $list['_id'],
'members.email' => array('$ne' => $email)),
array('$addToSet' => array('members' => array(
'email' => $email,
'date' => new MongoDate(),
// etc.
))));
答案 3 :(得分:0)
是的,这是可能的。查看mongoDB advanced queries部分中的$ exists运算符。将$ exists条件编码到where语句中,以便仅在成员电子邮件不存在时更新。
答案 4 :(得分:0)