Ilijanovic
Ilijanovic

Reputation: 14904

increase counter depending on array length

I have this following problem:

I want to track visits of my blog posts so i had the idea to create an array called visitorsIp and push the ip adress from the visitor into the array with $addToSet.

Now i have an cronjob that should increase the viewed counter depending on the length of the array. and the array should be cleared at the end.

My document simplified:

{
   _ip: 5aösldkf3sdlfk2,
   viewed: 0,
   visitorsIp: ["192.168.200.20", "192.168.200.21", "192.168.200.22"]
}

I tried something like this here:

await Blog.aggregate([
    {
      $addFields: {
        counter: {
          $size: "$this.visitorsIp"
        }
      }
    },
    {
      viewed: {
        $add: ["$this.counter"]
      }
    }, 
    {
       visitorsIp: {
          $set: []
       }
    }
  ]);
})

Doesnt seems to work how i expected

My expected result is this here:

{
   _ip: 5aösldkf3sdlfk2,
   viewed: 3,
   visitorsIp: []
}

The viewed gets increased by 3 because the array size was 3. And the array is cleared after.

Upvotes: 1

Views: 96

Answers (2)

Gibbs
Gibbs

Reputation: 22974

To update

db.getCollection('test').update(
  {},
  [{
    $set: {
      "viewed": {$add: [ {$size:"$visitorsIp"}, '$viewed' ]},
      "visitorsIp": []
      }
  }],
  {
    multi: true
  }
);

viewed is not a valid pipeline.

To unset visitorsIp, You need to have another query to set empty or unset visitorsIp. In single query, both cannot be referenced on the same field.

Upvotes: 2

turivishal
turivishal

Reputation: 36134

You can use updateMany() with pipeline,

updateMany()

  • $add to sum the existing count + $size of total visitorsIp
  • visitorsIp set empty []
await Blog.updateMany({},
  [{
      $set: {
        "viewed": {
          $add:[{ $size:"$visitorsIp" }, "$viewed"]
        },
        "visitorsIp": []
      }
  }]
)

update()

  • need to set option multi: true for multiple documents update
await Blog.update({},
  [{
      $set: {
        "viewed": {
          $add:[{ $size:"$visitorsIp" }, "$viewed"]
        },
        "visitorsIp": []
      }
  }],
  { multi: true }
)

Note: use updateMany() instead of update() because update() method is deprecated in mongoose.

Upvotes: 1

Related Questions