Question

I am using the c# driver, but I would be happy about pointers in any language.

My documents have the following structure:

 class Document
 {
      List<Comment> comments;
 }

Or in Json:

 [{
     "comments" : [{"comment" : "text1"}, {"comment" : "text2"}, ...]
  },
  {
     "comments" : [{"comment" : "text1"}, {"comment" : "text2"}, ...]
  }, ...]

As you can see, each document contains a list of comments.

My goal is to run a periodic task, that truncates the list of comments of each document to a specific number of elements (eg. 10).

The obvious way that comes to my mind is to:

  • Fetch each document
  • Get the comments that should be removed
  • Update the document by it's id by pulling the ids of the comments that should be removed

Is there a possibility to do this with a bulk Update?

I couldn't think of a condition for the update that would me allow to truncate the number of comments without fetching them first.

Was it helpful?

Solution

You can slice the elements of the comments array to the last n elements (-10 in the example below). Try this in the shell:

db.coll.update(
  { },
  { $push: { comments: { $each: [ ], $slice: -10 } } },
  { multi: true }
)

Since MongoDB 2.6 you can also use a positive n to update the array to contain only the first n elements.

In case you have a field you want to sort on before applying the slice operation:

db.coll.update(
  { }, { 
    $push: { 
      comments: { 
        $each: [ ], 
        $sort: { <field_to_sort_on>: 1 },
        $slice: -10 
      } 
    } 
  },
  { multi: true }
)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top