Home > front end >  Match elements before and after some criteria
Match elements before and after some criteria

Time:04-22

Suppose I have an ordered (by $sort aggregation pipeline stage) list of documents:

    { x: 0 }
    { x: 1 }
    { x: 3 }
    { x: 4 }
    { x: 5 }
    { x: 6 }

Now I can select all documents where x >= 3 using the aggregation pipeline stage:

    { $match: { x: { $gte: 3 } } }

But is it also possible to match all documents where x >= 3 AND the first element before the first matched element in a single query?

The expected result is:

    { x: 1 }
    { x: 3 }
    { x: 4 }
    { x: 5 }
    { x: 6 }

(I need this for relay compliant pagination)

CodePudding user response:

You can use $facet to separate into 2 pipelines for processing. Then use $setUnion to regroup the result back.

db.collection.aggregate([
  {
    "$facet": {
      "smaller": [
        {
          "$match": {
            x: {
              $lt: 3
            }
          }
        },
        {
          $sort: {
            x: -1
          }
        },
        {
          "$limit": 1
        }
      ],
      "larger": [
        {
          "$match": {
            x: {
              $gte: 3
            }
          }
        }
      ]
    }
  },
  // cosmetics to revert back to original form
  {
    "$project": {
      final: {
        "$setUnion": [
          "$smaller",
          "$larger"
        ]
      }
    }
  },
  {
    "$unwind": "$final"
  },
  {
    "$replaceRoot": {
      "newRoot": "$final"
    }
  }
])

Here is the Mongo playground for your reference.

  • Related