Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save length of array in extra MongoDB field [duplicate]

According to this answer, I am trying to find out the size of an array and save it in the extra field.

I have a collection user_details and the document structure is something like :

{
    user_id : 1,
    likes : [1,2,3,4],
    likes_count : 0
}

The query I'm using is as follows :

db.user_details.update({user_id : 1},{$set:{ likes_count : this.likes.length }})

BUT, it throws error that

"message" : "Cannot read property 'length' of undefined"

How do I save the length of an array in extra field?

PS: I'm using MongoDB 3.4

like image 647
Anand Undavia Avatar asked Mar 10 '23 19:03

Anand Undavia


2 Answers

With MongoDB 3.4 and newer, you can use the $addFields pipeline to add the desired field ($addFields stage is equivalent to a $project stage that explicitly specifies all existing fields in the input documents and adds the new fields) and then write the result of the aggregate operation to the same collection using $out operator, thereby effectively updating the underlying collection.

If the collection specified by the $out operation already exists, then upon completion of the aggregation, the $out stage atomically replaces the existing collection with the new results collection.

To get the count, use the $size operator which returns the length of an array field. Bear in mind that all documents must have the likes field.

Overall, you need to run the following pipeline to achieve the desired update operation:

db.user_details.aggregate([
    { "$addFields": { "likes_count": { "$size": "$likes" } } },
    { "$out": "user_details" }
])
like image 159
chridam Avatar answered Mar 12 '23 09:03

chridam


https://docs.mongodb.com/manual/reference/operator/aggregation/size/#exp._S_size

db.users.aggregate(
   [
      {
         $project: {
            likes_count: { $size: "$test" }
         }
      }
   ]
)

store the returned likes_count in an variable and perform update by providing the likes_count variable

something like this

Model.aggregate(
    [
        {
            $project: {
                likes_count: { $size: "$test" }
            }
        }
    ], (err, re) => {
        console.log(err, re);
        var likes_count = re[0].likes_count;
        Model.update({email: 1}, {$set: {likes_count: likes_count}}, (err, d) => {
            console.log(err, d);
        })
    }
)
like image 33
Parwat Kunwar Avatar answered Mar 12 '23 09:03

Parwat Kunwar