Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can meteor mongo driver handle $each and $position operators?

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

like image 229
Billybobbonnet Avatar asked Dec 14 '15 14:12

Billybobbonnet


1 Answers

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(...)

like image 114
webdeb Avatar answered Nov 16 '22 02:11

webdeb