Mongodb get error message "MongoError: Path collision at activity"

Viewed 19589

I am using mongoose library for the mongodb on my node.js project. On of my logs file getting the mongodb error message:

{
  message: 'Path collision at activity',
  stack: 'MongoError: Path collision at activity\n' +
    '    at Connection.<anonymous> (/project/node_modules/mongoose/node_modules/mongodb-core/lib/connection/pool.js:443:61)\n' +
    '    at Connection.emit (events.js:315:20)\n' +
    '    at Connection.EventEmitter.emit (domain.js:483:12)\n' +
    '    at processMessage (/project/node_modules/mongoose/node_modules/mongodb-core/lib/connection/connection.js:364:10)\n' +
    '    at Socket.<anonymous> (/project/node_modules/mongoose/node_modules/mongodb-core/lib/connection/connection.js:533:15)\n' +
    '    at Socket.emit (events.js:315:20)\n' +
    '    at Socket.EventEmitter.emit (domain.js:483:12)\n' +
    '    at addChunk (_stream_readable.js:295:12)\n' +
    '    at readableAddChunk (_stream_readable.js:271:9)\n' +
    '    at Socket.Readable.push (_stream_readable.js:212:10)\n' +
    '    at TCP.onStreamRead (internal/stream_base_commons.js:186:23)',
  operationTime: Timestamp { _bsontype: 'Timestamp', low_: 2, high_: 1600849377 },
  ok: 0,
  errmsg: 'Path collision at activity',
  code: 31250,
  codeName: 'Location31250',
  '$clusterTime': {
    clusterTime: Timestamp { _bsontype: 'Timestamp', low_: 2, high_: 1600849377 },
    signature: {
      hash: Binary {
        _bsontype: 'Binary',
        sub_type: 0,
        position: 20,
        buffer: <Buffer d2 34 b7 ac bc a7 3f ea 38 d1 5c e3 26 58 39 43 d8 11 6c 83>
      },
      keyId: Long { _bsontype: 'Long', low_: 4, high_: 1596659428 }
    }
  },
  name: 'MongoError',
  level: 'info',
  timestamp: '2020-09-23 08:22:57',
  [Symbol(mongoErrorContextSymbol)]: {}
}

This error did not point the location of error that on which function return this error. If anyone have anyclue then kindly let me know. Thanks in advance.

3 Answers

The problem should rely in the projection. This error is introduced as part of breaking change since v4.4.

From MongoDB 4.4 release notes here:

Path Collision: Embedded Documents and Its Fields

Starting in MongoDB 4.4, it is illegal to project an embedded document with any of the embedded document’s fields.

For example, consider a collection inventory with documents that contain a size field:

{ ..., size: { h: 10, w: 15.25, uom: "cm" }, ... }

Starting in MongoDB 4.4, the following operation fails with a Path collision error because it attempts to project both size document and the size.uom field:

db.inventory.find( {}, { size: 1, "size.uom": 1 } )  // Invalid starting in 4.4

In previous versions, lattermost projection between the embedded documents and its fields determines the projection:

  • If the projection of the embedded document comes after any and all projections of its fields, MongoDB projects the embedded document. For example, the projection document { "size.uom": 1, size: 1 } produces the same result as the projection document { size: 1 }.
  • If the projection of the embedded document comes before the projection any of its fields, MongoDB projects the specified field or fields. For example, the projection document { "size.uom": 1, size: 1, "size.h": 1 } produces the same result as the projection document { "size.uom": 1, "size.h": 1 }

For the record, I got this error when I wanted to select a set of fields of a populated collection, also paginating them. With this as an author-book example:

author: {
  _id: ObjectId
  name: String,
  birthday: String,
  ...,
  books: [
    _id: ObjectId,
    _id: ObjectId,
  ]
}

book: {
  _id: ObjectId,
  title: String,
  publisher: String,
  year: string,
  ...
}

I was trying to paginate sets of 5 books of the author and select the title and year fields using:

Author.findById(author_id)
  .populate('books')
  .select('books': { $slice: { [offset, limit + offset] } })
  .select('books books.title books.year');

Which was throwing the error. Instead, solved it by using select property on populate function:

Author.findById(author_id)
  .populate(
    path: 'books',
    select: 'title year'
  )
  .select('books': { $slice: { [offset, limit + offset] } });
Related