skip to Main Content

I was wondering if it was possible to somehow use the $match operator within the $sum function for aggregation.

{   "$unwind": "$info.avatarInfoList" },
{   "$unwind": "$info.avatarInfoList.equipList" },
{   "$unwind": "$info.avatarInfoList.equipList.flat.reliquarySubstats" },
{
    "$project": {
        "name" : "$name",
        "character" : "$info.avatarInfoList.avatarId",
        "artifact" : "$info.avatarInfoList.equipList.itemId",
        "statValue" : {
            "$sum": [
                 {"$match" : { "$info.avatarInfoList.equipList.flat.reliquarySubstats.appendPropId" : "FIGHT_PROP_CRITICAL_HURT" } },
                 {"$multiply": [2, {"$match" : { "$info.avatarInfoList.equipList.flat.reliquarySubstats.appendPropId" : "FIGHT_PROP_CRITICAL" } }]}
            ]
        },
    }
},
{ "$sort": { "statValue": -1 }},
{ '$limit' : 30 }
]).to_list(length=None) 
print(data)

I want to be able to use the value of the $sum operator within the project fields somehow, I just don’t really understand what the right approach would be for this.

Sample Input (may be too long):
https://www.toptal.com/developers/hastebin/ixamekaxoq.json

Sample Output:
( 2 * FIGHT_PROP_CRITICAL ) + FIGHT_PROP_CRITICAL_HURT sorted from highest to lowest for each item.

{name: hat, character: Slayer, artifact: 13, statValue : 25.6}

2

Answers


  1. It’s not quite clear what you want to achieve, but as mentioned you want to be using $cond here.

    like so:

    {
      "$project": {
        "statValue": {
          "$sum": [
            {
              $cond: [
                { // if this condition is true (prop id = prop critical hurt )
                  $eq: [
                      "$info.avatarInfoList.equipList.flat.reliquarySubstats.appendPropId",
                      "FIGHT_PROP_CRITICAL_HURT"
                  ]
                },
                { // then use this value for the "$sum"
                  "$multiply": [
                      2,
                      "$info.avatarInfoList.equipList.flat.reliquarySubstats.statValue"
                  ]
                },
                0 // otherwise use this value for the sum.
              ]
            }
          ]
      }
    }
    

    Mongo Playground

    Login or Signup to reply.
  2. There are still a few ambiguities about how you want to aggregate your data, but using the full document from your link, here’s one way to produce the output you want.

    N.B.: Weapons in the "equipList" don’t have "reliquarySubstats" so they show a "statValue" of null in the output.

    db.collection.aggregate([
      {"$unwind": "$info.avatarInfoList"},
      {"$unwind": "$info.avatarInfoList.equipList"},
      {
        "$project": {
          "_id": 0,
          "name": 1,
          "character": "$info.avatarInfoList.avatarId",
          "artifact": "$info.avatarInfoList.equipList.itemId",
          "statValue": {
            "$reduce": {
              "input": "$info.avatarInfoList.equipList.flat.reliquarySubstats",
              "initialValue": 0,
              "in": {
                "$switch": {
                  "branches": [
                    {
                      "case": {"$eq": ["$$this.appendPropId", "FIGHT_PROP_CRITICAL"]},
                      "then": {
                        "$add": [
                          "$$value",
                          {"$multiply": [2, "$$this.statValue"]}
                        ]
                      }
                    },
                    {
                      "case": {"$eq": ["$$this.appendPropId", "FIGHT_PROP_CRITICAL_HURT"]},
                      "then": {"$add": ["$$value", "$$this.statValue"]}
                    }
                  ],
                  "default": "$$value"
                }
              }
            }
          }
        }
      },
      {"$sort": {"statValue": -1}}
    ])
    

    Try it on mongoplayground.net.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search