1

Say I have the following collection/query: https://mongoplayground.net/p/u9wkBR92bnX

I want to filter the output to only include the subdocument array containing "any-ipv4" in $name as a result. Unfortunately my $project section does not work with this example, there seems to be an issue with $objecto array/list somehow "not being searchable", since it returns empty arrays.

If however I try to change the data layout to not have an $objecto array/list, the filter works perfectly fine: https://mongoplayground.net/p/p2nfcb4wWM6

What am I missing here?

2
  • Including the sample documents and query in the question text itself is better than just linking. The links are good, but if mongoplayground.net decides to do some cleanup, this question would become worthless. Commented Jul 22, 2021 at 0:06
  • I've chosen this approach since it's a lot easier to read IMO. Thx 4 pointing it out though! Commented Jul 22, 2021 at 9:15

3 Answers 3

2

You need to use map to go loop nested arrays

db.collection.aggregate([
  {
    $match: {
      "list_data.source.objecto.name": "any-ipv4"
    }
  },
  {
    $project: {
      result: {
        $map: {
          input: "$list_data",
          as: "list",
          in: {
            "source": {
              $filter: {
                input: "$$list.source.objecto",
                as: "obj",
                cond: {
                  $eq: [
                    "$$obj.name",
                    "any-ipv4"
                  ]
                }
              }
            }
          }
        }
      }
    }
  }
])

Working Mongo playground

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

Comments

0

use $unwind for the request

 db.collection.aggregate([
  {
    $match: {
      "list_data.source.objecto.name": "any-ipv4"
    },
    
  },
  {
    $unwind: "$list_data"
  },
  {
    $unwind: "$list_data.source.objecto"
  },
  {
    $match: {
      "list_data.source.objecto.name": "any-ipv4"
    },
    
  },
  {
    $project: {
      _id: 1
    }
  }
])

try this

Comments

0

use $filter to get an array with those elements/items that match the condition:

db.collection.aggregate([
  {
    $match: {
      "list_data.source.name": "any-ipv4"
    }
  },
  {
    $project: {
      result: {
        $filter: {
          input: "$list_data",
          as: "list",
          cond: {
            $eq: [
              "$$list.source.name",
              "any-ipv4"
            ]
          }
        }
      }
    }
  }
])

$and | $or

if the name == 'any-ipv4' && id > 2: return item

cond: { $and: [
        { $eq: [ "$$list.source.name", "any-ipv4" ] },
        { $gt: [ "$$ist.source.id", 2) ] }
]}

you can also include other elements in the $project like:

$project: {
   name: 1,
   result: {...}  
}

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.