Project Last element in nested array

Hi, I’m trying to build a projection that can help me with versioning. I’ve taken guidance from Building with Patterns: The Polymorphic Pattern | MongoDB this leaves me with a document which has an array of objects, some of these objects may also be arrays. I’ve abstracted an example document below:

[
  {
    Title:"hello",
    keyPoints: [
      {
        text: "Line 1"
      },
      [
        {
          text: "Line 2"
        },
        {
          text: "Line 2 version 2"
        }
      ],
      {
        text: "Line 3"
      }
    ]
  }
]

I aspire to have an output of:

Title:“hello”,
text: “Line 1”,
text: “Line 2 version 2”,
text: “Line 3”

I’ve been trying so far (unsuccessfully with the arrayElemAt and the slice operators) I haven’t been able to test the $last operator as its not supported on my db ( I plan to upgrade).

Please share what you tried because intuitively it would be the way I would go.

I would have a $map on keyPoints that would check if I have an object or an array. In the case of an object the mapped value would be $$this and for array I the mapped value would be $slice with -1 position.

1 Like

HI,
I’ve attached screenshots of the errors I got:

In the meantime I’ve upgraded from mdb:4.04 to 6.0.4.
I’m hoping this means I can use $getField and $last in my query.

I used ChatGPT to create a mongo query to achieve this. I think it could be done neater using the operators available in 6.0+

db.collection.aggregate([
  {
    $project: {
      Title: 1,
      keyPoints: {
        $map: {
          input: "$keyPoints",
          in: {
            $arrayElemAt: [
              "$$this",
              {
                $subtract: [
                  {
                    $size: "$$this"
                  },
                  1
                ]
              }
            ]
          }
        }
      }
    }
  }
])

see this working mongoplayground

The document you have in your playground is different from the one you shared in your first post.

The one in your playground presents an easier problem since all elements of keyPoints in an array. In your original document keyPoints had a mix of objects and arrays confirmed by your screenshot.

With an array of arrays you do not have to

You simply

The above give the following trivial $map for your $project.

{ "$map" : {
  "input" : "$keyPoints" ,
   in : { '$slice': [ "$$this" , -1 ] }
} }

As for

ChatGPT 0 - steevej 2

I will not tell you where I scored my other point.