Return subdocument array elements after matched element

Viewed 42

I have a document that basically looks like this:

{
    _id: ObjectId("5b980578db509b467960ef50"),
    items: [
        {
            _id: ObjectId("5b980578db509b467960ef90"),
            date: 2010-10-10T00:00:00.000Z
        },
        {
            _id: ObjectId("5b980578db509b467960ef91"),
            date: 2010-10-11T00:00:00.000Z
        },
        {
            _id: ObjectId("5b980578db509b467960ef92"),
            date: 2010-10-12T00:00:00.000Z
        },
        {
            _id: ObjectId("5b980578db509b467960ef93"),
            date: 2010-10-13T00:00:00.000Z
        },
        {
            _id: ObjectId("5b980578db509b467960ef94"),
            date: 2010-10-14T00:00:00.000Z
        },
        {
            _id: ObjectId("5b980578db509b467960ef95"),
            date: 2010-10-15T00:00:00.000Z
        }
     ]
}

I'm trying construct a query where I can get all Items after the ObjectId I have (i.e. ObjectId("5b980578db509b467960ef92")).

The result of my query should look like this:

{
    _id: ObjectId("5b980578db509b467960ef50"),
    items: [
        {
            _id: ObjectId("5b980578db509b467960ef93"),
            date: 2010-10-13T00:00:00.000Z
        },
        {
            _id: ObjectId("5b980578db509b467960ef94"),
            date: 2010-10-14T00:00:00.000Z
        },
        {
            _id: ObjectId("5b980578db509b467960ef95"),
            date: 2010-10-15T00:00:00.000Z
        }
     ]
}

Also, I want all Items after the corresponding date value of a given Item.

I'm currently using a two query approach where I get the matching Item based on ObjectID, then use the date value to find all Items afterwards.

Is there a "better" way to do this in one query?

1 Answers

You can use $indexOfArray to find the index for matching element and use $slice to get all the elements from matching index to end of array in 3.4. In essence get last elements till the matching index.

db.colname.aggregate([
  {"$project":{
    "items":{
      "$slice":[
        "$items",{
          "$multiply":[
            {"$subtract":[
              {"$size":"$items"},
              {"$add":[{"$indexOfArray":["$items._id",ObjectId("5b980578db509b467960ef92")]},1]}
            ]},
           -1
          ]
        }
      ]
    }
  }}
])
Related