javaamtho
javaamtho

Reputation: 382

Remove element from array in mongodb

I am new in mongodb and i want to remove the some element in array.

my document as below

{
  "_id" : ObjectId("4d525ab2924f0000000022ad"), 
  "name" : "hello", 
  "time" : [
      {
              "stamp" : "2010-07-01T12:01:03.75+02:00",
              "reason" : "new"
      },
      {
              "stamp" : "2010-07-02T16:03:48.187+03:00",
              "reason" : "update"
      },
      {
              "stamp" : "2010-07-02T16:03:48.187+04:00",
              "reason" : "update"
      },
      {
              "stamp" : "2010-07-02T16:03:48.187+05:00",
              "reason" : "update"
      },
      {
              "stamp" : "2010-07-02T16:03:48.187+06:00",
              "reason" : "update"
      }
  ]
}

in document, i want to remove first element(reason:new) and last element(06:00) .

and i want to do it using mongoquery, i am not using any java/php driver.

Upvotes: 5

Views: 14973

Answers (5)

asleepysamurai
asleepysamurai

Reputation: 1372

If I'm understanding you correctly, you want to remove the first and last elements of the array if the size of the array is greater than 3. You can do this by using the findAndModify query. In mongo shell you would be using this command:

db.collection.findAndModify({
    query: { $where: "this.time.length > 3" },
    update: { $pop: {time: 1}, $pop: {time: -1} },
    new: true
});

This would find the document in your collection which matches the $where clause. The $where field allows you to specify any valid javascript method. Please note that it applies the update only to the first matched document.

You might want to look at the following docs also:

  1. http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-JavascriptExpressionsand%7B%7B%24where%7D%7D for more on the $where clause.
  2. http://www.mongodb.org/display/DOCS/Updating#Updating-%24pop for more on $pop.
  3. http://www.mongodb.org/display/DOCS/findAndModify+Command for more on findAndModify.

Upvotes: 6

user2859713
user2859713

Reputation: 1

db.collection.findAndModify({ query: {$where: "this.time.length > 3"}, update: {$pop: {time: 1}, $pop{time: -1}}, new: true });

convert to PHP

Upvotes: 0

42n4
42n4

Reputation: 1329

If you would like to leave these time elements, you can use aggregate command from mongo 2.2+ to retrieve min and max time elements, unset all time elements, and push min and max versions (with some modifications it could do your job):

smax=db.collection.aggregate([{$unwind: "$time"},
{$project: {tstamp:"$time.stamp",treason:"$time.reason"}},
{$group: {_id:"$_id",max:{$max: "$tstamp"}}},
{$sort: {max:1}}])

smin=db.collection.aggregate([{$unwind: "$time"},
{$project: {tstamp:"$time.stamp",treason:"$time.reason"}},
{$group: {_id:"$_id",min:{$min: "$tstamp"}}},
{$sort: {min:1}}])

db.students.update({},{$unset: {"scores": 1}},false,true)

smax.result.forEach(function(o)  
{db.collection.update({_id:o._id},{$push:
{"time": {stamp: o.max ,reason: "new"}}},false,true)})

smin.result.forEach(function(o)
{db.collection.update({_id:o._id},{$push:
{"time": {stamp: o.min ,reason: "update"}}},false,true)})

Upvotes: 0

Bob
Bob

Reputation: 671

@javaamtho you cannot test for a size greater than 3 but only if it is exactly 3, for size greater than x number you should use the $inc operator and have a field you either 1 or -1 to in order to keep track when you remove or add items (use a separate field outside the array as below, time_count)

{
  "_id" : ObjectId("4d525ab2924f0000000022ad"), 
  "name" : "hello",
  "time_count" : 5,
  "time" : [
      {
              "stamp" : "2010-07-01T12:01:03.75+02:00",
              "reason" : "new"
      },
      {
              "stamp" : "2010-07-02T16:03:48.187+03:00",
              "reason" : "update"
      },
      {
              "stamp" : "2010-07-02T16:03:48.187+04:00",
              "reason" : "update"
      },
      {
              "stamp" : "2010-07-02T16:03:48.187+05:00",
              "reason" : "update"
      },
      {
              "stamp" : "2010-07-02T16:03:48.187+06:00",
              "reason" : "update"
      }
  ]
}

Upvotes: 0

gnarf
gnarf

Reputation: 106322

You could update it with { $pop: { time: 1 } } to remove the last one, and { $pop: { time : -1 } } to remove the first one. There is probably a better way to handle it though.

Upvotes: 4

Related Questions