0

The data in my database is as follows:

/* 1 */
{
      "name": "Severus",
      "u_name": "severussnape",
      "info": [
        {
          "value": "Severus",
          "source": "1",
          "infotag": "name"
        },
        {
          "value": "severussnape",
          "source": "2",
          "infotag": "name"
        }
      ]
}

/* 2 */
{
      "name": "Harry",
      "u_name": null,
      "info": [
        {
        "value": "Harry",
          "source": "1",
          "infotag": "name"
        }
      ]
}

I'd like to project the data so that the name field and the info array in the result are changed based on whether or not the u_name field is null. The result I expect looks like so:

/* 1 */
{
      "name": "severussnape",
      "info": [
        {
          "value": "severussnape",
          "source": "2",
          "infotag": "name"
        }
      ]
}

/* 2 */
{
      "name": "Harry",      
      "info": [
        {
          "value": "Harry",
          "source": "1",
          "infotag": "name"
        }
      ]
}

I've managed to project the name field correctly using the projection:

db.database.aggregate([{
    $project:{
        "name":{$cond:[{$eq:["$u_name",null]},"$name","$u_name"]}
    }
}])

But I've been unable to figure out how to remove the array element from info with value "Severus" in the first document depending on u_name. Is this possible?

2
  • 1
    You can get your desired results with the help of $unwind but I am still not clear how exactly you want to remove sub doc with the name "Severus". Commented Mar 13, 2019 at 6:30
  • @Jitendra sorry I wasn't clear. The array element with name "Severus" (or from source 1 to be broader) needs to be removed if u_name field is not null. Commented Mar 13, 2019 at 6:35

3 Answers 3

1

You should try this aggregate query, this will solve your problem.

db.database.aggregate([
    {
        $project:{
            'name': {
                '$ifNull': ['$u_name', '$name']
            },
            'info': '$info'
        }
    },
    {
        $project: {
            'name': '$name',
            'info': {
                '$filter': {
                    'input': '$info',
                    'as': 'info',
                    'cond': {
                        '$eq':['$$info.value', '$name']
                    }
                }
            }
        }
    }
])

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

Comments

0

You can try something like below:

db.database.aggregate([
    {
        $project:{
            "name":{ $cond: { if: { $eq:["$u_name",null] }, then: "$name", else: "$u_name" } },
        }
    },
])

1 Comment

This is equivalent to the query I've provided in my question if I'm not wrong.
0

Is this helpful ?

if any condition need. u can match it.

db.getCollection('TestQueries').aggregate([
{$unwind:{
 path:"$info",
 preserveNullAndEmptyArrays:true
}},
{$project:{
  name:"$info.value",
  info:1
}}
])

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.