问:
How do I add a sorted array of objects within a mongo aggregate pipeline?
I'm using a mongo Aggregate pipeline, to transform documents.  The why is simple enough:  make the documents easier to read from.

The documents start off looking something like this:

workouts...

```<code>{
  "_id": {
    "$oid": "59ccd28338c8f273346b1997"
  },
  "updateAt": {
    "$date": {
      "$numberLong": "1506952456789"
    }
  },
  "createdAt": {
    "$date": {
      "$numberLong": "1506678599417"
    }
  },
  "name": "Strength 1",
  "phase": {
    "$oid": "59ccd1a738c8f273346b1988"
  },
  "primer": {
    "$oid": "5df7625ce69199d3fa3c4746"
  },
  "__v": 0,
  "_partition": "PUBLIC"
}
</code>```

which is little more than a placeholder: almost all the information that comprises a workout is held in other collections, tied together by this documents' _id.

do that first lookup^ to get the primer (aka warmup) reference.

use that primer ref to get the warmup, by looking up that reference in two other collections and joining the outputs (I won't expand on those, as I do that bit fine already)

then head to a fourth collection, and use the original object Id to get another inter-connector type document, with data like this:

plans...

```<code>{
  "_id": {
    "$oid": "59ccd8c738c8f273346b199c"
  },
  "updatedAt": {
    "$date": {
      "$numberLong": "1506597063143"
    }
  },
  "createdAt": {
    "$date": {
      "$numberLong": "1506597063143"
    }
  },
  "workout": {
    "$oid": "59ccd28338c8f273346b1997"
  },
  "exercise": {
    "$oid": "59cccdc938c8f273346b1985"
  },
  "code": "A1",
  "weekOne": {
    "$oid": "59ccd8c738c8f273346b1998"
  },
  "weekTwo": {
    "$oid": "59ccd8c738c8f273346b1999"
  },
  "weekThree": {
    "$oid": "59ccd8c738c8f273346b199a"
  },
  "weekFour": {
    "$oid": "59ccd8c738c8f273346b199b"
  },
  "__v": 0,
  "_partition": "PUBLIC"
}
</code>```

then use the exercise-Id on a fifth collection to get the exercise info, which is stored like this...

exercises...

```<code>{
  "_id": {
    "$oid": "59cccdc938c8f273346b1985"
  },
  "updatedAt": {
    "$date": {
      "$numberLong": "1579906674667"
    }
  },
  "createdAt": {
    "$date": {
      "$numberLong": "1506594249199"
    }
  },
  "name": "DB Split Squat",
  "timing": "3-0-1-0",
  "videoUrl": "https://youtu.be/KgPxYpvHUe8",
  "cues": "Keep your chest tall and shoulders back.\nAs you descend, shoulders and hips should stay in a line (don't lean forward).\nHips should go straight down and straight up.\nYou should have an approximately 90-degree angle for both knees.\nBack knee should come close, but not touch, the ground.",
  "__v": 0,
  "is_weighted": true,
  "_partition": "PUBLIC"
}
</code>```

and use the "weekOne" etc object IDs in a sixth collection to retrieve the structure (reps & sets) of the workout.  Data for that looks like this:

programmings...

```<code>{
  "_id": {
    "$oid": "59ccd8c738c8f273346b1999"
  },
  "updatedAt": {
    "$date": {
      "$numberLong": "1506597063068"
    }
  },
  "createdAt": {
    "$date": {
      "$numberLong": "1506597063068"
    }
  },
  "sets": 3,
  "setRest": 30,
  "reps": "8-10",
  "repRest": null,
  "supersetRest": null,
  "exercise": {
    "$oid": "59cccdc938c8f273346b1985"
  },
  "__v": 0,
  "_partition": "PUBLIC"
}
</code>```

We want to generate new documents that contain all the information needed for a given workout, in one document.  (I am sure there are various pros/cons of alternative approaches, however this decision has been made; my job is not to debate it, but to implement it :) )

My Current Aggregate Pipeline

```<code>[
  {
    // NOTE limiter is just for testing!
    // remove when ready to go live!
    $limit: 1
  },
  {
    // Fetch the Warmup top-level fields
    $lookup: {
      from: "primers",
      localField: "primer",
      foreignField: "_id",
      pipeline: [
        {
          $project: {
            _id: 0,
            name: 1,
            show_reminder: 1,
            note: 1,
            exercises: 1,
          },
        },
      ],
      as: "warmup",
    },
  },
  {
    // squish the warmup 1-element array to an object
    $unwind: {
      path: "$warmup",
      preserveNullAndEmptyArrays: false,
    },
  },
  {
    // fetch the warmup exercise info
    $lookup: {
      from: "primer_plans",
      localField: "primer",
      foreignField: "primer",
      pipeline: [
        {
          $lookup: {
            from: "exercises",
            localField: "exercise",
            foreignField: "_id",
            pipeline: [
              {
                $project: {
                  _id: 0,
                  name: 1,
                  cues: 1,
                  videoUrl: 1,
                },
              },
            ],
            as: "exercise",
          },
        },
        {
          $project: {
            _id: 0,
            order: 1,
            exercise: 1,
            repText: 1,
          },
        },
        {
          $unwind: "$exercise",
        },
      ],
      as: "warmup.exercises",
    },
  },
  {
    // add arrays to populate later
    $addFields:
      // also add references to og docs, in case needed
      {
        overview: {
          supersetted: [],
          nonSupersetted: [],
        },
        workout: {
          supersetted: [],
          nonSupersetted: [],
        },
        references: {
          usedInPhase: {
            _id: "$phase",
          },
          warmup: {
            _id: "$primer",
          },
          ogWorkout: "$_id",
        },
      },
  },
  {
    // Fetch the Workout fields (and expand exercises)
    $lookup:
      // this is used to fill the non-supersetted version
      {
        from: "plans",
        localField: "_id",
        foreignField: "workout",
        pipeline: [
          {
            $lookup: {
              from: "exercises",
              localField: "exercise",
              foreignField: "_id",
              pipeline: [
                {
                  $project: {
                    _id: 0,
                    name: 1,
                    cues: 1,
                    videoUrl: 1,
                  },
                },
              ],
              as: "exercise",
            },
          },
          { $unwind: "$exercise" },
          {
            $lookup: {
              from: "programmings",
              localField: "weekOne",
              foreignField: "_id",
              pipeline: [
                {
                  $project: {
                    _id: 0,
                    sets: 1,
                    setRest: 1,
                    reps: 1,
                    repRest: 1,
                  },
                },
                {
                  $addFields: {
                    week: 1,
                  },
                },
              ],
              as: "weekOne",
            },
          },
          { $unwind: "$weekOne" },
          {
            $lookup: {
              from: "programmings",
              localField: "weekTwo",
              foreignField: "_id",
              pipeline: [
                {
                  $project: {
                    _id: 0,
                    sets: 1,
                    setRest: 1,
                    reps: 1,
                    repRest: 1,
                  },
                },
                {
                  $addFields: {
                    week: 2,
                  },
                },
              ],
              as: "weekTwo",
            },
          },
          { $unwind: "$weekTwo" },
          {
            $lookup: {
              from: "programmings",
              localField: "weekThree",
              foreignField: "_id",
              pipeline: [
                {
                  $project: {
                    _id: 0,
                    sets: 1,
                    setRest: 1,
                    reps: 1,
                    repRest: 1,
                  },
                },
                {
                  $addFields: {
                    week: 3,
                  },
                },
              ],
              as: "weekThree",
            },
          },
          { $unwind: "$weekThree" },
          {
            $lookup: {
              from: "programmings",
              localField: "weekFour",
              foreignField: "_id",
              pipeline: [
                {
                  $project: {
                    _id: 0,
                    sets: 1,
                    setRest: 1,
                    reps: 1,
                    repRest: 1,
                  },
                },
                {
                  $addFields: {
                    week: 4,
                  },
                },
              ],
              as: "weekFour",
            },
          },
          { $unwind: "$weekFour" },
          {
            $project: {
              _id: 0,
              code: 1,
              superset: { $substr: ["$code", 0, 1] },
              supersetIndex: { $substr: ["$code", 1, 1] },
              exercise: "$exercise",
              valuesThatVaryByWeek: [
                "$weekOne",
                "$weekTwo",
                "$weekThree",
                "$weekFour",
              ],
            },
          },
        ],
        as: "workout.nonSupersetted",
      },
  },
  {
    /**
     * newField: The new field name.
     * expression: The new field expression.
     */
    $addFields: {
      "workout.allWorkoutIndices": {
        $map: {
          input: "$workout.nonSupersetted",
          in: {
            $getField: {
              field: "code",
              input: "$$this",
            },
          },
        },
      },
    },
  },
  {
    // clone to workout supersetted
    $set: {
      "workout.supersetted": "$workout.nonSupersetted",
    },
  },
  {
    // add the warmup name to the references
    $lookup: {
      from: "primers",
      localField: "primer",
      foreignField: "_id",
      pipeline: [
        {
          $project: {
            _id: 0,
            name: 1,
          },
        },
      ],
      as: "references.warmup.name",
    },
  },
  {
    $unwind: {
      path: "$references.warmup.name",
    },
  },
  {
    $unset: [
      "_partition",
      "__v",
      "createdAt",
      "updateAt",
      "phase",
      "primer",
    ],
  },
  {
    // output to programData.workoutsTester
    $out: {
      db: "programData",
      coll: "workoutsTester",
    },
  },
]
</code>```

