1

I'm running an aggregate on a Collection and am using a lookup to another child Collection.

Each child may or may not have a field (foo) that can contain a String.

I'd like to project a Boolean for if at least 1 of these fields has a String for any of the child subdocuments.

So I can have something like

db.Parent.aggregate([
  {
    '$lookup': {
      'from': 'Children', 
      'localField': '_id', 
      'foreignField': 'parentId', 
      'as': 'CHILDREN'
    }
  }, {
     childHasFoo: {
         "$CHILDREN" : {$elemMatch: {foo: {$ne: ''}}}
     }
}
]

You can see my projection for childHasFoo . I'm thinking I can use $elemMatch or $anyElementTrue. Remember, foo may not exist on an/all of the children subdocuments either. So that needs to be taken into account.

Thanks!

1 Answer 1

2
  • iterate loop of CHILDREN array using $map array operator,
  • check your condition using $ne this will return boolean value
  • $anyElementTrue to check is any element has true
  {
    $addFields: {
      childHasFoo: {
        $anyElementTrue: {
          $map: {
            input: "$CHILDREN",
            in: { $ne: ["$$this.foo", ""] }
          }
        }
      }
    }
  }

Second option to more accurate condition,

  • $trim to remove white space from string
  • $not and $in to check is string empty "" or null then false otherwise true
  {
    $addFields: {
      childHasFoo: {
        $anyElementTrue: {
          $map: {
            input: "$CHILDREN",
            in: {
              $not: {
                $in: [
                  { $trim: { input: "$$this.foo" } },
                  ["", null]
                ]
              }
            }
          }
        }
      }
    }
  }
Sign up to request clarification or add additional context in comments.

3 Comments

More accurate soln is what worked, thanks! Is there a reason you're using addFields instead of just adding to the projection, or was this just for demo's sake?
Also, any idea how expensive this operation is? Or - will it not really matter?
the projection is find() property, you are using aggregate() method so you can use anyone stage from $addFields, $project, $set there are different approaches, yes little expensive but its ok if you have limited elements in array CHILDREN.

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.