Minimongo .$ operator not supported

My Meteor.users includes a subdocument called profile. I would like to query and recover just this profile subdocument.

Meteor.users.find({"profile.public": true},{fields: {_id:0,'profile.$':1}}).fetch();

I am using the former code, however the following error code is returned:
Uncaught Error: Minimongo doesn't support $ operator in projections yet.(…)

Any idea how this can be done? using subscriptions may be?

well, why u want to use $ there? profile: 1 should do the work

I would like to recover just the profile document.
I.e:

var profiles = Meteor.users.find({"profile.public": true},{fields: {_id:0,'profile.$':1}}).fetch();

profiles.forEach(function(profile){

//things with profile.name, profile.phone, etc.

}

otherwise I have to

var users = Meteor.users.find({"profile.public": true},{fields: {_id:0,'profile':1}}).fetch();

users.forEach(function(user){

//things with user.profile.name, user.profile.phone, etc.

}

I think is more convenient to write code in the former way. Although the latter works.

Is it the same security wise?

that $ sign means some filtered item from array

for your usecase, what about instead of .fetch() do
.map(function(x) {return x.profile});
I dont know exact syntax, i am coffee user :smiley:

If is problem for you addressing it with full path in given document.

Any fixes on this issue? We also encountered this problem, in the projection it doesn’t execute the things we want…

Like on the example, we also need to filter only those sub element items that is not yet marked as deleted.

The structure is:

document
–items (this contains a multiple elements, it’s an array type of field)

Here’s the example

{ 
    "_id" : "SEAWRcioKoz2R8p2C", 
    "name" : "Testing 1", 
    "items" : [
        {
            "display" : NumberInt(1), 
            "require" : NumberInt(1), 
            "occupation" : "Anchor Points", 
            "description" : "1 Testing", 
            "quantity" : "35", 
            "item" : "hrs", 
            "rate" : "5.54", 
            "labour" : "0.00", 
            "_id" : "fsf342fdsfj3hj342", 
            "deleted" : true
        }, 
        {
            "display" : NumberInt(1), 
            "require" : NumberInt(1), 
            "occupation" : "Asbestos", 
            "description" : "2 Testing eere", 
            "quantity" : "3", 
            "item" : "visit", 
            "rate" : "1.04", 
            "labour" : "0.00", 
            "_id" : "fea8394028df47cef0afcc51", 
            "deleted" : false
        }
    ], 
    "deleted" : false
}

…as you see the items fields has deleted field, now what we want is to filter only those items with deleted value is false.

I tried in MongoChef and it works but on meteor it doesn’t. Suppose to be the query looks like this:

{'items.description' : '1 Testing'}, {'items.$': 1}

Any help are appreciated. :slight_smile:

Thanks!

If I understand what you’re wanting, I’m pretty sure you want to use $elemMatch:

find({ 'items.description' : '1 Testing' }, { items: { $elemMatch: { deleted: false } } })

That doesn’t work either… that’s the first query I’ve tried but still it returns all sub elements of items field.

Oops. Forgot the fields operator:

find({ 'items.description' : '1 Testing' }, { fields: { items: { $elemMatch: { deleted: false } } } });

Hi,

Thanks for the possible answer but still it doesn’t work, here’s the error.

Exception in template helper: MinimongoError: Minimongo doesn't support operators in projections yet.

Thanks!

Since you’re doing this on the client (minimongo) - that means the client has all the data available already.

You don’t need to use minimonog to query you can just use lodash or underscore to do a _.find(yourCollectionObject, { query }) or use another one of the collection helpers in those libraries.

Github repo here:

1 Like

Hi @robfallows,

Thanks for the idea… I like this, as alternative solution of mini-mongo instead of using JS to loop through… millions of records will cause the big problem if we will always use JS way to obtain that goal, that’s why I prefer to use exactly like your idea…

Thanks for sharing that valuable idea!

One quick question, how can we pass some parameters to that method to assign an specific fields to pull out?

Thanks!

Hi @robfallows,

I wonder, your solution was working before but now it only returns 1 element? The first match? Seems like there’s an new validation in mongodb? I’m using the MongoChef for testing and managing the db and here’s the command I have in there.

db.scope_template.find({ 'items.description' : '1 Testing' }, { name: 1, items: { $elemMatch: { deleted: false } } } )

That only gives me 1 sub element item.

Thanks!

Remember when I said

Well, I think I didn’t understand what you were wanting :wink:. That is the behaviour of $elemMatch. From the docs:

The $elemMatch operator limits the contents of an <array> field from the query results to contain only the first element matching the $elemMatch condition.

There is a feature request for the functionality you want, but in the meantime you could adopt @shock’s approach and rewrite the document: you could use map, or (if it’s a “permanent” requirement) use a transform when defining the collection with new Mongo.Collection.