0

Suppose I had this data structure as my document:

{
  id: 1,
  customers: [
    {
      id: 2,
      addresses: [
        {
          phone: "555-342",
          zipCode: "1946873193",
          addressLine: "whatever"
        }
      ]
    }
  ]
}

How do I access the phone property in the aggregation framework? $ROOT.customers.0.addresses.0.phone doesn't work as a field path expression.

3
  • docs.mongodb.com/manual/reference/operator/aggregation/… Commented Jan 16, 2018 at 17:32
  • @AlexBlex yes I saw that but can't understand how to use chained "arrayElemAt"s for the cause Commented Jan 16, 2018 at 17:34
  • The syntax is { $arrayElemAt: [ "$customers", 0 ] }, not customers.0. Applies to all arrays. Commented Jan 16, 2018 at 17:38

2 Answers 2

3

You can use $let with $arrayElemAt to handle two nesting levels but then you can add $project to get phone property.

db.collection.aggregate([
{
  $addFields: {
    selectedElement: {
        $let: {
           vars: {
              fstCustomer: { $arrayElemAt: [ '$customers', 0 ] }                
           },
           in: { $arrayElemAt: [ '$$fstCustomer.addresses', 0 ] }
        }
     }
  } 
},
{
  $project: {
    phone: "$selectedElement.phone"
  }
}
])
Sign up to request clarification or add additional context in comments.

Comments

2

You can chain the $arrayElemAt in following way.

Outer $let expression to get the first customer and inner $let expression to get the first address element of first customer followed by projection of phone property.

db.col.aggregate(
{"$project":{
  "phone":{
    "$let":{
      "vars":{
        "customer":{"$arrayElemAt":["$customers",0]}
      },
      "in":{
        "$let":{
          "vars":{
            "address":{"$arrayElemAt":["$$customer.addresses",0]}
          },
          "in":"$$address.phone"
        }
      }
    }
  }
}})

1 Comment

I see $let was the missing key. @mickl user answered a min sooner so I should accept his despite the similarity in answer

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.