Home > front end >  Mongodb array projection
Mongodb array projection

Time:10-27

I have a set of documents in a mongo collection that have a schema like so:

{
   "itemIds":{
      "12341234-1234-1234-1234-123412341234": true,
      "23452345-2345-2354-2345-234523452354": false,
      "34563456-3456-3456-3456-345634563456": true
   }
}

Because of our move to azure cognitive search, I need to use a mongo projection to get the data to look like this:

{
   "itemIds": ["12341234-1234-1234-1234-123412341234",
               "34563456-3456-3456-3456-345634563456"]
}

The properties with a false value should be excluded, and the properties with a true value should be converted to array values.

CodePudding user response:


Option 1. Maybe something like this:

db.collection.aggregate([
{
"$addFields": {
  "itemIds": {
    "$filter": {
      "input": {
        "$objectToArray": "$itemIds"
      },
      "as": "item",
      "cond": {
        $eq: [
          "$$item.v",
          true
        ]
      }
    }
  }
  }
 },
 {
  $project: {
    _id: "$_id",
    itemIds: "$itemIds.k"
  }
 }
])

Explained:

  1. In the addFileds stage convert the object to array to get the key /values in the form k,v so you can filter only the true values.
  2. In the project stage project the _id and itemIds.k values inside the itemIds array

Playground1


Option 2. Faster option via single stage: addFields/$map/$filter:

db.collection.aggregate([
{
"$addFields": {
  "itemIds": {
    "$map": {
      "input": {
        "$filter": {
          "input": {
            "$objectToArray": "$itemIds"
          },
          "as": "item",
          "cond": {
            $eq: [
              "$$item.v",
              true
            ]
          }
        }
      },
      "as": "it",
      "in": "$$it.k"
    }
   }
  }
 }
])

Explained:

Map the filtered values from ObjectToArray to project in addFields only the necessary array values.

Playground2

  • Related