Insert if there no more than N documents

Assuming we have a collection with the following document schema:

_id: ObjectId
parent: string

Now, I have to insert the following document:

_id: ... //Whatever, it doesn't matter
parent: "myparent"

The specification is: "Insert the document only if there are not already at most N documents with the same parent"

Is it possible to perform it with a single query (or at least single round-trip) operation?

Hi @Matteo_Tarantino ,

I believe you can achieve that with games on $count and $redact for specific parents, using a $merge eventually.

For example the following aggregation:

[{$match: {
 parent: 'myparent'
}}, {$group: {
 _id: '$parent',
 count: {
  $count: {}
}}, {$redact: {
 $cond: {
  'if': {
   $gte: [
  then: '$$PRUNE',
  'else': '$$KEEP'
}}, {$addFields: {
 createDocument: {
  _id: ObjectId('6208e7c09c02b5bbe1391e8e'),
  parent: 'myparent',
  value: 5
}}, {$replaceRoot: {
 newRoot: '$createDocument'
}}, {$merge: {
 into: 'myparents',
 on: '_id',
 whenMatched: 'fail',
 whenNotMatched: 'insert'

If the grouping and counting for a specific parent yeild a result of less or equal than 3 the document will be kept and we can use “$addFields” to add the new document we wish to insert under “createDocument” field.

Now this is a pretty complex agg for something stratigicaly small. Have you considered changing the document model to have children of a parent under the same parent?


Which document model you suggest?


_id : ... ,
type : "parent",
childs : [
      { _id : ...,
       type : "child", 
       value : "..."

Now you can limit the amount of childs by pushing only if the $size of this array is not above N …

How much N’s do you expect?


N will be bounded, so the size limit of 16MB will not be a problem. However, I think that my document model suits well for other queries, so I wonder: which will be the difference in performance between the aggregation you write before and the query you are suggesting now?

Moreover is it possible to know if the document has been inserted or not after the $merge stage?