2

I'd like to fetch a single element within an array in my document, without fetching the whole array itself. Is that possible to do using Mongoose?

I've tried using dot.notation but it doesn't seem to work - It just fetches empty nested objects after the "index dot"

  // Here I'd like to get 
  // The first undo-ed item from the first board within my `boardBucket`

  Room.findOne({name: this.name}, `boardBucket.items.0.undoedItems.1`, (err, result)=> {
    if (err) throw err;
    console.log(JSON.stringify(result, null, 4));
  })

Is there any way to achieve this?

Reasons I'd like to avoid fetching the whole array

  • My objects are quite large and would result in memory issues if I fetched them back in their entirety
  • It's inefficient however one looks at it.

Here's my Schema in case it helps:

var roomSchema = new mongoose.Schema({
    name: String,
    boardBucket: {
      currentBoardId: String,
      items: [
        {
          boardId: String,
          boardItems: Array,
          undoedItems: Array, // <- Need to get a *single* element from this array
          viewPosition: String
        }
      ]
    }
});
1
  • Did you find any solution to this? Commented Aug 29, 2018 at 12:42

1 Answer 1

5

you can use slice funtionality of query provided by mongoose. Go through mongoose documentation on slice for better understanding.

According to the documentation:

slice([path], val)

Specifies a $slice projection for an array.

Parameters:

[path] <String>
val <Number> number/range of elements to slice

Try this for your problem, i hope it works:

Room.findOne({name: this.name})
    .slice('boardBucket.items', 1)
    .slice('boardBucket.items.undoedItems', [1,1])
    .exec()

This will return the first element of the items array, and the second of undoedItems.

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

5 Comments

Disclaimer: I'm not the downvoter - However what you posted wouldn't work with nested arrays
@NicholasKyriakides This actually will do what you want if you chain a second slice call to what ravi shows of .slice('boardBucket.items.undoedItems', [1,1]). That way both array levels are sliced.
I will update the answer according to @JohnnyHK suggestion. i didnt look for the first item in undoedItem .I just looked for first item in items.
@JohnnyHK does the slice chaining fetch only the item I'm after? Fetch here meaning from the mongoDB server my db runs to my server that calls find() - Or does mongoose fetch the whole doc but just return me the sliced-sliced item?
@NicholasKyriakides Yes, the slice filtering is done server-side. The query gets translated to the following when sent to the server: rooms.findOne({}) { fields: { 'boardBucket.items': { '$slice': 1 }, 'boardBucket.items.undoedItems': { '$slice': [ 1, 1 ] } } }

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.