0

this is my document:

{
"CreationDateTime" : ISODate("2017-09-26T06:39:29.105Z"),
"DeviceId" : "89984320001499681816",
"UserId" : UUID("bca0db12-2246-49a5-8703-b03fee45e50f"),
"FirstName" : " ",
"LastName" : "",
}

some of my this documents , "FirstName" and "LastName" were filled. but all documents have DeviceId.

I write this query and I want to pass an object to a method that has a Filled FirstName .

db.location.aggregate([
 {$match : {
     FirstName : 
         {$nin : [" "]}
            }
  },
 {$group: {_id : "$DeviceId" }
 },{
 $project: {
     "DeviceId" : 1
 }}
 ]).forEach(
  function(obj)
    {
      print(
      "Orginal Coll \nDeviceId: " + obj.DeviceId
      +" \nFirstName: "   + obj.FirstName
      +" \nLastName: "    + obj.LastName)
      //compareCollection(obj);

});

but I got this at the end:

Orginal Coll 
DeviceId: undefined 
FirstName: undefined 
LastName: undefined

what is the problem?

1 Answer 1

1

I can see a few issues with this command:

db.location.aggregate([
 {$match : { FirstName: { $nin : [" "] } } },
 {$group: {_id : "$DeviceId" } },
 {$project: { "DeviceId" : 1 } }
])
  1. The $match stage will not match the document supplied in your question because the document you supplied has "FirstName" : " " so that document would be matched by $in but not by $nin
  2. If the $match stage was changed to $in then it would emit a document and the grouping stage would have something to work on but the grouping stage is only configured to return an _id attribute so it returns the following intermediate document:

    {
        "_id" : "89984320001499681816"
    }
    
  3. The $project stage attempts to project "DeviceId" but the result of the grouping stage contains only an _id attribute so you cannot project a DeviceId attribute from that document.

  4. By the time your aggregation pipeline reaches the forEach funciton there is no DeviceId, FirstName or LastName attribute in the documents.

To further understand what's happening inside the aggregation pipeline you could run this query:

db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } },
 {$project: { "DeviceId" : 1, FirstName: 1, LastName: 1 } }
]).forEach(
  function(obj) {
      print(obj);
  }
);

Or, just run each stage in the pipeline on its own and review the output of each state since that becomes the input to the next stage. So, for example:

This command ...

db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } }
])

... returns:

{
    "_id" : ObjectId("59d13b64c26584cd8b7a15c8"),
    "CreationDateTime" : ISODate("2017-09-26T06:39:29.105Z"),
    "DeviceId" : "89984320001499681816",
    "UserId" : UUID("bca0db12-2246-49a5-8703-b03fee45e50f"),
    "FirstName" : " ",
    "LastName" : ""
}

This command ...

db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } },
 {$group: {_id : "$DeviceId" } }
])

... returns:

{
    "_id" : "89984320001499681816"
}

This command ...

db.location.aggregate([
 {$match : { FirstName: { $in : [" "] } } },
 {$group: {_id : "$DeviceId" } },
 {$project: { "DeviceId" : 1 } }
])

... returns:

{
    "_id" : "89984320001499681816"
}

This should make clear that once you add in the $group stage you lose the DeviceId, FirstName and LastName attributes hence they are not available for you to print in the forEach function.

Sign up to request clarification or add additional context in comments.

3 Comments

thanks dude. But imagine I have 2 documents with same device Id but one of them FirstName field is empty.I want by ‍group by‍ at first do filter documents and then By some condition I do filter and send the document that has a filled FirstName to a method. what is your idia?
@sayres apologies I cannot follow your last comment. I think the above answer explains exactly why your forEach function is getting a document which does not have the state you expected. The answer also provides some tips on how to diagnose these issues yourself. If you still have an issue perhaps you could raise another question with a MCVE or at least update your original question to provide a clear statement of your inputs, your desired end results and what you have tried so far?
dude your explanation was clear and I understand what's happen. thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.