One of the great features of MongoDB is the ability to store an array in a
document.
While I’m fully aware that there are issues with storing unbounded arrays in
MongoDB, due to document size limitations, there are times when you may want to
store data in an array that is in fact bounded.
I do it from time to time, usually to track the last x
values. Because I’m
keeping a fixed number of values, truncating at the time of save, the document
can’t get too out of control.
When storing data in this fashion, I’ll usually want to grab the last item on
the list, which usually represents the latest item.
When querying, without specifying which fields (“projecting” as they call it),
you end up getting the entire array back, so you have to tell MongoDB which
fields you want to return. For an array, you can pass in an additional object
and tell it that you’d like to slice off the last item for the return:
// Returns the entire array:
db.table.find({}, { array: 1
// Returns the last array item:
db.table.find({}, { array: { $slice: -1 }
Very similar to using .slice()
in JavaScript, just with the MongoDB-centric
syntax. The value of -1
says “start at the first item, and go backwards one”
which in this case, is the last item of the array, since it loops around.
One thing I had noticed with this syntax, is that when using it by itself, like
the aforementioned code snippet, you still receive the rest of the fields, and
the array is truncated. If you only want to include the last item of the array,
I would simply include the _id
in the return as well, which will limit the
return to only those fields:
// Returns ONLY the _id and the last array item:
db.table.find({}, { _id: 1, array: { $slice: -1 }
While it’s not something I usually need to do, you can also use the $slice
syntax to pull the first item of an array as well:
// Returns the first array item:
db.table.find({}, { array: { $slice: 1 }
Unlike working with an array and .slice()
in JavaScript, the MongoDB $slice
syntax works with 1
being the first element of the array instead of 0
.