I have a lists
collection where each document has an array of members
. Each element of the members
array is a document with an email
property, creation date
property, and some other meta. I have a unique index on members.email
to prevent the same email being entered into the same list twice, but I would like to retain the original date
value. Unfortunately, neither $addToSet
nor $push
seem to do this.
Example using $push:
$lists->update(array('_id' => $list['_id'], 'members.email' => array('$ne' => $email)), array('$push' => array('members' => array(
'email' => $email,
'date' => new MongoDate(),
// etc.
))));
And with $addToSet:
$lists->update(array('_id' => $list['_id']), array('$addToSet' => array('members' => array(
'email' => $email,
'date' => new MongoDate(),
// etc.
))));
Both examples replace the entire embedded document with the new one due to (I assume) the unique date
value. Is it possible to only $push
the "member" document if members.email
doesn't already exist or will I need to do this in two commands?
Alternatively, would it be better scalability-wise to put the members
in their own collection with a parent_list
-like property?
In my experience the reason that you cannot "$push" or "$addToSet" is because your target "members" is probably an embedded object (or converted to one after its creation). You can only use $push, $pushAll, $addToSet on embedded arrays...
Unfortunately for us php developers a cursor query always returns the data as arrays, the best way to check to see if something like "members" is an array or object, is to run a find() in the mongo shell and look for the curly/square brackets ( "{}" or "[]" ) in the result.
Hope this helps.
Why not have a collection where you store list_id, email, added_date You would then create a unique index on 2 keys list_id and email. That would prevent insertion of a record with the same list_id and email
There will not be embedded documents. You can still use find() by list_id
use $ne
in query condiction to filter documents with members of same email:
$lists->update(array('_id' => $list['_id'],
'members.email' => array('$ne' => $email)),
array('$addToSet' => array('members' => array(
'email' => $email,
'date' => new MongoDate(),
// etc.
))));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With