Current output

The new workout document now looks like...

```<code>{
  "_id": {
    "$oid": "59ccd28338c8f273346b1997"
  },
  "name": "Strength 1",
  "warmup": {
    "name": "Lower Body Lifting",
    "show_reminder": true,
    "note": "",
    "exercises": [
      {
        "order": 1,
        "exercise": {
          "name": "Frog Squat",
          "videoUrl": "https://youtu.be/zZDq6OejYBM",
          "cues": "A great hamstring stretch and hip mobility focused exercise"
        },
        "repText": "5-8 reps"
      },
      {
        "order": 2,
        "exercise": {
          "name": "Frog Squat with Reach",
          "videoUrl": "https://youtu.be/Kem3YR2Fic4",
          "cues": "Different from the standard Frog Squat!\nMore of a full body movement challenge,\nLess stretch on the hamstrings & hip-hinge,\nMore challenging to thoracic spine mobility"
        },
        "repText": "5-8 reps"
      },
      {
        "order": 3,
        "exercise": {
          "name": "Five point Lunge",
          "videoUrl": "https://youtu.be/bBdSuretuHY",
          "cues": ""
        },
        "repText": "Three reps each leg"
      },
      {
        "order": 4,
        "exercise": {
          "name": "Three point SLDL",
          "videoUrl": "https://youtu.be/r1hPMviYbLQ",
          "cues": ""
        },
        "repText": "Three reps each leg"
      },
      {
        "order": 5,
        "exercise": {
          "name": "Backwards Spiderman",
          "videoUrl": "https://youtu.be/drHorMgQBWM",
          "cues": ""
        },
        "repText": "If you have time add this full-body mobility drill"
      },
      {
        "order": 6,
        "exercise": {
          "name": "Walking Bow and Arrow",
          "videoUrl": "https://youtu.be/7MeaaZ8pRNQ",
          "cues": ""
        },
        "repText": "If you have time add this full-body mobility drill"
      }
    ]
  },
  "overview": {
    "supersetted": [],
    "nonSupersetted": []
  },
  "workout": {
    "nonSupersetted": [
      {
        "code": "A1",
        "superset": "A",
        "supersetIndex": "1",
        "exercise": {
          "name": "DB Split Squat",
          "videoUrl": "https://youtu.be/KgPxYpvHUe8",
          "cues": "Keep your chest tall and shoulders back.\nAs you descend, shoulders and hips should stay in a line (don't lean forward).\nHips should go straight down and straight up.\nYou should have an approximately 90-degree angle for both knees.\nBack knee should come close, but not touch, the ground."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "A2",
        "superset": "A",
        "supersetIndex": "2",
        "exercise": {
          "name": "Cable Pull-Through",
          "videoUrl": "https://youtu.be/2lXOIeiWYk4",
          "cues": "Feet are slightly wider than shoulder width. Knees are bent about 10 degrees.\nReach back between your legs with the rope attachment.\nUse your glutes to push your hips forward and stand up."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "B1",
        "superset": "B",
        "supersetIndex": "1",
        "exercise": {
          "name": "Semi-supinated grip Pull-up",
          "videoUrl": "https://youtu.be/R-j7IvquHwE",
          "cues": "\"Semi supinated\" means that your palms are facing one another. If you do not have a bar that allows for this, use a supinated grip (palms toward you).\nKeep your chest up.\nSqueeze shoulder blades together at the top of the movement.\nIf you do not have an assisted chin-up machine, you can use a lat pulldown instead."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "4-6",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "4-6",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "C1",
        "superset": "C",
        "supersetIndex": "1",
        "exercise": {
          "name": "Stability Ball Hip Raise to Bridge",
          "videoUrl": "https://youtu.be/MEqwmz-nfVo",
          "cues": "Squeeze the glutes to get the hips off the floor.\nKeeping the glutes tight, bring the ball in toward you forming a 90 degree angle of the knees."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 2,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 2,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "C2",
        "superset": "C",
        "supersetIndex": "2",
        "exercise": {
          "name": "Bow and Arrow",
          "videoUrl": "https://youtu.be/Fq9Jlz261m4",
          "cues": "If you imagine an archer, you will naturally do this exercise correctly.\nStand up tall.\nKeep the elbow of the pulling arm up.\nSqueeze the shoulder blades together during the iso hold."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "10-12",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 2,
            "setRest": 30,
            "reps": "10-12",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 2,
            "setRest": 30,
            "reps": "10-12",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "B2",
        "superset": "B",
        "supersetIndex": "2",
        "exercise": {
          "name": "One-Arm Semi-sup' Grip Incline DB Bench",
          "videoUrl": "https://youtu.be/tkPqct_J338",
          "cues": "Hold a dumbbell only in one hand while performing this exercise.\nEngage the core to resist rotation."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 60,
            "reps": "8-10",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 3,
            "setRest": 60,
            "reps": "8-10",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 3,
            "setRest": 60,
            "reps": "6-8",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      }
    ],
    "allWorkoutIndices": [
      "A1",
      "A2",
      "B1",
      "C1",
      "C2",
      "B2"
    ],
    "supersetted": [
      {
        "code": "A1",
        "superset": "A",
        "supersetIndex": "1",
        "exercise": {
          "name": "DB Split Squat",
          "videoUrl": "https://youtu.be/KgPxYpvHUe8",
          "cues": "Keep your chest tall and shoulders back.\nAs you descend, shoulders and hips should stay in a line (don't lean forward).\nHips should go straight down and straight up.\nYou should have an approximately 90-degree angle for both knees.\nBack knee should come close, but not touch, the ground."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "A2",
        "superset": "A",
        "supersetIndex": "2",
        "exercise": {
          "name": "Cable Pull-Through",
          "videoUrl": "https://youtu.be/2lXOIeiWYk4",
          "cues": "Feet are slightly wider than shoulder width. Knees are bent about 10 degrees.\nReach back between your legs with the rope attachment.\nUse your glutes to push your hips forward and stand up."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "B1",
        "superset": "B",
        "supersetIndex": "1",
        "exercise": {
          "name": "Semi-supinated grip Pull-up",
          "videoUrl": "https://youtu.be/R-j7IvquHwE",
          "cues": "\"Semi supinated\" means that your palms are facing one another. If you do not have a bar that allows for this, use a supinated grip (palms toward you).\nKeep your chest up.\nSqueeze shoulder blades together at the top of the movement.\nIf you do not have an assisted chin-up machine, you can use a lat pulldown instead."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "4-6",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "4-6",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "C1",
        "superset": "C",
        "supersetIndex": "1",
        "exercise": {
          "name": "Stability Ball Hip Raise to Bridge",
          "videoUrl": "https://youtu.be/MEqwmz-nfVo",
          "cues": "Squeeze the glutes to get the hips off the floor.\nKeeping the glutes tight, bring the ball in toward you forming a 90 degree angle of the knees."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 2,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 2,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "C2",
        "superset": "C",
        "supersetIndex": "2",
        "exercise": {
          "name": "Bow and Arrow",
          "videoUrl": "https://youtu.be/Fq9Jlz261m4",
          "cues": "If you imagine an archer, you will naturally do this exercise correctly.\nStand up tall.\nKeep the elbow of the pulling arm up.\nSqueeze the shoulder blades together during the iso hold."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "10-12",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 2,
            "setRest": 30,
            "reps": "10-12",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 2,
            "setRest": 30,
            "reps": "10-12",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "B2",
        "superset": "B",
        "supersetIndex": "2",
        "exercise": {
          "name": "One-Arm Semi-sup' Grip Incline DB Bench",
          "videoUrl": "https://youtu.be/tkPqct_J338",
          "cues": "Hold a dumbbell only in one hand while performing this exercise.\nEngage the core to resist rotation."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 60,
            "reps": "8-10",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 3,
            "setRest": 60,
            "reps": "8-10",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 3,
            "setRest": 60,
            "reps": "6-8",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      }
    ]
  },
  "references": {
    "usedInPhase": {
      "_id": {
        "$oid": "59ccd1a738c8f273346b1988"
      }
    },
    "warmup": {
      "_id": {
        "$oid": "5df7625ce69199d3fa3c4746"
      },
      "name": {
        "name": "Lower Body Lifting"
      }
    },
    "ogWorkout": {
      "$oid": "59ccd28338c8f273346b1997"
    }
  }
}
</code>```

