Query for a Portion of a Nested Array Element in a Document Using $slice
Now that you're familiar with how projections work in Mongo what we can do is we can actually dive down even further to be able to be more explicit with what gets returned back for nested collections.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

So I'm going to create a new document here for Blink and it's going to have multiple authors, it's going to have a Malcolm Gladwell as one of the authors and then a Ghost Writer as the second one. What the goal is going to be is once this is added to the database then I want to be able to query this document but I want to be able to query it and I want to leave out the second author so it only pulls in Malcolm Gladwell. So that's going to be something that we can use what is called the slice method inside of Mongo and so we'll get into how that works.

large

Now if I go into the terminal and run this it is inserted.

large

Now earlier on in the course, I inserted blank but in between guides I went and I removed it. I'll show you how to remove documents in a later guide but just so it's not confusing. I removed it so we can be working just with the single one. So now that is in the database I'm going to come to delete here and let's create our query. We are going to start with

db.books.find

As usual, here I'm going to give it two objects. The first object is our query object so here I'm going to say Blink and let's indent this and then I'm also going and pretty at the very end.

large

Just to make sure that all of this is working I'm going to come run it and you can see that Malcolm Gladwell and the Ghost Writer are both included in that query.

large

So with our projection let's come here and our set of constraints. I'm going to say that I want the publishedDate, So I do publishedDate: 1. I want the name: 1, and then I want authors. But instead of giving it a 1 like we've done in the past what I'm going to do is pass it an object and instead of passing in say name or one of the attributes inside I'm going to pass in a special function called $slice and with $slice what I can do is pass in and say I want this specific element in the array. So now if I copy this

large

and I run this you can see that it works.

large

So now what we've done is we've essentially created a query and we've gone into a nested collection and said I only want the very first element in that array. Now if we wanted to go the other direction then we could say $slice: 2 and that would bring us back the second item and so now it's showing the Ghost Writer and Malcolm Gladwell right here.

large

If we only wanted the Ghost Writer by himself I can say $slice: -1 and if I run that you can see only has the Ghost Writer.

large

So what exactly is going on here is that we're working with a very similar construct as that is contained in pretty much every other programming language which is our array manipulation. So what that means is if you remember back authors is an array. So the nice thing about working with Mongo is we're able to treat that array just like we would in a regular programming language. And in a regular language if I gave a -1 to an array index that will go backward and it will go pull whatever the last author is or the last element in the array and you'll pull that one whereas we could pass in and go one and two and bring the first couple items so that using the slice method is a very nice way of being able to go into nested collections and be able to retrieve only the data that you want to have.

Code

db.books.insert({
  "name": "Blink",
  "publishedDate": new Date(),
  "authors": [
    { "name": "Malcolm Gladwell" },
    { "name": "Ghost Writer" }
  ]
});


db.books.find(
  {
    name: "Blink"
  },
  {
    publishedDate: 1,
    name: 1,
    authors: { $slice: 1 }
  }
).pretty()