5

I am new to MongoDB and I would like to ask how to make a new field for the element, which represents for the size of another field in that element. For example: - I have the element such like:

{ 
  "_id" : ObjectId("57e1ffcb94d9ae534869c6cd"), 
  "url" : "http://www.nytimes.com", 
  "verticals" : [ 1, 2, 3, 4, 5, 12 ] 
}

I want to add new field say "numadx" which is the size of "verticals" array, in this case, it's 6. And the result can be:

{ 
  "_id" : ObjectId("57e1ffcb94d9ae534869c6cd"), 
  "url" : "http://www.nytimes.com", 
  "verticals" : [ 1, 2, 3, 4, 5, 12 ] 
  "numadx" : 6
}

I use the command in the terminal:

db.test.update({},{$set:{numadx:{$size: "$verticals"}}},{multi:true})

but it return the error:

"errmsg" : "The dollar ($) prefixed field '$size' in 'numadx.$size' is not valid for storage."

Can someone help me :D ? I do this for sorting the elements in this collection based on numadx field, which helps me know the least to the most number of verticals values of these elements in collection.

Thank you very much.

styvane
  • 59,869
  • 19
  • 150
  • 156
Blurie
  • 148
  • 1
  • 2
  • 13

3 Answers3

1

$addFields is a new feature in Mongo 3.4 that adresses the question: it lets you update the record of the collection by storing the product of the aggregation inside the record

db.collection.aggregate(   
     [ {          
          "$addFields": {  "numadx": { $size: "$verticals" } }       
        },
        { "$out":"collection"}
     ]    
)
c24b
  • 5,278
  • 6
  • 27
  • 35
  • As at MongoDB 3.4, the `$out` stage can only [create a new collection or replace an existing one](https://docs.mongodb.com/manual/reference/operator/aggregation/out/#behaviors) so this isn't a viable solution for updating an existing document. – Stennie Jul 21 '17 at 04:41
-1

I don't think $size is an update operator in MongoDB. The update operators are https://docs.mongodb.com/manual/reference/operator/update-field/. I've never seen $size used anywhere other than in a find like

db.test.find( { verticals: { $size: 6 } } );

I think its impossible to use that in an update. You are going to need to explicitly read the record and jack in your new array.

Bob Kuhar
  • 10,838
  • 11
  • 62
  • 115
  • Oh I see, but I still can not get the size of that array and update it into a new field for that element xD – Blurie Sep 21 '16 at 04:45
-1

Currently in MongoDB you cannot update a document using some calculated value in that document. Also, Bob is correct that $size is not an operator recognized by the update() command.

Having said that, there is a way to achieve what you want using mongo shell scripting:

db.test.find().forEach(function(doc){
    db.test.update({_id:doc._id}, {$set:{numadx:doc.verticals.length}})
})

This script will go into each document in your collection, and set the numadx field using the values of the current document that is accessible in the doc variable.

You can modify the find() query there to process only a subset of your data, otherwise it will run for every document in your collection.

For more information, please see:

kevinadi
  • 13,365
  • 3
  • 33
  • 49