Black Mamba
Black Mamba

Reputation: 15545

How to escape $ while inserting inside mongoDB

I have a large object which I have no control over, fields might vary a lot:

Error ==>> { MongoError: The dollar ($) prefixed field '$' in 'value.external.originalRequest.rawRequest.ns2:LoadData.Orders.0.Order.0.TotalThirdPartyCharge.0.CurrencyValue.0.$' is not valid for storage. 0|lt-check | at Function.MongoError.create (/home/ops/lt-checkin-api/node_modules/mongodb-core/lib/error.js:31:11) 0|lt-check | at /home/ops/lt-checkin-api/node_modules/mongodb-core/lib/connection/pool.js:497:72 0|lt-check | at authenticateStragglers (/home/ops/lt-checkin-api/node_modules/mongodb-core/lib/connection/pool.js:443:16) 0|lt-check | at Connection.messageHandler (/home/ops/lt-checkin-api/node_modules/mongodb-core/lib/connection/pool.js:477:5) 0|lt-check | at Socket. (/home/ops/lt-checkin-api/node_modules/mongodb-core/lib/connection/connection.js:333:22) 0|lt-check | at Socket.emit (events.js:159:13) 0|lt-check | at addChunk (_stream_readable.js:265:12) 0|lt-check | at readableAddChunk (_stream_readable.js:252:11) 0|lt-check | at Socket.Readable.push (_stream_readable.js:209:10) 0|lt-check | at TCP.onread (net.js:608:20) 0|lt-check | name: 'MongoError', 0|lt-check | message: 'The dollar ($) prefixed field \'$\' in \'value.external.originalRequest.rawRequest.ns2:LoadData.Orders.0.Order.0.TotalThirdPartyCharge.0.CurrencyValue.0.$\' is not valid for storage.', 0|lt-check | ok: 0, 0|lt-check |
errmsg: 'The dollar ($) prefixed field \'$\' in \'value.external.originalRequest.rawRequest.ns2:LoadData.Orders.0.Order.0.TotalThirdPartyCharge.0.CurrencyValue.0.$\' is not valid for storage.', 0|lt-check | code: 52, 0|lt-check |
codeName: 'DollarPrefixedFieldName' }

Here the key causing the error:

"rawRequest": {
                        "ns2:LoadData": {
                            "$": {
                                "xmlns:ns2": "http://schemas.3gtms.com/tms/v1/tns"
                            },
                            "BatchInfo": [
                                {
                                    "$": {
                                        "xmlns": ""
                                    },

As there are multiple keys starting with $.

Is there a setting in mongoose or mongoDB itself to insert anything without validating the request coming in.

Upvotes: 1

Views: 1053

Answers (2)

Bharat D Bhadresha
Bharat D Bhadresha

Reputation: 779

function escapeMongo(obj) {
    return JSON.parse(
        JSON.stringify(obj),
        function(p, v) {
            if ((p[0] === '$') || (p.includes('.'))) {
                this[p.replace(/\$/g, '\uFF04').replace(/\./g, '\uFF0E')] = v;
                return;
            }
            return v;
        }
    )
}

userInput = {
    'foo': 'bar',
    'ba.z': {
        '$in': 'quz'
    }
}
console.log(userInput)
console.log(escapeMongo(userInput))

You can use JSON.parse to process a JSON string before creating object.

Upvotes: 0

Black Mamba
Black Mamba

Reputation: 15545

Was going to create a new plugin but @Anirudh helped me find this package in the comment

https://www.npmjs.com/package/mongo-escape

To use it, just before your insert query escape you object using the above package.

var escapeForMongo = require('mongo-escape').escape;
userInput = escapeForMongo({
  'foo': 'bar',
  'ba.z': {
    '$in': 'quz'
  }
})

Upvotes: 0

Related Questions