php - Doctrine Mongo ODM UniqueIndex is replicated -
i'm playing uniqueindex picked doc of doctrine odm , seems have misanderstood of aims do.
indeed have keyword document mapped doctrine odm :
namespace app\document; use doctrine\odm\mongodb\mapping\annotations odm; /** * @odm\document * @odm\uniqueindex(keys={"name"="asc", "lang"="asc"}) */ class keyword { /** @odm\id(strategy="auto") */ protected $id; /** @odm\string */ protected $name; /** @odm\string */ protected $lang; ....
as can see document has uniqueindex on 2 keys (name , lang)
i have simple script persist document
.... .... $keyword=new \app\document\keyword(); $keyword->setcreatedate(new \datetime()); $keyword->setlang("fr"); $keyword->setlastparsedate(new \datetime()); $keyword->setname("test"); $dm->persist($keyword); $dm->flush();
now when find mongo shell, data same pair name/lang replicated when should unique :
> db.keyword.find() { "_id" : objectid("5171c72c6155795e47000000"), "name" : "test", "lang" : "fr", "createdate" : isodate("2013-04-19t22:37:32z"), "lastparsedate" : isodate("2013-04-19t22:37:32z") } { "_id" : objectid("5171c7366155796147000000"), "name" : "test", "lang" : "fr", "createdate" : isodate("2013-04-19t22:37:42z"), "lastparsedate" : isodate("2013-04-19t22:37:42z") } { "_id" : objectid("5171c7406155796447000000"), "name" : "test", "lang" : "fo", "createdate" : isodate("2013-04-19t22:37:52z"), "lastparsedate" : isodate("2013-04-19t22:37:52z") } { "_id" : objectid("5171c7fd615579a747000000"), "name" : "test", "lang" : "fo", "createdate" : isodate("2013-04-19t22:41:01z"), "lastparsedate" : isodate("2013-04-19t22:41:01z") } { "_id" : objectid("5171c7fe615579aa47000000"), "name" : "test", "lang" : "fo", "createdate" : isodate("2013-04-19t22:41:02z"), "lastparsedate" : isodate("2013-04-19t22:41:02z") }
my goal make pair name/lang unique persistence.
so have 2 questions :
- what uniqueindex made ? (because doesnt prevent replication)
- should use
custom strategy
concatenates name , lang unique id ? common usage ?
edit :
thanks @gview advices found didnt ensureindexes. fixed link : http://www.testically.org/2011/08/25/using-a-unique-index-in-mongodb-with-doctrine-odm-and-symfony2/
but instead of update entry, throws error duplicate entry. should use custom id said above ?
the index ensure documents don't duplicated.
if want equivalent of "replace into", should either:
get document if present, set values:
$keyword= $dm->findby(array("name"=> $name, "lang"=> $lang)); if(!$keyword) { $keyword= new keyword(); $dm->persist($keyword); } $keyword->setcreatedate(new \datetime()); $keyword->setlang("fr"); $keyword->setlastparsedate(new \datetime()); $keyword->setname("test");
this lead 2 queries.
or:
do upsert:
$dm->createquerybuilder('keyword') ->setnewobj(array( 'lang' => 'fr', 'name' => 'test', // ... other fields )) ->field('lang')->equals('fr') ->field('name')->equals('test') ->getquery() ->execute();
this update doc if present, otherwise create new document.
however, new document created raw array, actually bypassing doctrine events (like @timestampeble annotation).
so if query isn't problem, use first method.
Comments
Post a Comment