Search code examples
arraysmongodbsortingmongooseaggregation

How to sort documents from mongodb by arrays of strings


For Example, I have a collection of documents called Dialogs. Format:

Dialogs{
  {
    _id: ObjectId(),
    members: [
      "admin",
      "all"
    ]
  },
  {
    _id: ObjectId(),
    members: [
      "user_637b2ed34ce3130e8532c4b9",
      "admin"
    ]
  },
  {
    _id: ObjectId(),
    members: [
      "group_637c708927f9df62ca646623",
      "admin"
    ]
  },
  {
    _id: ObjectId(),
    members: [
      "admin",
      "group_63a70e959fm566d28skkfi5b2",
      "user_427b2ed34ce4h50e8532c92h"
    ]
  },
}

I need to return sorted documents in this order: first documents containing only all, then documents containing all and some group, then just with a group, then group and users, then just users (each array has an admin string).

I tried to use aggregation, but nothing happened


Solution

  • One option is to add a field using $switch:

    db.collection.aggregate([
      {$addFields: {memberTypes: {$map: {
              input: "$members",
              in: {$first: {$split: ["$$this", "_"]}}
      }}}},
      {$addFields: {
          order: {$switch: {
              branches: [
                {
                  case: {$eq: [{$size: {$setUnion: ["$members", ["admin", "all"]]}}, 2]},
                  then: 1
                },
                {
                  case: {$in: ["all", "$members"]},
                  then: 2
                },
                {
                  case: {$and: [
                          {$in: ["group", "$memberTypes"]},
                          {$not: {$in: ["user", "$memberTypes"]}}
                  ]},
                  then: 3
                },
                {
                  case: {$in: ["group", "$memberTypes"]}]},
                  then: 4
                }
              ],
              default: 5
            }
          }
        }
      },
      {$sort: {order: 1}},
      {$unset: ["memberTypes", "order"]}
    ])
    

    See how it works on the playground example