1

Suppose I have a document structure where one of the fields, X, is an array av objects as shown below.

"X" : [ 
    {
      "A" : "abc",
      "B" : 123
    },
    {
      "A" : "wer",
      "B" : 124
    },
    {
      "A" : "fgh",
      "B" : 124
    }
]

How can I project only the document where field B has the highest values? And if the maximum value is shared by several documents, I just want to return one of them (not important which one). In this case the result could look like:

"X" : [ 
    {
      "A" : "wer",
      "B" : 124
    }
]

3 Answers 3

2

What about this one:

db.collection.aggregate([
   {
      $set: {
         X: {
            $filter: {
               input: "$X",
               cond: { $eq: ["$$this.B", { $max: "$X.B" }] }
            }
         }
      }
   },
   { $set: { X: { $arrayElemAt: ["$X", 0] } } }
])
Sign up to request clarification or add additional context in comments.

3 Comments

This produces the error "Unrecognized pipeline stage name: '$set'".
$set is new in 4.2. Try $addField instead
Yeah I figured, ended up doing that. Thanks!
1

You can use $reduce

  db.collection.aggregate([
      {
        "$project": {
          "X": {
            $reduce: {
              input: "$X",
              initialValue: {},
              in: {
                $cond: [ { "$gt": [ "$$this.B", "$$value.B" ]}, // Condition Check
                  "$$this",      // If condition true ($$this - Current Object)  
                  "$$value"      // If condition false $$value - Previous Returned Object
                ]
              }
            }
          }
        }
      }
    ])

Mongo Playground

Comments

0

Updated answer:

Another option that results in the full object being returned at the end:


    [
    {$unwind: {
      path: "$X"
    }}, 
    {$sort: {
      "X.B": -1
    }}, 
    {$group: {
      _id: { _id: "$_id"},
      X: {
        $first: "$X"
      }
    }}]

Original answer:

You can use the $max operator (https://docs.mongodb.com/manual/reference/operator/aggregation/max/).

    [{$project: {
      X: {$max: "$X.B"}
    }}]

4 Comments

Have a look on this Url - mongoplayground.net/p/0wu_q4kjYjo
This sorts by A - you get {A: "wer", B: 124} because of A: "wer", not due to B: 124
I think you'd want to change that to X: {$max: "$X.B"}. In any case, this will only return the maximum value. I want the whole object to be returned.
Good catch. Updated to be "$X.B". As you pointed out, that only returns the maximum value and not the entire object.

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.