which is much closer, but still not quite there.

My current questions

The workout above, is, stripping out all the extra bumpf, basically this:

```<code>{
  ...,
  notSupersetted: [
    { superset: "a", supersetIndex: 1, <other data> },
    { superset: "c", supersetIndex: 1, ...},
    { superset: "a", supersetIndex: 2, ...},
    { superset: "c", supersetIndex: 2, ...},
    { superset: "b", supersetIndex: 2, ...},
    { superset: "b", supersetIndex: 1, ...}
  ],
  supersetted: []
  ...
}
</code>```

I need to:

find a way to add an index-ordering to notSupersetted. e.g. although they are listed as [a-1, c-1, a-2, c-2, b-2, b-1 ] these exercises should actually be done in alpha-numeric order, ie [ a1, a2, b1, b2, c1, c2 ].  How do I generate a workout index for them?

populate the supersetted field, which is basically just a rearrangement of the non-supersetted field in this form...

```<code>{
  ...,
  notSupersetted: [ <as before> ],
  supersetted: [
    {
      superset: "A",
      elements: [
        { index: 1, <other data> },
        { index: 2, ... }
      ]
    },
    {
      superset: "B",
      elements: [
        { index: 1, ...},
        { index: 2, ... }
      ]
    },
    {
      superset: "C",
      elements: [
        { index: 1, ...},
        { index: 2, ...}
      ]
    },
  ],
  ...
}
</code>```

Body:
I'm using a mongo Aggregate pipeline, to transform documents.  The why is simple enough:  make the documents easier to read from.

The documents start off looking something like this:

workouts...

{
  "_id": {
    "$oid": "59ccd28338c8f273346b1997"
  },
  "updateAt": {
    "$date": {
      "$numberLong": "1506952456789"
    }
  },
  "createdAt": {
    "$date": {
      "$numberLong": "1506678599417"
    }
  },
  "name": "Strength 1",
  "phase": {
    "$oid": "59ccd1a738c8f273346b1988"
  },
  "primer": {
    "$oid": "5df7625ce69199d3fa3c4746"
  },
  "__v": 0,
  "_partition": "PUBLIC"
}

which is little more than a placeholder: almost all the information that comprises a workout is held in other collections, tied together by this documents' _id.

do that first lookup^ to get the primer (aka warmup) reference.

use that primer ref to get the warmup, by looking up that reference in two other collections and joining the outputs (I won't expand on those, as I do that bit fine already)

then head to a fourth collection, and use the original object Id to get another inter-connector type document, with data like this:

plans...

{
  "_id": {
    "$oid": "59ccd8c738c8f273346b199c"
  },
  "updatedAt": {
    "$date": {
      "$numberLong": "1506597063143"
    }
  },
  "createdAt": {
    "$date": {
      "$numberLong": "1506597063143"
    }
  },
  "workout": {
    "$oid": "59ccd28338c8f273346b1997"
  },
  "exercise": {
    "$oid": "59cccdc938c8f273346b1985"
  },
  "code": "A1",
  "weekOne": {
    "$oid": "59ccd8c738c8f273346b1998"
  },
  "weekTwo": {
    "$oid": "59ccd8c738c8f273346b1999"
  },
  "weekThree": {
    "$oid": "59ccd8c738c8f273346b199a"
  },
  "weekFour": {
    "$oid": "59ccd8c738c8f273346b199b"
  },
  "__v": 0,
  "_partition": "PUBLIC"
}

then use the exercise-Id on a fifth collection to get the exercise info, which is stored like this...

exercises...

{
  "_id": {
    "$oid": "59cccdc938c8f273346b1985"
  },
  "updatedAt": {
    "$date": {
      "$numberLong": "1579906674667"
    }
  },
  "createdAt": {
    "$date": {
      "$numberLong": "1506594249199"
    }
  },
  "name": "DB Split Squat",
  "timing": "3-0-1-0",
  "videoUrl": "https://youtu.be/KgPxYpvHUe8",
  "cues": "Keep your chest tall and shoulders back.\nAs you descend, shoulders and hips should stay in a line (don't lean forward).\nHips should go straight down and straight up.\nYou should have an approximately 90-degree angle for both knees.\nBack knee should come close, but not touch, the ground.",
  "__v": 0,
  "is_weighted": true,
  "_partition": "PUBLIC"
}

and use the "weekOne" etc object IDs in a sixth collection to retrieve the structure (reps & sets) of the workout.  Data for that looks like this:

programmings...

{
  "_id": {
    "$oid": "59ccd8c738c8f273346b1999"
  },
  "updatedAt": {
    "$date": {
      "$numberLong": "1506597063068"
    }
  },
  "createdAt": {
    "$date": {
      "$numberLong": "1506597063068"
    }
  },
  "sets": 3,
  "setRest": 30,
  "reps": "8-10",
  "repRest": null,
  "supersetRest": null,
  "exercise": {
    "$oid": "59cccdc938c8f273346b1985"
  },
  "__v": 0,
  "_partition": "PUBLIC"
}

We want to generate new documents that contain all the information needed for a given workout, in one document.  (I am sure there are various pros/cons of alternative approaches, however this decision has been made; my job is not to debate it, but to implement it :) )

My Current Aggregate Pipeline

