1

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.

1 Answer 1

3

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.