0

Through an aggregation pipeline, I get a list of objects, with a conditional checkin list:

/* 1 */
{
    "_id" : ObjectId("600ebcb7f1128cd4517f2336"),
    "deskId" : "deskA",
    "checkin" : []
}

/* 2 */
{
    "_id" : ObjectId("600ebcb7f1128cd4517f2338"),
    "deskId" : "deskB",
    "checkin" : [ 
        {
            "_id" : ObjectId("602a7a4483e6fe1a7f5fe909"),
            "date" : ISODate("2021-02-15T13:42:28.712Z"),
            "phone" : "nico",
        }
    ]
}

Which I want to turn into

/* 1 */
{
    "_id" : ObjectId("600ebcb7f1128cd4517f2336"),
    "deskId" : "deskA",
    "phone" : ""
}

/* 2 */
{
    "_id" : ObjectId("600ebcb7f1128cd4517f2338"),
    "deskId" : "deskB",
    "phone" : "nico"
}

As in:

  • empty string when the array is empty
  • phone field when checkin.phone is present
  • At this stage of the pipeline, the checkin field of type array has zero or one element

I tried $unwind, but because the checkin field can be a list with zero element, top element are being skipped.

1
  • 1
    You can try using the preserveNullAndEmptyArrays option for $unwind. Commented Feb 15, 2021 at 14:21

1 Answer 1

1

If you are sure that checkin array will always contain only zero/one value then below solution works (no need of $unwind operator):

db.users.aggregate([
    {
        $addFields: {
            "phone": {
                $ifNull: [{ $arrayElemAt: ["$checkin.phone", 0] }, ""]
            }
        }
    }
])

Output:

[
  {
    "_id": ObjectId("600ebcb7f1128cd4517f2336"),
    "deskId": "deskA",
    "phone": "",
    "checkin": []
  },
  {
    "_id": ObjectId("600ebcb7f1128cd4517f2338"),
    "deskId": "deskB",
    "phone": "nico",
    "checkin": [
      {
        "_id": ObjectId("602a7a4483e6fe1a7f5fe909"),
        "date": ISODate("2021-02-15T19:12:28.712+05:30"),
        "phone": "nico"
      }
    ]
  }
]

otherwise use below query:

db.users.aggregate([
    {
        $unwind: {
            path: "$checkin",
            preserveNullAndEmptyArrays: true
        }
    },
    {
        $group: {
            _id: "$_id",
            deskId: { $first: "$deskId" },
            phone: { $push: "$checkin.phone" }
        }
    }
])

Output:

[
  {
    "_id": ObjectId("600ebcb7f1128cd4517f2336"),
    "deskId": "deskA",
    "phone": []
  },
  {
    "_id": ObjectId("600ebcb7f1128cd4517f2338"),
    "deskId": "deskB",
    "phone": [
      "nico",
      "pico"
    ]
  }
]
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.