[
  {
    // NOTE limiter is just for testing!
    // remove when ready to go live!
    $limit: 1
  },
  {
    // Fetch the Warmup top-level fields
    $lookup: {
      from: "primers",
      localField: "primer",
      foreignField: "_id",
      pipeline: [
        {
          $project: {
            _id: 0,
            name: 1,
            show_reminder: 1,
            note: 1,
            exercises: 1,
          },
        },
      ],
      as: "warmup",
    },
  },
  {
    // squish the warmup 1-element array to an object
    $unwind: {
      path: "$warmup",
      preserveNullAndEmptyArrays: false,
    },
  },
  {
    // fetch the warmup exercise info
    $lookup: {
      from: "primer_plans",
      localField: "primer",
      foreignField: "primer",
      pipeline: [
        {
          $lookup: {
            from: "exercises",
            localField: "exercise",
            foreignField: "_id",
            pipeline: [
              {
                $project: {
                  _id: 0,
                  name: 1,
                  cues: 1,
                  videoUrl: 1,
                },
              },
            ],
            as: "exercise",
          },
        },
        {
          $project: {
            _id: 0,
            order: 1,
            exercise: 1,
            repText: 1,
          },
        },
        {
          $unwind: "$exercise",
        },
      ],
      as: "warmup.exercises",
    },
  },
  {
    // add arrays to populate later
    $addFields:
      // also add references to og docs, in case needed
      {
        overview: {
          supersetted: [],
          nonSupersetted: [],
        },
        workout: {
          supersetted: [],
          nonSupersetted: [],
        },
        references: {
          usedInPhase: {
            _id: "$phase",
          },
          warmup: {
            _id: "$primer",
          },
          ogWorkout: "$_id",
        },
      },
  },
  {
    // Fetch the Workout fields (and expand exercises)
    $lookup:
      // this is used to fill the non-supersetted version
      {
        from: "plans",
        localField: "_id",
        foreignField: "workout",
        pipeline: [
          {
            $lookup: {
              from: "exercises",
              localField: "exercise",
              foreignField: "_id",
              pipeline: [
                {
                  $project: {
                    _id: 0,
                    name: 1,
                    cues: 1,
                    videoUrl: 1,
                  },
                },
              ],
              as: "exercise",
            },
          },
          { $unwind: "$exercise" },
          {
            $lookup: {
              from: "programmings",
              localField: "weekOne",
              foreignField: "_id",
              pipeline: [
                {
                  $project: {
                    _id: 0,
                    sets: 1,
                    setRest: 1,
                    reps: 1,
                    repRest: 1,
                  },
                },
                {
                  $addFields: {
                    week: 1,
                  },
                },
              ],
              as: "weekOne",
            },
          },
          { $unwind: "$weekOne" },
          {
            $lookup: {
              from: "programmings",
              localField: "weekTwo",
              foreignField: "_id",
              pipeline: [
                {
                  $project: {
                    _id: 0,
                    sets: 1,
                    setRest: 1,
                    reps: 1,
                    repRest: 1,
                  },
                },
                {
                  $addFields: {
                    week: 2,
                  },
                },
              ],
              as: "weekTwo",
            },
          },
          { $unwind: "$weekTwo" },
          {
            $lookup: {
              from: "programmings",
              localField: "weekThree",
              foreignField: "_id",
              pipeline: [
                {
                  $project: {
                    _id: 0,
                    sets: 1,
                    setRest: 1,
                    reps: 1,
                    repRest: 1,
                  },
                },
                {
                  $addFields: {
                    week: 3,
                  },
                },
              ],
              as: "weekThree",
            },
          },
          { $unwind: "$weekThree" },
          {
            $lookup: {
              from: "programmings",
              localField: "weekFour",
              foreignField: "_id",
              pipeline: [
                {
                  $project: {
                    _id: 0,
                    sets: 1,
                    setRest: 1,
                    reps: 1,
                    repRest: 1,
                  },
                },
                {
                  $addFields: {
                    week: 4,
                  },
                },
              ],
              as: "weekFour",
            },
          },
          { $unwind: "$weekFour" },
          {
            $project: {
              _id: 0,
              code: 1,
              superset: { $substr: ["$code", 0, 1] },
              supersetIndex: { $substr: ["$code", 1, 1] },
              exercise: "$exercise",
              valuesThatVaryByWeek: [
                "$weekOne",
                "$weekTwo",
                "$weekThree",
                "$weekFour",
              ],
            },
          },
        ],
        as: "workout.nonSupersetted",
      },
  },
  {
    /**
     * newField: The new field name.
     * expression: The new field expression.
     */
    $addFields: {
      "workout.allWorkoutIndices": {
        $map: {
          input: "$workout.nonSupersetted",
          in: {
            $getField: {
              field: "code",
              input: "$$this",
            },
          },
        },
      },
    },
  },
  {
    // clone to workout supersetted
    $set: {
      "workout.supersetted": "$workout.nonSupersetted",
    },
  },
  {
    // add the warmup name to the references
    $lookup: {
      from: "primers",
      localField: "primer",
      foreignField: "_id",
      pipeline: [
        {
          $project: {
            _id: 0,
            name: 1,
          },
        },
      ],
      as: "references.warmup.name",
    },
  },
  {
    $unwind: {
      path: "$references.warmup.name",
    },
  },
  {
    $unset: [
      "_partition",
      "__v",
      "createdAt",
      "updateAt",
      "phase",
      "primer",
    ],
  },
  {
    // output to programData.workoutsTester
    $out: {
      db: "programData",
      coll: "workoutsTester",
    },
  },
]

Current output

The new workout document now looks like...

