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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.