I work on a meteor application with meteor bundle up to date. I want to reposition an item within a mongo document array. To achieve that, I $pull
it out of the array, and then $push
it at a specific index
position according to mongoDB documentation.
MyCollection.update({_id: my_doc.id},
{
$push:
{
my_array:
{
$each:[my_item.id],
$position:index
}
}
}
)
Meteor/Mongo throws the following error:
update failed: MongoError: Can't canonicalize query: BadValue unknown top level operator: $each
I first implemented this client side. I assumed it didn't work because of minimongo limitations.
I wrote a method to handle this server side, but I end up with the same error.
What is wrong with this request, can meteor handle the $each operator?
EDIT : I tried to insert it directly in robomongo, and it worked. Mongo version, when typing db.version()
returns 2.6.7
*EDIT2 : I did not expect it so I didn't check before: the update works, both with the $pull
and the $push
. However, even if the data is actually updated, I still get the error.
*EDIT : Here is some example data:
{
"_id" : "oSNrpgAAu8BuznvD6",
"name" : "tynhjderjye",
"description" : "",
"notes" : "",
"display_notes" : false,
"keywords" : [
""
],
"owner" : "mA5Y7LBCoRyeSDkaG",
"createdAt" : ISODate("2015-10-27T13:59:06.083Z"),
"createdBy" : "C3i9oj4eapyttHZj6",
"contributors" : [
"C3i9oj4eapyttHZj6"
],
"medias" : [
"TcFqermNY4y5cjBG3",
"dbkNN2rxXJXth8urw",
"jML4JKkRoKxx8sLwu",
"LEWYsnPrXRSH6MPkX"
],
"modifiedAt" : ISODate("2015-11-17T09:35:50.303Z"),
"modifiedBy" : "C3i9oj4eapyttHZj6",
"chunks" : [
"qCCHKJDbdTLEFR5Yt",
"ySiM7dcxvduEM2npj",
"5q46vqrmYttscitiK"
],
"trashed" : ISODate("2015-11-17T09:35:50.303Z")
}
chunks
is the array my_array
where I pull and push the my_item.id
at the position index
If you create a Meteor Collection with new Mongo.Collection('col')
you get back a Minimongo instance which is not the native Node MongoDriver, right?
So some methods just don't work or not fully supported.. like collection.aggregate
But you can easily access the native driver via Col.rawCollection()
and perform your query directly on the native instance. The native instance is only accessible on the server, of course.
So to do what you want do you have several ways, for example you could first take the array, resort it how you want and
$set: {my_array: sortedArray }
Personally I would prefer this way because you need to do only one update operation instead of two ($pull
& $push at $position
)
But if you want to do it the $push at $position way.. just do it with the native driver
var col = Collection.rawCollection();
var result = Meteor.wrapAsync(col.update.bind(col)(
/* update query goes here */
);
Note: You need the Meteor.wrapAsync because of Meteor sync style, you could also do it with out it. Collection.rawCollection().update(...)
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