{
  "_id": {
    "$oid": "59ccd28338c8f273346b1997"
  },
  "name": "Strength 1",
  "warmup": {
    "name": "Lower Body Lifting",
    "show_reminder": true,
    "note": "",
    "exercises": [
      {
        "order": 1,
        "exercise": {
          "name": "Frog Squat",
          "videoUrl": "https://youtu.be/zZDq6OejYBM",
          "cues": "A great hamstring stretch and hip mobility focused exercise"
        },
        "repText": "5-8 reps"
      },
      {
        "order": 2,
        "exercise": {
          "name": "Frog Squat with Reach",
          "videoUrl": "https://youtu.be/Kem3YR2Fic4",
          "cues": "Different from the standard Frog Squat!\nMore of a full body movement challenge,\nLess stretch on the hamstrings & hip-hinge,\nMore challenging to thoracic spine mobility"
        },
        "repText": "5-8 reps"
      },
      {
        "order": 3,
        "exercise": {
          "name": "Five point Lunge",
          "videoUrl": "https://youtu.be/bBdSuretuHY",
          "cues": ""
        },
        "repText": "Three reps each leg"
      },
      {
        "order": 4,
        "exercise": {
          "name": "Three point SLDL",
          "videoUrl": "https://youtu.be/r1hPMviYbLQ",
          "cues": ""
        },
        "repText": "Three reps each leg"
      },
      {
        "order": 5,
        "exercise": {
          "name": "Backwards Spiderman",
          "videoUrl": "https://youtu.be/drHorMgQBWM",
          "cues": ""
        },
        "repText": "If you have time add this full-body mobility drill"
      },
      {
        "order": 6,
        "exercise": {
          "name": "Walking Bow and Arrow",
          "videoUrl": "https://youtu.be/7MeaaZ8pRNQ",
          "cues": ""
        },
        "repText": "If you have time add this full-body mobility drill"
      }
    ]
  },
  "overview": {
    "supersetted": [],
    "nonSupersetted": []
  },
  "workout": {
    "nonSupersetted": [
      {
        "code": "A1",
        "superset": "A",
        "supersetIndex": "1",
        "exercise": {
          "name": "DB Split Squat",
          "videoUrl": "https://youtu.be/KgPxYpvHUe8",
          "cues": "Keep your chest tall and shoulders back.\nAs you descend, shoulders and hips should stay in a line (don't lean forward).\nHips should go straight down and straight up.\nYou should have an approximately 90-degree angle for both knees.\nBack knee should come close, but not touch, the ground."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "A2",
        "superset": "A",
        "supersetIndex": "2",
        "exercise": {
          "name": "Cable Pull-Through",
          "videoUrl": "https://youtu.be/2lXOIeiWYk4",
          "cues": "Feet are slightly wider than shoulder width. Knees are bent about 10 degrees.\nReach back between your legs with the rope attachment.\nUse your glutes to push your hips forward and stand up."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "B1",
        "superset": "B",
        "supersetIndex": "1",
        "exercise": {
          "name": "Semi-supinated grip Pull-up",
          "videoUrl": "https://youtu.be/R-j7IvquHwE",
          "cues": "\"Semi supinated\" means that your palms are facing one another. If you do not have a bar that allows for this, use a supinated grip (palms toward you).\nKeep your chest up.\nSqueeze shoulder blades together at the top of the movement.\nIf you do not have an assisted chin-up machine, you can use a lat pulldown instead."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "4-6",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "4-6",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "C1",
        "superset": "C",
        "supersetIndex": "1",
        "exercise": {
          "name": "Stability Ball Hip Raise to Bridge",
          "videoUrl": "https://youtu.be/MEqwmz-nfVo",
          "cues": "Squeeze the glutes to get the hips off the floor.\nKeeping the glutes tight, bring the ball in toward you forming a 90 degree angle of the knees."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 2,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 2,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "C2",
        "superset": "C",
        "supersetIndex": "2",
        "exercise": {
          "name": "Bow and Arrow",
          "videoUrl": "https://youtu.be/Fq9Jlz261m4",
          "cues": "If you imagine an archer, you will naturally do this exercise correctly.\nStand up tall.\nKeep the elbow of the pulling arm up.\nSqueeze the shoulder blades together during the iso hold."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "10-12",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 2,
            "setRest": 30,
            "reps": "10-12",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 2,
            "setRest": 30,
            "reps": "10-12",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "B2",
        "superset": "B",
        "supersetIndex": "2",
        "exercise": {
          "name": "One-Arm Semi-sup' Grip Incline DB Bench",
          "videoUrl": "https://youtu.be/tkPqct_J338",
          "cues": "Hold a dumbbell only in one hand while performing this exercise.\nEngage the core to resist rotation."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 60,
            "reps": "8-10",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 3,
            "setRest": 60,
            "reps": "8-10",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 3,
            "setRest": 60,
            "reps": "6-8",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      }
    ],
    "allWorkoutIndices": [
      "A1",
      "A2",
      "B1",
      "C1",
      "C2",
      "B2"
    ],
    "supersetted": [
      {
        "code": "A1",
        "superset": "A",
        "supersetIndex": "1",
        "exercise": {
          "name": "DB Split Squat",
          "videoUrl": "https://youtu.be/KgPxYpvHUe8",
          "cues": "Keep your chest tall and shoulders back.\nAs you descend, shoulders and hips should stay in a line (don't lean forward).\nHips should go straight down and straight up.\nYou should have an approximately 90-degree angle for both knees.\nBack knee should come close, but not touch, the ground."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "A2",
        "superset": "A",
        "supersetIndex": "2",
        "exercise": {
          "name": "Cable Pull-Through",
          "videoUrl": "https://youtu.be/2lXOIeiWYk4",
          "cues": "Feet are slightly wider than shoulder width. Knees are bent about 10 degrees.\nReach back between your legs with the rope attachment.\nUse your glutes to push your hips forward and stand up."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "B1",
        "superset": "B",
        "supersetIndex": "1",
        "exercise": {
          "name": "Semi-supinated grip Pull-up",
          "videoUrl": "https://youtu.be/R-j7IvquHwE",
          "cues": "\"Semi supinated\" means that your palms are facing one another. If you do not have a bar that allows for this, use a supinated grip (palms toward you).\nKeep your chest up.\nSqueeze shoulder blades together at the top of the movement.\nIf you do not have an assisted chin-up machine, you can use a lat pulldown instead."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "4-6",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "4-6",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 3,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "C1",
        "superset": "C",
        "supersetIndex": "1",
        "exercise": {
          "name": "Stability Ball Hip Raise to Bridge",
          "videoUrl": "https://youtu.be/MEqwmz-nfVo",
          "cues": "Squeeze the glutes to get the hips off the floor.\nKeeping the glutes tight, bring the ball in toward you forming a 90 degree angle of the knees."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 2,
            "setRest": 30,
            "reps": "6-8",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 2,
            "setRest": 30,
            "reps": "8-10",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "C2",
        "superset": "C",
        "supersetIndex": "2",
        "exercise": {
          "name": "Bow and Arrow",
          "videoUrl": "https://youtu.be/Fq9Jlz261m4",
          "cues": "If you imagine an archer, you will naturally do this exercise correctly.\nStand up tall.\nKeep the elbow of the pulling arm up.\nSqueeze the shoulder blades together during the iso hold."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 30,
            "reps": "10-12",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 2,
            "setRest": 30,
            "reps": "10-12",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 2,
            "setRest": 30,
            "reps": "10-12",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      },
      {
        "code": "B2",
        "superset": "B",
        "supersetIndex": "2",
        "exercise": {
          "name": "One-Arm Semi-sup' Grip Incline DB Bench",
          "videoUrl": "https://youtu.be/tkPqct_J338",
          "cues": "Hold a dumbbell only in one hand while performing this exercise.\nEngage the core to resist rotation."
        },
        "valuesThatVaryByWeek": [
          {
            "sets": 2,
            "setRest": 60,
            "reps": "8-10",
            "repRest": null,
            "week": 1
          },
          {
            "sets": 3,
            "setRest": 60,
            "reps": "8-10",
            "repRest": null,
            "week": 2
          },
          {
            "sets": 3,
            "setRest": 60,
            "reps": "6-8",
            "repRest": null,
            "week": 3
          },
          {
            "sets": null,
            "setRest": null,
            "reps": "",
            "repRest": null,
            "week": 4
          }
        ]
      }
    ]
  },
  "references": {
    "usedInPhase": {
      "_id": {
        "$oid": "59ccd1a738c8f273346b1988"
      }
    },
    "warmup": {
      "_id": {
        "$oid": "5df7625ce69199d3fa3c4746"
      },
      "name": {
        "name": "Lower Body Lifting"
      }
    },
    "ogWorkout": {
      "$oid": "59ccd28338c8f273346b1997"
    }
  }
}

which is much closer, but still not quite there.

My current questions

The workout above, is, stripping out all the extra bumpf, basically this:

{
  ...,
  notSupersetted: [
    { superset: "a", supersetIndex: 1, <other data> },
    { superset: "c", supersetIndex: 1, ...},
    { superset: "a", supersetIndex: 2, ...},
    { superset: "c", supersetIndex: 2, ...},
    { superset: "b", supersetIndex: 2, ...},
    { superset: "b", supersetIndex: 1, ...}
  ],
  supersetted: []
  ...
}

I need to:

find a way to add an index-ordering to notSupersetted. e.g. although they are listed as [a-1, c-1, a-2, c-2, b-2, b-1 ] these exercises should actually be done in alpha-numeric order, ie [ a1, a2, b1, b2, c1, c2 ].  How do I generate a workout index for them?

populate the supersetted field, which is basically just a rearrangement of the non-supersetted field in this form...

{
  ...,
  notSupersetted: [ <as before> ],
  supersetted: [
    {
      superset: "A",
      elements: [
        { index: 1, <other data> },
        { index: 2, ... }
      ]
    },
    {
      superset: "B",
      elements: [
        { index: 1, ...},
        { index: 2, ... }
      ]
    },
    {
      superset: "C",
      elements: [
        { index: 1, ...},
        { index: 2, ...}
      ]
    },
  ],
  ...
}


来源: stackexchange

问:
Multiple authentication methods working as OR instead of AND in .NET Framework 4.8 Web API
I have a Web api in FW 4.8. I currently have it rigged with 2 authentication methods: Salesforce auth and Basic auth. Some of the controllers require Salesforce, some require basic auth, but so far they have worked independently.

As per a new requirement from the client, we need to keep those auth methods exactly as they are, but we need to add a new one: Okta authentication.

This is the code that I used to add it to the IAppBuilder, which will run at startup:

```<code>public static void AddAuthenticationConfiguration(this IAppBuilder app)
    {
        app.UseOktaWebApi(ApiAuthenticationScheme, new OktaWebApiOptions
        {
            OktaDomain = "https://some.domain.com",
            AuthorizationServerId = "default"
        });
    }
</code>```

So now if I add this to one of my controllers:

```<code>[Authorize]
    public class SomeController : ApiController
    {
      ...
    }
</code>```

...I'll be able to authenticate using the Okta token.

The problem, however, is that if I do this, my old authentication methods (Salesforce or basic auth) stop working altogether.

What I need to do is make it so Okta starts working in parallel with those auth methods.

So, for example, the controllers that once required only Salesforce Auth, will now require
either Okta OR Salesforce, and the ones that required Basic Auth, will also be accesible using Okta.

So, in summary, I wish to keep the auth methods that I already have in place, untouched, but make them coexist with Okta.

I know this is somewhat easy to do with .Net Core and up, since it has multiple authentication schemas, but sadly I cannot upgrade to Core at the moment.

Is there a way to add multiple authentication schemas to a web api controller in Framework 4.8, that behave as an OR rather than an AND (I think this is the case of chaining together multiple Authentication Filters), or is it not possible?

Some more context: here's how I set up both Okta and Salesforce in my Startup class:

```<code>var saleforceoption = new SalesforceAuthenticationOptions
        {
            ClientId = authSettings.SaleforceClientId,
            ClientSecret = authSettings.SaleforceClientSecret,
            AuthenticationType = "Salesforce",
            AuthenticationMode = AuthenticationMode.Active,
            Prompt = "login",
            Endpoints =
                new SalesforceAuthenticationOptions.SalesforceAuthenticationEndpoints
                {
                    AuthorizationEndpoint = $"https://{authSettings.SalesforceCompanyDomain}/services/oauth2/authorize",
                    TokenEndpoint = $"https://{authSettings.SalesforceCompanyDomain}/services/oauth2/token"
                }
        };
        app.UseSalesforceAuthentication(saleforceoption);

        app.AddAuthenticationConfiguration();
</code>```

As per the controller that uses Basic auth, I registered it with a IAutofacAuthorizationFilter.

ContentLicense: CC BY-SA 4.0

Body:
I have a Web api in FW 4.8. I currently have it rigged with 2 authentication methods: Salesforce auth and Basic auth. Some of the controllers require Salesforce, some require basic auth, but so far they have worked independently.

As per a new requirement from the client, we need to keep those auth methods exactly as they are, but we need to add a new one: Okta authentication.

This is the code that I used to add it to the IAppBuilder, which will run at startup:

public static void AddAuthenticationConfiguration(this IAppBuilder app)
    {
        app.UseOktaWebApi(ApiAuthenticationScheme, new OktaWebApiOptions
        {
            OktaDomain = "https://some.domain.com",
            AuthorizationServerId = "default"
        });
    }

So now if I add this to one of my controllers:

[Authorize]
    public class SomeController : ApiController
    {
      ...
    }

...I'll be able to authenticate using the Okta token.

The problem, however, is that if I do this, my old authentication methods (Salesforce or basic auth) stop working altogether.

What I need to do is make it so Okta starts working in parallel with those auth methods.

So, for example, the controllers that once required only Salesforce Auth, will now require
either Okta OR Salesforce, and the ones that required Basic Auth, will also be accesible using Okta.

So, in summary, I wish to keep the auth methods that I already have in place, untouched, but make them coexist with Okta.

I know this is somewhat easy to do with .Net Core and up, since it has multiple authentication schemas, but sadly I cannot upgrade to Core at the moment.

Is there a way to add multiple authentication schemas to a web api controller in Framework 4.8, that behave as an OR rather than an AND (I think this is the case of chaining together multiple Authentication Filters), or is it not possible?

Some more context: here's how I set up both Okta and Salesforce in my Startup class:

var saleforceoption = new SalesforceAuthenticationOptions
        {
            ClientId = authSettings.SaleforceClientId,
            ClientSecret = authSettings.SaleforceClientSecret,
            AuthenticationType = "Salesforce",
            AuthenticationMode = AuthenticationMode.Active,
            Prompt = "login",
            Endpoints =
                new SalesforceAuthenticationOptions.SalesforceAuthenticationEndpoints
                {
                    AuthorizationEndpoint = $"https://{authSettings.SalesforceCompanyDomain}/services/oauth2/authorize",
                    TokenEndpoint = $"https://{authSettings.SalesforceCompanyDomain}/services/oauth2/token"
                }
        };
        app.UseSalesforceAuthentication(saleforceoption);

        app.AddAuthenticationConfiguration();

As per the controller that uses Basic auth, I registered it with a IAutofacAuthorizationFilter.


问:
Selenium not working with Vite, possibly due to HMR
I am trying to use Selenium with a Django backend using Vite for JS stuff but for some reason the JS stuff isn't running when, for example, I tell Selenium to click a button. I think it has to do with Vite's HMR, because when I build the JS and link the bundled file in my Django templates it works fine. How can I get Selenium to work properly without having to use the bundled file?</p>


问:
PyBullet garbage console output how to run pybullet without that
When running PyBullet the console gets converted to a PyBullet one printing debugging info like these one:

```<code>numActiveThreads = 0
stopping threads
destroy semaphore
Thread with taskId 0 exiting
Thread TERMINATED
semaphore destroyed
destroy main semaphore
main semaphore destroyed
finished
numActiveThreads = 0
btShutDownExampleBrowser stopping threads
Thread with taskId 0 exiting
Thread TERMINATED
</code>```

and also constantly printing

```<code>argv[0]=
argv[0]=
argv[0]=
argv[0]=
argv[0]=
</code>```

Is there a way to tell PyBullet not to do that and act as a normal Python library that does not hijack your console?

Body:
When running PyBullet the console gets converted to a PyBullet one printing debugging info like these one:

numActiveThreads = 0
stopping threads
destroy semaphore
Thread with taskId 0 exiting
Thread TERMINATED
semaphore destroyed
destroy main semaphore
main semaphore destroyed
finished
numActiveThreads = 0
btShutDownExampleBrowser stopping threads
Thread with taskId 0 exiting
Thread TERMINATED

and also constantly printing

argv[0]=
argv[0]=
argv[0]=
argv[0]=
argv[0]=

Is there a way to tell PyBullet not to do that and act as a normal Python library that does not hijack your console?


问:
Node JS based service on ECS fills 6.8GB disk space on error
I am using puppeteer in node project. In some specific scenery puppeteer page error occurs.
When that error occurs, ECS disk space get filled(6.8GB). For a few such kind of error ECS service stops due to no space left on device.

I am cleaning everything thing that i store in the file system.

This whole disk space jump occurs whithin 1minitue.

Some investigation shows that storage jump occurred inside my app folder.

I have another ECS service running same app, if the same thing happens on the other service, that doesn't fills disk space.

I have tried deploying same image to both services for one service disk space get filled for the other service this doesn't happen.

I am really stuck here, any kind of help will be much appreciated.

Thanks in advance.

I have tried to replicate that same error in my local docker, when error occurs storage doesn't get filled.


问:
Complex? Dynamic SQL pivot table in c# with no aggregation
Bit of a rookie with c# and SQl but have come across a potentially tricky pivot table query that i'm unable to solve.

I have a database that looks like this:

Number
Revision
Status
Date

J1234-S-CA-0001
00
S9
01/01/2022

H5678-C-TN-0005
A2
S0
05/09/2022

X5274-X-SC-0012
05
S4
06/07/2022

J1234-S-CA-0001
01
S4
06/09/2022

Which essentially tracks the issuing of documents - the document numbers, it's revision, status and the date it was issued.

The number, revision and status columns are of type NVARCHAR and need to remain as such as they're a mixture of text and numbers. I'd like to transform the database to produce the following result. A log of which revisions of the documents were issued on which days. Note the column headers will need to be set dynamically as the data source will be large and varying.

Number
01/01/2022
06/07/2022
05/09/2022
06/09/2022

J1234-S-CA-0001
00

01

H5678-C-TN-0005

A2

X5274-X-SC-0012

01

If possible, i'd also like to add two additional columns that show the revision and status of the most recent issue date, but I can live without this if it's too tricky/not possible.

Number
Last Revision
Last Revision Status
01/01/2022
06/07/2022
05/09/2022
06/09/2022

J1234-S-CA-0001
01
S4
00

01

H5678-C-TN-0005
A2
S0

A2

X5274-X-SC-0012
01
S4

01

So far I have tried the below, without much success - any help would be greatly appreciated!

```<code>DROP TABLE tbl_1

SELECT Number, Revision, Status INTO tbl_1 FROM documents

DECLARE @SqlQuery AS NVARCHAR(MAX)
DECLARE @PivotColumns AS NVARCHAR(Max)

SELECT @PivotColumns = (SELECT DISTINCT [Date]) FROM documents

SET @SqlQuery = N'SELECT [Number], [Revision], [Status]' + @PivotColumns + '
                INTO TEMP
                FROM tbl_1
                PIVOT(MAX([Revision])
                FOR
                [Date] IN (' + @PivotColumns + ')) AS Q'

EXEC sp_executesql @SqlQuery

SELECT * FROM TEMP
</code>```

Body:
Bit of a rookie with c# and SQl but have come across a potentially tricky pivot table query that i'm unable to solve.

I have a database that looks like this:

Number
Revision
Status
Date

J1234-S-CA-0001
00
S9
01/01/2022

H5678-C-TN-0005
A2
S0
05/09/2022

X5274-X-SC-0012
05
S4
06/07/2022

J1234-S-CA-0001
01
S4
06/09/2022

Which essentially tracks the issuing of documents - the document numbers, it's revision, status and the date it was issued.

The number, revision and status columns are of type NVARCHAR and need to remain as such as they're a mixture of text and numbers. I'd like to transform the database to produce the following result. A log of which revisions of the documents were issued on which days. Note the column headers will need to be set dynamically as the data source will be large and varying.

Number
01/01/2022
06/07/2022
05/09/2022
06/09/2022

J1234-S-CA-0001
00

01

H5678-C-TN-0005

A2

X5274-X-SC-0012

01

If possible, i'd also like to add two additional columns that show the revision and status of the most recent issue date, but I can live without this if it's too tricky/not possible.

Number
Last Revision
Last Revision Status
01/01/2022
06/07/2022
05/09/2022
06/09/2022

J1234-S-CA-0001
01
S4
00

01

H5678-C-TN-0005
A2
S0

A2

X5274-X-SC-0012
01
S4

01

So far I have tried the below, without much success - any help would be greatly appreciated!

DROP TABLE tbl_1

SELECT Number, Revision, Status INTO tbl_1 FROM documents

DECLARE @SqlQuery AS NVARCHAR(MAX)
DECLARE @PivotColumns AS NVARCHAR(Max)

SELECT @PivotColumns = (SELECT DISTINCT [Date]) FROM documents

SET @SqlQuery = N'SELECT [Number], [Revision], [Status]' + @PivotColumns + '
                INTO TEMP
                FROM tbl_1
                PIVOT(MAX([Revision])
                FOR
                [Date] IN (' + @PivotColumns + ')) AS Q'

EXEC sp_executesql @SqlQuery

SELECT * FROM TEMP


问:
gzip decoding error when using Python requests but not curl
I'm making a POST request of some JSON to an endpoint (Vertex AI Endpoint) and the request works when I make it via curl:

curl \
-X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
$API_URL \
-d "@input.json"
```
<p>but if I try the same in Python:</p>
<pre class="lang-py prettyprint-override"><code>with open("input.json") as f:
    input_dict = json.load(f)

response = requests.post(
    url,
    json=input_dict,
    headers={
        "Content-Type": "application/json",
        "Authorization": f"Bearer {token}"
    }
)
</code>```

I get the following exception:

requests.exceptions.ContentDecodingError: ('Received response with content-encoding: gzip, but failed to decode it.', error('Error -3 while decompressing data: incorrect header check'))
```
<p>I inspected the headers to see the difference between the curl request and the python one and I see in Python, the header <code>Accept-Encoding: gzip, deflate</code> is added to the request. Is this causing a problem and if so, is there a way I can modify it?</p>
<p>Also, if I modify the request to decode the raw response, I can use it correctly:</p>
<pre class="lang-py prettyprint-override"><code>response = requests.post(
    url,
    json=input_dict,
    headers={
        "Content-Type": "application/json",
        "Authorization": f"Bearer {token}"
    },
    stream=True
)

parsed_response = json.loads(response.raw.read().decode('utf-8'))
</code>```

but I'm still trying to understand why the first option doesn't work and where the issues lies.

Body:
I'm making a POST request of some JSON to an endpoint (Vertex AI Endpoint) and the request works when I make it via curl:

curl \
-X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
$API_URL \
-d "@input.json"

but if I try the same in Python:

with open("input.json") as f:
    input_dict = json.load(f)

response = requests.post(
    url,
    json=input_dict,
    headers={
        "Content-Type": "application/json",
        "Authorization": f"Bearer {token}"
    }
)

I get the following exception:

requests.exceptions.ContentDecodingError: ('Received response with content-encoding: gzip, but failed to decode it.', error('Error -3 while decompressing data: incorrect header check'))

I inspected the headers to see the difference between the curl request and the python one and I see in Python, the header Accept-Encoding: gzip, deflate is added to the request. Is this causing a problem and if so, is there a way I can modify it?

Also, if I modify the request to decode the raw response, I can use it correctly:

response = requests.post(
    url,
    json=input_dict,
    headers={
        "Content-Type": "application/json",
        "Authorization": f"Bearer {token}"
    },
    stream=True
)

parsed_response = json.loads(response.raw.read().decode('utf-8'))

but I'm still trying to understand why the first option doesn't work and where the issues lies.


问:
Can't bind 2 child collections in the same OData Post
I am experiencing a very weird behavior in dataverse. I can bind 1 child collection at a time but not 2 at once.

HTTP Method: Post

URL: https://mywebsite.crm4.dynamics.com/api/data/v9.2/schools

When I send the following body:

```<code>{
    "school_student@odata.bind": [
        "students(b547470e-5704-ed11-82e5-000d3abcf1a1),
        "students(b547470e-5704-ed11-82e5-000d3abcf1a2)
     ]
}
</code>```

The creation of the links between the school and its students is correctly created.

If I do the same between the schools and teachers, it also works.

However, if I try to do the 2 at once, only the first one is set:

```<code>{
    "school_student@odata.bind": [
        "students(b547470e-5704-ed11-82e5-000d3abcf1a3),
        "students(b547470e-5704-ed11-82e5-000d3abcf1a4)
     ],
    "school_teacher@odata.bind": [
        "teachers(b547470e-5704-ed11-82e5-000d3abcf1a5),
        "teachers(b547470e-5704-ed11-82e5-000d3abcf1a6)
     ]
}
</code>```

In the past 2 years I found many limitations in dataverse, but I couldn't find this one anywhere. Is it impossible to bind 2 child collections in the same Post?

Body:
I am experiencing a very weird behavior in dataverse. I can bind 1 child collection at a time but not 2 at once.

HTTP Method: Post

URL: https://mywebsite.crm4.dynamics.com/api/data/v9.2/schools

When I send the following body:

{
    "school_student@odata.bind": [
        "students(b547470e-5704-ed11-82e5-000d3abcf1a1),
        "students(b547470e-5704-ed11-82e5-000d3abcf1a2)
     ]
}

The creation of the links between the school and its students is correctly created.

If I do the same between the schools and teachers, it also works.

However, if I try to do the 2 at once, only the first one is set:

{
    "school_student@odata.bind": [
        "students(b547470e-5704-ed11-82e5-000d3abcf1a3),
        "students(b547470e-5704-ed11-82e5-000d3abcf1a4)
     ],
    "school_teacher@odata.bind": [
        "teachers(b547470e-5704-ed11-82e5-000d3abcf1a5),
        "teachers(b547470e-5704-ed11-82e5-000d3abcf1a6)
     ]
}

In the past 2 years I found many limitations in dataverse, but I couldn't find this one anywhere. Is it impossible to bind 2 child collections in the same Post?


问:
Exception: The flutter tool cannot access the file or directory
My friend send me her flutter code, and she uses Windows. However, when I unzip it on my Mac and try to run it, I get this error:

```<code>Exception: The flutter tool cannot access the file or directory.
Please ensure that the SDK and/or project is installed in a location that has read/write permissions for the current user.
</code>```

Even though I can run my Flutter project without any errors -- how could I fix this?

I tried to run the following command but it did not work:

```<code>sudo xattr -c -r  <project_folder>
</code>```

Body:
My friend send me her flutter code, and she uses Windows. However, when I unzip it on my Mac and try to run it, I get this error:

Exception: The flutter tool cannot access the file or directory.
Please ensure that the SDK and/or project is installed in a location that has read/write permissions for the current user.

Even though I can run my Flutter project without any errors -- how could I fix this?

I tried to run the following command but it did not work:

sudo xattr -c -r  <project_folder>


问:
FFmpeg segmentation and transcoding missing frames
I code videos for hobbies and have a decent understanding of ffmpeg and mkvmerge. I prefer to encode video when my computer is on for other things as well, so I recently looked for a way that I could resume encoding after the computer was turned off.

I tried a virtual machine, saving the whole state and it seems to work very well, but the performance is very slow and with the same settings the encoding time is much longer than normal.

I then tried to divide the starting video into several segments, so as to resume from the appropriate segment after restarting the computer.

I tried to do this with ffmpeg:

```<code>ffmpeg -i input -map 0:v:0 -c copy -f segment -segment_time 300 -reset_timestamps 1 segment%03d.mkv
</code>```

But also with the mkvtoolnix gui.

Both operations provide an excellent result.Trying to merge the segments into one video, with ffconcat or mkvtoolnix the result is perfect.

The problem arises when segments are encoded. I use a simple script based on slow preset for every segment in loop (I use both windows and linux):

```<code>ffmpeg -i input.mkv -threads 0 -map 0 -c:a copy -c:s copy -preset slow -pix_fmt yuv420p10le -c:v libx265 -x265-params crf=18:bframes=8:aq-mode=2:aq-strength=1.0 output.mkv
</code>```

Putting them together in the same way, the video also looks quite good, and with the naked eye you don't notice the passage of the various segments, but analyzing them with ffmpeg I notice that the individual segments have slightly shorter durations and a different number of frames, even 2 or 3 less. When putting together very long videos, you notice even 2 seconds of difference with the original, which also causes the audio and subtitles to go into desynch.

I know the problem has to do with keyframes, timestamps and stuff like that. But I don't understand why. FFmpeg, as well as mkvmerge should split the video exactly where the keyframes are, about 300 seconds apart, so as not to mess up the video structure and allow for good encoding and reassembling.

The problem is just encoding with ffmpeg that removes some frames from the original segments. Sometimes I noticed during the encoding of some segments the following error code, or maybe warning, because the encoding worked anyway:

```<code>[hevc @ 0x55758bf92dc0] First slice in a frame missing.
    Last message repeated 6 times
[hevc @ 0x55758c2000c0] First slice in a frame missing.
</code>```

I've read every discussion about it on the net, I've tried to segment both with mp4 and mkv format, with and without audio, but the problem remains. Where am I doing wrong?

Body:
I code videos for hobbies and have a decent understanding of ffmpeg and mkvmerge. I prefer to encode video when my computer is on for other things as well, so I recently looked for a way that I could resume encoding after the computer was turned off.

I tried a virtual machine, saving the whole state and it seems to work very well, but the performance is very slow and with the same settings the encoding time is much longer than normal.

I then tried to divide the starting video into several segments, so as to resume from the appropriate segment after restarting the computer.

I tried to do this with ffmpeg:

ffmpeg -i input -map 0:v:0 -c copy -f segment -segment_time 300 -reset_timestamps 1 segment%03d.mkv

But also with the mkvtoolnix gui.

Both operations provide an excellent result.Trying to merge the segments into one video, with ffconcat or mkvtoolnix the result is perfect.

The problem arises when segments are encoded. I use a simple script based on slow preset for every segment in loop (I use both windows and linux):

ffmpeg -i input.mkv -threads 0 -map 0 -c:a copy -c:s copy -preset slow -pix_fmt yuv420p10le -c:v libx265 -x265-params crf=18:bframes=8:aq-mode=2:aq-strength=1.0 output.mkv

Putting them together in the same way, the video also looks quite good, and with the naked eye you don't notice the passage of the various segments, but analyzing them with ffmpeg I notice that the individual segments have slightly shorter durations and a different number of frames, even 2 or 3 less. When putting together very long videos, you notice even 2 seconds of difference with the original, which also causes the audio and subtitles to go into desynch.

I know the problem has to do with keyframes, timestamps and stuff like that. But I don't understand why. FFmpeg, as well as mkvmerge should split the video exactly where the keyframes are, about 300 seconds apart, so as not to mess up the video structure and allow for good encoding and reassembling.

The problem is just encoding with ffmpeg that removes some frames from the original segments. Sometimes I noticed during the encoding of some segments the following error code, or maybe warning, because the encoding worked anyway:

[hevc @ 0x55758bf92dc0] First slice in a frame missing.
    Last message repeated 6 times
[hevc @ 0x55758c2000c0] First slice in a frame missing.

I've read every discussion about it on the net, I've tried to segment both with mp4 and mkv format, with and without audio, but the problem remains. Where am I doing wrong?


问:
location of source code of django.contrib.admin module
I want to figure out how the value for Django's admin.site.urls is generated. Where can I find the source code for  django.contrib.admin module?</p>
```<code>$ find . -name "admin.py"
./opt/rh/rh-python36/root/usr/lib/python3.6/site-packages/rest_framework/authtoken/admin.py
./opt/rh/rh-python36/root/usr/lib/python3.6/site-packages/django/contrib/sites/admin.py
./opt/rh/rh-python36/root/usr/lib/python3.6/site-packages/django/contrib/redirects/admin.py
./opt/rh/rh-python36/root/usr/lib/python3.6/site-packages/django/contrib/auth/admin.py
./opt/rh/rh-python36/root/usr/lib/python3.6/site-packages/django/contrib/flatpages/admin.py
./opt/rh/rh-python36/root/usr/lib/python3.6/site-packages/django/contrib/contenttypes/admin.py
</code>```

Body:
I want to figure out how the value for Django's admin.site.urls is generated. Where can I find the source code for  django.contrib.admin module?

$ find . -name "admin.py"
./opt/rh/rh-python36/root/usr/lib/python3.6/site-packages/rest_framework/authtoken/admin.py
./opt/rh/rh-python36/root/usr/lib/python3.6/site-packages/django/contrib/sites/admin.py
./opt/rh/rh-python36/root/usr/lib/python3.6/site-packages/django/contrib/redirects/admin.py
./opt/rh/rh-python36/root/usr/lib/python3.6/site-packages/django/contrib/auth/admin.py
./opt/rh/rh-python36/root/usr/lib/python3.6/site-packages/django/contrib/flatpages/admin.py
./opt/rh/rh-python36/root/usr/lib/python3.6/site-packages/django/contrib/contenttypes/admin.py


问:
Global Rank based on Visual and Page Filters but should not affected by slicer selection
I have a major headache now.
My client wants Global Ranking and it should not be changed if he make any slicer selection. Below are the issues which I'm facing

I used ALL Function - Got Static Ranking but the problem is my table data is a filtered data based on visual and page filters. But this filters are omitted by All Function and it ranks all the data

I used ALLSELECTED Function - It Ranks based on my filtered data but the Ranking is not static and it is dynamic

My issue is My Rank should be based on my filtered data in my data table and also it should be static and should not be affected by slicer.

Below is my code to generate Rank. This produces Dynamic Ranking but I want static Ranking. kindly dont suggest ALL function as I mentioned i need to Rank based on filtered data in my report.

```<code>Rank =
Var summry=
SUMMARIZE(**ALLSELECTED**('Employee'),
        'Employee'[Employee Name],
                "TotalScore",[Total Score],
                "WinRate",[Win Rate],
                "CustomerCount",[Customer Count])
var tmp=                       ------- Here I'm doing Tie Breaker based on Win Rate & CustomerCount
ADDCOLUMNS(summry,"RNK",
RANKX(summry,
    RANKX(summry,
        RANKX (summry, [TotalScore])
            + DIVIDE(
                RANKX(summry, [WinRate],,ASC),
                (COUNTROWS(summry) + 1)
            )
    , , DESC) +
    + DIVIDE(
            RANKX(summry,[CustomerCount],,ASC),
            (COUNTROWS(summry) + 1)
            )
    , , ASC)
)
var rnk = MAXX(FILTER(tmp,'Employee'[Employee Name]=SELECTEDVALUE('Employee'[Employee Name])),[RNK])
return rnk
</code>```

enter image description here

In the image, you can see it missing many ranks if I use ALL function as it Ranking all data and not filtered data.

Please provide a solution for this

Body:
I have a major headache now.
My client wants Global Ranking and it should not be changed if he make any slicer selection. Below are the issues which I'm facing

I used ALL Function - Got Static Ranking but the problem is my table data is a filtered data based on visual and page filters. But this filters are omitted by All Function and it ranks all the data

I used ALLSELECTED Function - It Ranks based on my filtered data but the Ranking is not static and it is dynamic

My issue is My Rank should be based on my filtered data in my data table and also it should be static and should not be affected by slicer.

Below is my code to generate Rank. This produces Dynamic Ranking but I want static Ranking. kindly dont suggest ALL function as I mentioned i need to Rank based on filtered data in my report.

Rank =
Var summry=
SUMMARIZE(**ALLSELECTED**('Employee'),
        'Employee'[Employee Name],
                "TotalScore",[Total Score],
                "WinRate",[Win Rate],
                "CustomerCount",[Customer Count])
var tmp=                       ------- Here I'm doing Tie Breaker based on Win Rate & CustomerCount
ADDCOLUMNS(summry,"RNK",
RANKX(summry,
    RANKX(summry,
        RANKX (summry, [TotalScore])
            + DIVIDE(
                RANKX(summry, [WinRate],,ASC),
                (COUNTROWS(summry) + 1)
            )
    , , DESC) +
    + DIVIDE(
            RANKX(summry,[CustomerCount],,ASC),
            (COUNTROWS(summry) + 1)
            )
    , , ASC)
)
var rnk = MAXX(FILTER(tmp,'Employee'[Employee Name]=SELECTEDVALUE('Employee'[Employee Name])),[RNK])
return rnk

enter image description here

In the image, you can see it missing many ranks if I use ALL function as it Ranking all data and not filtered data.

Please provide a solution for this


问:
NestJs Webpack skips Lambda.ts when doing a build
I can't get the lambda.ts file to be included in the bundled webpack compilation.

Create a standard NestJs application --- > nest new app

Test the application --- > npm run start

Manually add a new file lambda.ts to the src/ directory right next to main.ts

Test the application again --- > npm run start

Build the application --- > nest build --webpack

The bundled main.js in the dist/ directory will not include the lambda.ts code

What am I doing wrong???

I expect that the problem is around manually adding the file but can't figure out the correct way to add the file to a nest application so that it is included when webpack runs