Christian Fazzini
Christian Fazzini

Reputation: 19723

How do I update an item in an array in this document structure?

I have the following document structure:

{
  "_id" : "20120725/foobar/song/test-pg3-long-title-here-test-lorem-ipsum-dolor-lo",
  "live_daily_count" : 4,
  "metacontent" : { "date" : "20120725",
    "live_daily_statable_slug" : "test-pg3-long-title-here-test-lorem-ipsum-dolor-lo",
    "live_daily_statable_title" : "test pg3 long title here test lorem ipsum dolor lorem ipsume dolor long description here msam dfam sdfm asfa sfasfas df as f as fas f sa f",
    "live_daily_statable_type" : "Song",
    "url" : "foobar/songs/test-pg3-long-title-here-test-lorem-ipsum-dolor-lo",
    "user_slug" : "foobar" },
  "visits" : [
    { "country_name" : "UK",
      "iso_two_letter_country_code" : "UK",
      "referer" : "http://localhost:3000/",
      "minute" : 1121,
      "token_id" : "13432416893tlfsmmgh" },
    { "country_name" : "UK",
      "iso_two_letter_country_code" : "UK",
      "referer" : "http://localhost:3000/",
      "minute" : 1281,
      "token_id" : "13432512733xcqhhrqs" },
    { "country_name" : "UK",
      "iso_two_letter_country_code" : "UK",
      "referer" : "http://localhost:3000/",
      "minute" : 1285,
      "token_id" : "13432515303rwiaczcx" },
    { "country_name" : "UK",
      "iso_two_letter_country_code" : "UK",
      "referer" : "http://localhost:3000/",
      "minute" : 1288,
      "token_id" : "13432517303eusgjcgz" }
  ]
}

How do I find the visit with token_id 13432515303rwiaczcx and update its minute to 1234?

I am able to find the item in the array using the Aggregation Framework (code below), but how do I update it?

  connection = Mongo::Connection.new
  database   = conn['foobar_development']

  query = {
    aggregate: 'live_daily_stats',
    pipeline: [
      { '$project' => {
        :visits => 1,
      } },
      { '$unwind' => '$visits' },
      { '$match' => { 'visits.token_id' => '13432515303rwiaczcx' } },
    ]
  }

  visit = database.command(query)['result'][0]

Which returns:

{
       "_id" => "20120725/foobar/song/test-pg3-long-title-here-test-lorem-ipsum-dolor-lo",
    "visits" => {
                                      "country_name" => "UK",
                       "iso_two_letter_country_code" => "UK",
                                           "referer" => "http://localhost:3000/",
                                            "minute" => 1285,
                                          "token_id" => "13432515303rwiaczcx"
    }
}

Upvotes: 0

Views: 73

Answers (1)

Jenna
Jenna

Reputation: 2396

The aggregation framework is not designed to update existing documents in your collection. As idefine points out, you can use the positional operator:

input:

{
  "_id" : xyz
  "visits" : [
    {"minute" : 1281,
      "token_id" : 1 },
    { "minute" : 1285,
      "token_id" : 2 },
    { "minute" : 1288,
      "token_id" : 3 }
  ]
}

update:

db.collection.update({"visits.token_id":2}, {$inc:{"visits.$.minute":1}})

result:

{
  "_id" : xyz
  "visits" : [
    {"minute" : 1281,
      "token_id" : 1 },
    { "minute" : 1286,
      "token_id" : 2 },
    { "minute" : 1288,
      "token_id" : 3 }
  ]
}

Upvotes: 1

Related Questions