4

I have a user model like this:

  user : {
       myArmy : {
           mySoldiers : [
               {
                    positioned : false,
                    soldierInfo : {
                       _id : s99212
                    }
               },
               {
                    positioned : true,
                    soldierInfo : {
                       _id : s99112
                    }
               }
           ]
       }
   },
   user : {
       myArmy : {
           mySoldiers : [
               {
                    positioned : true,
                    soldierInfo : {
                       _id : s99212
                    }
               },
               {
                    positioned : false,
                    soldierInfo : {
                       _id : s99112
                    }
               }
           ]
       }
   }

   ...

I have a query that i want to do to return the user(s) who have soldier id s99212 positioned (true): (could be thousands of those, and i need to read and retrieve them all)

This is my faulty query with mongoose:

var soldierId = s99212;


stream = User.find({
            $and: [
                {'myArmy.mySoldier.positioned': {$ne: null}},
                {'myArmy.mySoldier.soldierInfo._id': soldierId}
            ]
        }).lean(true).stream();

Nothing is returned by this query, should there be another way to do this $and stuff?

How exactly am i suppose to use $elemMatch if at all, should it be instead of the find? (If it worth to mention, i want to return the complete user object, not just parts of it...)

Tried this, crashed my app:

    stream = User.find({
        '$elemMatch': [
            {'myArmy.mySoldiers.pos': {$ne: null}},
            {'myArmy.mySoldiers.soldierInfo._id': soldierId}
        ]
    }).lean(true).stream();

I know i have a small syntax problem, where is it?

totothegreat
  • 1,633
  • 4
  • 27
  • 59
  • possible duplicate of [Retrieve only the queried element in an object array in MongoDB collection](http://stackoverflow.com/questions/3985214/retrieve-only-the-queried-element-in-an-object-array-in-mongodb-collection). Answers using `$elemMatch` in the query as both conditions need to be applied to the same array element. That is what `$elemMatch` does. – Blakes Seven Sep 07 '15 at 09:03
  • I dont think $elemMatch should be in my case, i need the full user object if soldier id is positioned by this structure, would you mind set me straight? – totothegreat Sep 07 '15 at 09:44
  • You are reading the wrong answer. Look at [`$elemMatch`](http://docs.mongodb.org/master/reference/operator/query/elemMatch/) in the documentation and then look at the answers again. Remember that "you" are the person asking for the advice of those who know better. `$elemMatch` is what you need here to match both properties on an element. Does not alter the object in any way. – Blakes Seven Sep 07 '15 at 09:46
  • Yes but again, this small syntax problem is a killer for me, what is the correct way to write it down? i tried this one: stream = User.find( {'$elemMatch': {'myClub.myPlayers.player._id': ev.outcome.playerId,'myClub.myPlayers.pos':{ $ne: null } } } ).lean(true).stream(); and failed again – totothegreat Sep 07 '15 at 09:51

1 Answers1

3

Very simple and well documented. The $elemMatch operator acts as a "query in itself", where it applies "it's conditions" to members of the array specified:

var query = User.find({
    "myArmy.mySoldiers": {
        "$elemMatch": {
            "positioned": { "$ne": null },
            "soldierInfo._id": soldierId
        }
    }
});

Therefore for a document to "match" then the conditions specfied under $elemMatch must be present and valid for the "same" array element. Array on "left", arguments on "right".

Other "dot notation" forms only ever test that the values match "some element" in the array, and not necessarily the same one.

Blakes Seven
  • 49,422
  • 14
  • 129
  • 135
  • I love you! i just forgot those: myArmy.mySoldiers, – totothegreat Sep 07 '15 at 10:02
  • @totothegreat How about going back to and having a "red hot go" at your [other question](http://stackoverflow.com/q/32433412/5031275). Now you got a bit more insight into syntax it should be simple to work out. Or at least get "part" of the way along. – Blakes Seven Sep 07 '15 at 10:04
  • You are right, now part 2 begins, give me a few im gonna build another army just for you – totothegreat Sep 07 '15 at 10:05