MongoDB: set value in collection depending on another object

Problem

The document is as follows:

{
  data: [
    { identifier: 'a', value: 10 },
    { identifier: 'b', value: 53 },
    { identifier: 'c', value: 16 }
  ]
}

I would like to set all values ​​to nullif another object inside the same array with identifier xsatisfies the condition. Real life example:

If the property of the valueobject with the identifier is agreater than 9, set the property of the valueobjects with the identifier bor cin null.

An approach

I am trying to use a pipeline $project, but do not know how to find other objects.

// ... Rest
{
$unwind: '$data'
}, {
$project: {
  data: {
    identifier: 1,
    value: {
      $cond: {
        if: {}, // Implement
        then: null, // Only valid for current value
        else: '$row.value'
      }
    }
  }
}
// ... Rest

Output required

The result of aggregation should be an array.

If the value amatches the condition:

[
  { data: { identifier: 'a', value: null } },
  { data: { identifier: 'b', value: null } },
  { data: { identifier: 'c', value: null } },
  // ... more documents
]

If the value adoes not comply with the condition:

[
  { data: { identifier: 'a', value: 10 } },
  { data: { identifier: 'b', value: 53 } },
  { data: { identifier: 'c', value: 16 } },
  // ... more documents
]
+4
2

.

$cond $filter , $size, $gt, 0; , $map, null; .

 db.colname.aggregate({"$addFields":{
  "data":{
    "$cond":[
      {"$gt":[
        {"$size":{
          "$filter":{
            "input":"$data",
            "as":"d",
            "cond":{
              "$and":[
                {"$eq":["a","$$d.identifier"]}, 
                {"$gt":["$$d.value", 9]}
              ]
            }
          }
        }}, 
        0
      ]}, 
      {"$map":{
        "input":"$data",
        "as":"d",
        "in":{ "identifier": "$$d.identifier", "value": null }
      }}, 
      "$data"
    ]
  }
}})
+2

, $unwind

db.col.aggregate([
    {$addFields : {
        index : {$indexOfArray : ["$data.identifier", "a"]},
        isTrue : {$gte : [{$arrayElemAt : ["$data.value", {$indexOfArray : ["$data.identifier", "a"]}]}, 10]}
        }},
    {$addFields : {
        row : {
            identifier : {$arrayElemAt : ["$data.identifier", "$index"]},
            value : {$cond : ["$isTrue", {$arrayElemAt : ["$data.value", "$index"]}, null]}
        }
    }},
    {$project : {index :0, isTrue : 0, data : 0}}
]).pretty()

> db.col.aggregate([ {$addFields : { index : {$indexOfArray : ["$data.identifier", "a"]}, isTrue : {$gte : [{$arrayElemAt : ["$data.value", {$indexOfArray : ["$data.identifier", "a"]}]}, 10]} }}, {$addFields : { row : { identifier : {$arrayElemAt : ["$data.identifier", "$index"]}, value : {$cond : ["$isTrue", {$arrayElemAt : ["$data.value", "$index"]}, null]} } }}, {$project : {index :0, isTrue : 0, data : 0}} ]).pretty()

{ "_id" : 1, "row" : { "identifier" : "a", "value" : 10 } }
> 

$map

db.col.aggregate([
    {$addFields : { 
        isTrue : {$gte : [{$arrayElemAt : ["$data.value", {$indexOfArray : ["$data.identifier", "a"]}]}, 10]}
    }},
    {$addFields : {
        data : 
            {$map : {
                input : "$data",
                as : "d",
                in : {
                    identifier : "$$d.identifier",
                    value : {$cond : ["$isTrue", "$$d.value", null]}
                }
            }}
    }},
    {$project : {_id :0, isTrue : 0}}
]).pretty()

{
    "data" : [
        {
            "identifier" : "a",
            "value" : 10
        },
        {
            "identifier" : "b",
            "value" : 53
        },
        {
            "identifier" : "c",
            "value" : 16
        }
    ]
}
+1

Source: https://habr.com/ru/post/1694390/


All Articles