0

I'm trying to update a hash in a MongoDB doc with a simple value but it store the value in an array. I use the ruby driver for mongo

Code will explain better because my english is bad.

What I have :

{
    'id' : ...
    'stream' : {
            "1406481985(a timestamp)" : 35603
     }
}

What I want :

{
    'id' : ...
    'stream' : {
            "1406481985" : 35603,
            "1406481990" : 15000
     }
}

What I get :

{
    'id' : ...
    'stream' : {
            "1406481985" : 35603,
            "1406481990" : [
                                   15000
            ]
     }
}

How did I get there :

views = 15000
time = Time.now
coll.find_and_modify({
    query: {:id => id},                                      
    update: {'$push' => {"stream.#{time}" => views}},                           
})

I've already tried with Updating nested document in MongoDB and I can't see what I do wrong

Community
  • 1
  • 1
chambo_e
  • 74
  • 2
  • 8
  • 2
    You use [push](http://docs.mongodb.org/manual/reference/operator/update/push/) which appends elements to an Array. I suppose it creates the Array for a first element, so you end up with `[ value ]`. However, you can probably use [set](http://docs.mongodb.org/manual/reference/operator/update/set/) to insert a single value. So something like `'$set' => { "stream.#{time}" => views }`. I don't have MongoDB myself, so you should first try it out :) – Daniël Knippers Jul 27 '14 at 19:49

1 Answers1

0

Daniël Knippers is correct — using $set should work. I also notice you are using id instead of '_id`. Perhaps a typo?


edit: note that it's usually not recommended to have dynamic key values as they are difficult to index and query. Consider a stream structure of hashes inside an array:

{
    '_id' : ...
    'stream' : [
            {'time' : 1406481985, 'views': 35603},
            {'time' : 1406481990, 'views': 15000}
    ]
}

Now you can easily query the time and views fields.

Justin Case
  • 1,503
  • 11
  • 20