2Fast4YouBR
2Fast4YouBR

Reputation: 1042

MongoDB Filter only IF ANY

Mongo Playgound

Lets say I have these results:

A)

[
{_id: 1, Name: 'A', Price: 10, xx:0},
{_id: 2, Name: 'B', Price: 15, xx:0},
{_id: 3, Name: 'A', Price: 100, xx:1},
{_id: 4, Name: 'B', Price: 150, xx:1},
]

B)

[
{_id: 1, Name: 'A', Price: 10, xx:0},
{_id: 2, Name: 'B', Price: 15, xx:0},
]

I want to:

Should I do a MAP & FILTER on root docs? or some kind of MATCH with conditionals? or Redact?

Results desired Ex.:

A) Removed x:0 because exists x:1, so returned only x:1

[
{_id: 3, Name: 'A', xx:1},
{_id: 4, Name: 'B', xx:1},
]

B) Returned only x:0 as there are only x:0

[
{_id: 1, Name: 'A', xx:0},
{_id: 2, Name: 'B', xx:0},
]

Upvotes: 0

Views: 70

Answers (1)

Arun Kumar Mohan
Arun Kumar Mohan

Reputation: 11915

  1. Group the documents by the xx field and add the grouped docs to the docs array using $push.

  2. Sort the docs by the _id field in descending order.

  3. Limit the result to 1.

If there are documents with both xx: 0 and xx: 1 values, only the xx: 1 group would be returned since we're sorting in descending order and limiting the result to the first group. If there are no documents with xx: 1 but documents with xx: 0 exist, the first group would be xx: 0 which gets returned.

You can then use $unwind to return a document for each grouped document and $replaceRoot to lift the document to the root level.

db.collection.aggregate([
  {
    $group: {
      _id: "$xx",
      docs: {
        $push: "$$ROOT",
      }
    }
  },
  {
    $sort: {
      _id: -1,
    }
  },
  {
    $limit: 1,
  },
  {
    $unwind: "$docs"
  },
  {
    $replaceRoot: {
      newRoot: "$docs"
    },
  }
])

MongoPlayground


If there might be docs with an xx value other than 0 and 1, you should filter those out using $match before grouping the docs using $group.

db.collection.aggregate([
  {
    $match: {
      xx: {
        $in: [
          0,
          1
        ]
      }
    }
  },
  {
    $group: {
      _id: "$xx",
      docs: {
        $push: "$$ROOT",
      }
    }
  },
  {
    $sort: {
      _id: -1,
    }
  },
  {
    $limit: 1,
  },
  {
    $unwind: "$docs"
  },
  {
    $replaceRoot: {
      newRoot: "$docs"
    },
  }
])

MongoPlayground

Upvotes: 1

Related Questions