3

Consider following collection in mongoDB :

{a:[4,2,8,71,21]}
{a:[24,2,2,1]}
{a:[4,1]}
{a:[4,2,8,21]}
{a:[2,8,71,21]}
{a:[4,2,8]}

How can I get following results in a most easily:

Getting nth element of array

{a:4}
{a:24}
{a:4}
{a:4}
{a:2}
{a:4}

Getting elements 2 to 4

{a:[8,71,21]}
{a:[2,1]}
{a:[]}
{a:[8,21]}
{a:[71,21]}
{a:[8]}

And other similar queries.

1 Answer 1

7

What you are looking for is the $slice projection.

Getting a number of elements from the beginning of an array

You can pass a simple $limit with a number of values to return (eg. 1):

> db.mycoll.find({}, {_id: 0, a: { $slice: 1}})
{ "a" : [ 4 ] }
{ "a" : [ 24 ] }
{ "a" : [ 4 ] }
{ "a" : [ 4 ] }
{ "a" : [ 2 ] }
{ "a" : [ 4 ] }

Getting a range of elements

You can pass an array with parameters of ( $skip, $limit ).

Note: to match your expected output you would have to find elements 3 to 5 (skip the first 2 elements, return the next 3):

> db.mycoll.find({}, {_id: 0, a: { $slice: [2,3]}})

{ "a" : [ 8, 71, 21 ] }
{ "a" : [ 2, 1 ] }
{ "a" : [ ] }
{ "a" : [ 8, 21 ] }
{ "a" : [ 71, 21 ] }
{ "a" : [ 8 ] }

Getting the nth element of array

Pass the number of elements to $skip and a value of 1 for the limit.

For example, to find the second element you need to skip 1 entry:

> db.mycoll.find({}, {_id: 0, a: { $slice: [1,1]}})

{ "a" : [ 2 ] }
{ "a" : [ 2 ] }
{ "a" : [ 1 ] }
{ "a" : [ 2 ] }
{ "a" : [ 8 ] }
{ "a" : [ 2 ] }

Note that the $slice operator:

  • always returns an array
  • will return an empty array for documents that match the find criteria but return an empty result for the $slice selection (eg. if you ask for the 5th element of an array with only 2 elements)
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, in case one I want to get scaler value: {'a':'x'} and not {'a':['x']}
The $slice operator always returns an array. I don't believe there is syntax (as at MongoDB 2.2) to project a single simple array element as a scalar. You could achieve this with MapReduce, but that seems like overkill compared to just converting the single element array returned by $slice to a scalar in your application code if needed. If your array contained embedded documents and you wanted to match specific values (not an array position) you could use the $elemMatch projection to return the first matching element.

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.