2

I need help for querying mongoDb

So I have two collections like

Collection A:

{someField: "123", anotherField: "456"},
{someField: "1234", anotherField: "4567"}

Collection B

{someField: "123", otherField: "789"}

with Query:

db.A.aggregate([
   {
      $lookup:
         {
           from: "B",
           let: { someField: "$someField", otherField: "$otherField" },
           pipeline: [
              { $match:
                 { $expr:
                    { $and:
                       [
                         { $eq: [ "$someField",  "$$someField" ] },
                         { $eq: [ "$otherField",  "789" ] }                       
                       ]
                    }
                 }
              },
           ],
           as: "B"
         }
    }
])

I get all collection A, with B empty in {someField: "1234", anotherField: "4567"}

What I want to achieve is like:

{someField: "123", anotherField: "456", b: {someField: "123", otherField: "789"}}

Thank you in advance

3
  • You can filter the documents after the lookup, if the B array size is greater than zero (see $size). Commented Mar 2, 2020 at 11:27
  • @prasad_ how to do that? Please advice Commented Mar 2, 2020 at 11:49
  • Please, see the updated code. Commented Mar 2, 2020 at 13:42

2 Answers 2

2

you only need to declare $someField in the let section.

db.collectionA.aggregate([
  {
    $lookup: {
      from: 'collectionB',
      let: { some_field: '$someField' },
      pipeline: [
        { $match: {
            $expr: {
              $and: [
                { $eq: [ "$someField", "$$some_field" ] },
                { $eq: [ "$otherField", "789" ] }
              ]
            }
          }
        }
      ],
      as: 'B'
    }
  },
  {
    $match: {
      $expr: {
        $gt: [ { $size: "$B" }, 0 ]
      }
    }
  }
])

https://mongoplayground.net/p/RTiUMWl8QaX

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

2 Comments

It still shows all of collection A rather than only collection A that has collection B ...
@dImasAnggaSaputra you can either reverse the lookup or add a $match stage. updated my answer above.
1

This is how I removed the empty B array documents:

db.A.aggregate( [
   {
      $lookup: {
           from: "B",
           localField: "someField",
           foreignField: "someField",
           as: "B"
         }
    },
    {
       $addFields: {
            B: {
                 $filter: {
                      input: "$B",
                      cond: {
                          $eq: [ "$$this.otherField", "789" ]
                      }
                 }
            }
      }
    },
    {
       $match: { 
           $expr: {
                $gt: [ { $size: "$B" }, 0 ]
           }
       }
    }
] ).pretty()

Comments

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.