jjj
jjj

Reputation: 2672

MongoDB sorting the output alphabetically (after grouping)

I have the following data:

[
  {
    "names": [
      "name1,name2,name3"
    ]
  },
  {
    "names": [
      "name1 , name2 , name3 , name4 , name5 , name6"
    ]
  }
]

Which I reduce to a set of unique values by removing whitespace and splitting by commas, using the following query:

db.collection.aggregate([
  {
    $project: {
      names: {
        $reduce: {
          input: "$names",
          initialValue: [],
          in: {
            $setUnion: [
              {
                $split: [
                  "$$this",
                  ","
                ],
                
              },
              "$$value"
            ]
          }
        }
      }
    }
  },
  {
    $unwind: "$names"
  },
  {
    $group: {
      _id: "$a",
      names: {
        $addToSet: {
          $trim: {
            input: "$names",
            chars: " "
          }
        }
      }
    }
  }
])

Everything works as you can see here: https://mongoplayground.net/p/nlK5Gmf-gkw The list of unique values produces, however, I need to sort the results alphabetically and the sorting mechanism added like this:

{
    $sort: {
      "a": -1
    }
}

, doesn't seem to work.

The result I get is unsorted:

[
  {
    "_id": null,
    "names": [
      "name1",
      "name5",
      "name4",
      "name6",
      "name3",
      "name2"
    ]
  }
]

Any suggestions?

https://mongoplayground.net/p/nlK5Gmf-gkw

Upvotes: 1

Views: 516

Answers (1)

turivishal
turivishal

Reputation: 36114

You just need change the order of stage and operations,

  • $group by null and use the same process that you used $reduce to split string to array and $map to remove white space from names using $trim
  • $project to update get unique array from all names using $reduce and $setUnion
  • $unwind deconstruct names array
  • $sort by names descending order
  • $group by null and make array of names
db.collection.aggregate([
  {
    $group: {
      _id: null,
      names: {
        $push: {
          $map: {
            input: {
              $reduce: {
                input: "$names",
                initialValue: [],
                in: { $split: ["$$this", ","] }
              }
            },
            in: { $trim: { input: "$$this" } }
          }
        }
      }
    }
  },
  {
    $project: {
      names: {
        $reduce: {
          input: "$names",
          initialValue: [],
          in: { $setUnion: ["$$this", "$$value"] }
        }
      }
    }
  },
  { $unwind: "$names" },
  { $sort: { names: -1 } },
  {
    $group: {
      _id: null,
      names: { $push: "$names" }
    }
  }
])

Playground

Upvotes: 1

Related Questions